diff --git a/PWGCF/Femto/Core/collisionHistManager.h b/PWGCF/Femto/Core/collisionHistManager.h index f683da3cd78..39d78a0e6ad 100644 --- a/PWGCF/Femto/Core/collisionHistManager.h +++ b/PWGCF/Femto/Core/collisionHistManager.h @@ -24,8 +24,6 @@ #include #include -#include -#include #include #include #include diff --git a/PWGCF/Femto/Core/pairHistManager.h b/PWGCF/Femto/Core/pairHistManager.h index 0d0d8ba37a4..a2519f2e5bd 100644 --- a/PWGCF/Femto/Core/pairHistManager.h +++ b/PWGCF/Femto/Core/pairHistManager.h @@ -31,6 +31,7 @@ #include #include +#include #include #include #include diff --git a/PWGCF/Femto/Core/partitions.h b/PWGCF/Femto/Core/partitions.h index 136cf6615ee..aac05f3ea91 100644 --- a/PWGCF/Femto/Core/partitions.h +++ b/PWGCF/Femto/Core/partitions.h @@ -51,21 +51,21 @@ (o2::aod::femtobase::stored::mass < selection.massMax) // partition for phis and rhos, i.e. resonance that are their own antiparticle -#define MAKE_RESONANCE_0_PARTITON(selection) \ - (o2::aod::femtobase::stored::pt > selection.ptMin) && \ - (o2::aod::femtobase::stored::pt < selection.ptMax) && \ - (o2::aod::femtobase::stored::eta > selection.etaMin) && \ - (o2::aod::femtobase::stored::eta < selection.etaMax) && \ - (o2::aod::femtobase::stored::phi > selection.phiMin) && \ - (o2::aod::femtobase::stored::phi < selection.phiMax) && \ - (o2::aod::femtobase::stored::mass > selection.massMin) && \ - (o2::aod::femtobase::stored::mass < selection.massMax) && \ - ifnode(ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.posDauBitForThres), \ - ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.posDauMaskAboveThres), \ - ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.posDauMaskBelowThres)) && \ - ifnode(ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.negDauBitForThres), \ - ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.negDauMaskAboveThres), \ - ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.negDauMaskBelowThres)) +#define MAKE_RESONANCE_0_PARTITON(selection) \ + (o2::aod::femtobase::stored::pt > selection.ptMin) && \ + (o2::aod::femtobase::stored::pt < selection.ptMax) && \ + (o2::aod::femtobase::stored::eta > selection.etaMin) && \ + (o2::aod::femtobase::stored::eta < selection.etaMax) && \ + (o2::aod::femtobase::stored::phi > selection.phiMin) && \ + (o2::aod::femtobase::stored::phi < selection.phiMax) && \ + (o2::aod::femtobase::stored::mass > selection.massMin) && \ + (o2::aod::femtobase::stored::mass < selection.massMax) && \ + ifnode(o2::aod::femtotwotrackresonances::posDauHasHighMomentum, \ + ncheckbit(o2::aod::femtotwotrackresonances::maskPosDau, selection.posDauMaskAboveThres), \ + ncheckbit(o2::aod::femtotwotrackresonances::maskPosDau, selection.posDauMaskBelowThres)) && \ + ifnode(o2::aod::femtotwotrackresonances::negDauHasHighMomentum, \ + ncheckbit(o2::aod::femtotwotrackresonances::maskNegDau, selection.negDauMaskAboveThres), \ + ncheckbit(o2::aod::femtotwotrackresonances::maskNegDau, selection.negDauMaskBelowThres)) // partition for kstars, they have distinct antiparticle #define MAKE_RESONANCE_1_PARTITON(selection) \ @@ -79,12 +79,12 @@ (o2::aod::femtobase::stored::phi < selection.phiMax) && \ (o2::aod::femtobase::stored::mass > selection.massMin) && \ (o2::aod::femtobase::stored::mass < selection.massMax) && \ - ifnode(ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.posDauBitForThres), \ - ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.posDauMaskAboveThres), \ - ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.posDauMaskBelowThres)) && \ - ifnode(ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.negDauBitForThres), \ - ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.negDauMaskAboveThres), \ - ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.negDauMaskBelowThres)) + ifnode(o2::aod::femtotwotrackresonances::posDauHasHighMomentum, \ + ncheckbit(o2::aod::femtotwotrackresonances::maskPosDau, selection.posDauMaskAboveThres), \ + ncheckbit(o2::aod::femtotwotrackresonances::maskPosDau, selection.posDauMaskBelowThres)) && \ + ifnode(o2::aod::femtotwotrackresonances::negDauHasHighMomentum, \ + ncheckbit(o2::aod::femtotwotrackresonances::maskNegDau, selection.negDauMaskAboveThres), \ + ncheckbit(o2::aod::femtotwotrackresonances::maskNegDau, selection.negDauMaskBelowThres)) // partition for lambdas #define MAKE_LAMBDA_PARTITION(selection) \ diff --git a/PWGCF/Femto/Core/trackBuilder.h b/PWGCF/Femto/Core/trackBuilder.h index 7971c7fe34e..62ad742de25 100644 --- a/PWGCF/Femto/Core/trackBuilder.h +++ b/PWGCF/Femto/Core/trackBuilder.h @@ -160,11 +160,22 @@ constexpr const char PrefixTrackSelection1[] = "TrackSelection1"; constexpr const char PrefixTrackSelection2[] = "TrackSelection2"; constexpr const char PrefixTrackSelection3[] = "TrackSelection3"; +// for resonances builder +constexpr const char PrefixPionPlus[] = "PionPlusSelection"; +constexpr const char PrefixPionMinus[] = "PionMinusSelection"; +constexpr const char PrefixKaonPlus[] = "KaonPlusSelection"; +constexpr const char PrefixKaonMinus[] = "KaonMinusSelection"; + // Instantiate different instances with unique prefixes using ConfTrackSelection1 = ConfTrackSelection; using ConfTrackSelection2 = ConfTrackSelection; using ConfTrackSelection3 = ConfTrackSelection; +using ConfPionPlusSelection = ConfTrackSelection; +using ConfPionMinusSelection = ConfTrackSelection; +using ConfKaonPlusSelection = ConfTrackSelection; +using ConfKaonMinusSelection = ConfTrackSelection; + /// enum for all track selections enum TrackSels { // track quality cuts diff --git a/PWGCF/Femto/Core/trackHistManager.h b/PWGCF/Femto/Core/trackHistManager.h index 0aba818a043..9ce323841c1 100644 --- a/PWGCF/Femto/Core/trackHistManager.h +++ b/PWGCF/Femto/Core/trackHistManager.h @@ -155,26 +155,35 @@ struct ConfTrackBinning : o2::framework::ConfigurableGroup { constexpr const char PrefixTrackBinning1[] = "TrackBinning1"; constexpr const char PrefixTrackBinning2[] = "TrackBinning2"; constexpr const char PrefixTrackBinning3[] = "TrackBinning3"; -constexpr const char PrefixResonancePosDauBinning[] = "ResonancePosDauBinning"; -constexpr const char PrefixResonanceNegDauBinning[] = "ResonanceNegDauBinning"; constexpr const char PrefixV0PosDauBinning[] = "V0PosDauBinning"; constexpr const char PrefixV0NegDauBinning[] = "V0NegDauBinning"; constexpr const char PrefixCascadePosDauBinning[] = "CascadePosDauBinning"; constexpr const char PrefixCascadeNegDauBinning[] = "CascadeNegDauBinning"; constexpr const char PrefixCascadeBachelorBinning[] = "CascadeBachelorBinning"; constexpr const char PrefixKinkChaDauBinning[] = "KinkChaDauBinning"; +constexpr const char PrefixResonancePosDauBinning[] = "ResonancePosDauBinning"; +constexpr const char PrefixResonanceNegDauBinning[] = "ResonanceNegDauBinning"; +constexpr const char PrefixPionPlusBinning[] = "PionPlusBinning"; +constexpr const char PrefixPionMinusBinning[] = "PionMinusBinning"; +constexpr const char PrefixKaonPlusBinning[] = "KaonPlusBinning"; +constexpr const char PrefixKaonMinusBinning[] = "KaonMinusBinning"; using ConfTrackBinning1 = ConfTrackBinning; using ConfTrackBinning2 = ConfTrackBinning; using ConfTrackBinning3 = ConfTrackBinning; -using ConfResonancePosDauBinning = ConfTrackBinning; -using ConfResonanceNegDauBinning = ConfTrackBinning; using ConfV0PosDauBinning = ConfTrackBinning; using ConfV0NegDauBinning = ConfTrackBinning; using ConfCascadePosDauBinning = ConfTrackBinning; using ConfCascadeNegDauBinning = ConfTrackBinning; using ConfCascadeBachelorBinning = ConfTrackBinning; using ConfKinkChaDauBinning = ConfTrackBinning; +// for resonance daughters +using ConfResonancePosDauBinning = ConfTrackBinning; +using ConfResonanceNegDauBinning = ConfTrackBinning; +using ConfPionPlusBinning = ConfTrackBinning; +using ConfPionMinusBinning = ConfTrackBinning; +using ConfKaonPlusBinning = ConfTrackBinning; +using ConfKaonMinusBinning = ConfTrackBinning; template struct ConfTrackQaBinning : o2::framework::ConfigurableGroup { diff --git a/PWGCF/Femto/Core/twoTrackResonanceBuilder.h b/PWGCF/Femto/Core/twoTrackResonanceBuilder.h index f1dbb8cd5e1..21ca5ff343c 100644 --- a/PWGCF/Femto/Core/twoTrackResonanceBuilder.h +++ b/PWGCF/Femto/Core/twoTrackResonanceBuilder.h @@ -16,11 +16,9 @@ #ifndef PWGCF_FEMTO_CORE_TWOTRACKRESONANCEBUILDER_H_ #define PWGCF_FEMTO_CORE_TWOTRACKRESONANCEBUILDER_H_ -#include "PWGCF/Femto/Core/baseSelection.h" #include "PWGCF/Femto/Core/dataTypes.h" #include "PWGCF/Femto/Core/femtoUtils.h" #include "PWGCF/Femto/Core/modes.h" -#include "PWGCF/Femto/Core/selectionContainer.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" #include "Common/Core/RecoDecay.h" @@ -30,35 +28,19 @@ #include #include #include -#include #include #include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) #include -#include -#include #include -#include #include -#include -#include namespace o2::analysis::femto { namespace twotrackresonancebuilder { -struct ConfTwoTrackResonanceDaughterFilters : o2::framework::ConfigurableGroup { - std::string prefix = std::string("TwoTrackResonanceDaughterFilter"); - o2::framework::Configurable ptMin{"ptMin", 0.2f, "Minimum pT of daughters"}; - o2::framework::Configurable ptMax{"ptMax", 6.f, "Maximum pT of daughters"}; - o2::framework::Configurable etaMin{"etaMin", -0.9f, "Minimum eta of daughters"}; - o2::framework::Configurable etaMax{"etaMax", 0.9f, "Maximum eta of daughters"}; - o2::framework::Configurable phiMin{"phiMin", 0.f, "Minimum phi of daughters"}; - o2::framework::Configurable phiMax{"phiMax", 1.f * o2::constants::math::TwoPI, "Maximum phi of daughters"}; -}; - template struct ConfTwoTrackResonanceFilters : o2::framework::ConfigurableGroup { std::string prefix = Prefix; @@ -74,77 +56,25 @@ struct ConfTwoTrackResonanceFilters : o2::framework::ConfigurableGroup { constexpr const char PrefixRhoFilters[] = "Rho0Filters1"; constexpr const char PrefixPhiFilters[] = "PhiFilters1"; constexpr const char PrefixKstarFilters[] = "Kstar0Filters1"; + using ConfRhoFilters = ConfTwoTrackResonanceFilters; using ConfPhiFilters = ConfTwoTrackResonanceFilters; using ConfKstarFilters = ConfTwoTrackResonanceFilters; -#define TWOTRACKRESONANCE_DEFAULT_BITS(posThres, negThres) \ - o2::framework::Configurable> dauEtaMax{"dauEtaMax", {0.8f}, "Maximum |eta| "}; \ - o2::framework::Configurable> dauTpcClustersMin{"dauTpcClustersMin", {90.f}, "Minimum number of clusters in TPC"}; \ - o2::framework::Configurable> dauDcaxyMax{"dauDcaxyMax", {"0.004 + 0.013*pow(x, -1)"}, "Maximum |dca_xy| as a function of pT"}; \ - o2::framework::Configurable> dauDcazMax{"dauDcazMax", {"0.004 + 0.013*pow(x, -1)"}, "Maximum |dca_z| as a function of pT"}; \ - o2::framework::Configurable> posDauPtMin{"posDauPtMin", {0.2f}, "Minimum pT of positive daughter "}; \ - o2::framework::Configurable> posDauPtMax{"posDauPtMax", {6.f}, "Maximum pT of the positive daughter"}; \ - o2::framework::Configurable> negDauPtMin{"negDauPtMin", {0.2f}, "Minimum pT of negative daughter "}; \ - o2::framework::Configurable> negDauPtMax{"negDauPtMax", {6.f}, "Maximum pT of the negative daughter"}; \ - o2::framework::Configurable> posDauMinMomForTof{"posDauMinMomForTof", {posThres}, "Minimum momentum to require TOF PID (positive daughters)"}; \ - o2::framework::Configurable> negDauMinMomForTof{"negDauMinMomForTof", {negThres}, "Minimum momentum to require TOF PID (negative daughters)"}; - -#define TWOTRACKRESONANCE_PIONPID_BITS \ - o2::framework::Configurable> posDauTpcPion{"posDauTpcPion", {3.f}, "Maximum |nsimga_Pion| TPC for positive daughter tracks"}; \ - o2::framework::Configurable> posDauTofPion{"posDauTofPion", {}, "Maximum |nsimga_Pion| TOF for positive daughter tracks"}; \ - o2::framework::Configurable> posDauTpctofPion{"posDauTpctofPion", {3.f}, "Maximum |nsimga_Pion| TPCTOF for positive daughter tracks"}; \ - o2::framework::Configurable> negDauTpcPion{"negDauTpcPion", {3.f}, "Maximum |nsimga_Pion| TPC for negative daughter tracks"}; \ - o2::framework::Configurable> negDauTofPion{"negDauTofPion", {}, "Maximum |nsimga_Pion| TOF for negative daughter tracks"}; \ - o2::framework::Configurable> negDauTpctofPion{"negDauTpctofPion", {3.f}, "Maximum |nsimga_Pion| TPCTOF for negative daughter tracks"}; - -#define TWOTRACKRESONANCE_KAONPID_BITS \ - o2::framework::Configurable> posDauTpcKaon{"posDauTpcKaon", {3.f}, "Maximum |nsimga_Kaon| TPC for positive daughter tracks"}; \ - o2::framework::Configurable> posDauTofKaon{"posDauTofKaon", {}, "Maximum |nsimga_Kaon| TOF for positive daughter tracks"}; \ - o2::framework::Configurable> posDauTpctofKaon{"posDauTpctofKaon", {3.f}, "Maximum |nsimga_Kaon| TPCTOF for positive daughter tracks"}; \ - o2::framework::Configurable> negDauTpcKaon{"negDauTpcKaon", {3.f}, "Maximum |nsimga_Kaon| TPC for negative daughter tracks"}; \ - o2::framework::Configurable> negDauTofKaon{"negDauTofKaon", {}, "Maximum |nsimga_Kaon| TOF for negative daughter tracks"}; \ - o2::framework::Configurable> negDauTpctofKaon{"negDauTpctofKaon", {3.f}, "Maximum |nsimga_Kaon| TPCTOF for negative daughter tracks"}; - -struct ConfPhiBits : o2::framework::ConfigurableGroup { - std::string prefix = std::string("PhiBits"); - TWOTRACKRESONANCE_DEFAULT_BITS(0.4f, 0.4f) - TWOTRACKRESONANCE_KAONPID_BITS -}; - -struct ConfRho0Bits : o2::framework::ConfigurableGroup { - std::string prefix = std::string("Rho0Bits"); - TWOTRACKRESONANCE_DEFAULT_BITS(0.5f, 0.5f) - TWOTRACKRESONANCE_PIONPID_BITS -}; - -struct ConfKstar0Bits : o2::framework::ConfigurableGroup { - std::string prefix = std::string("Kstar0Bits"); - TWOTRACKRESONANCE_DEFAULT_BITS(0.5f, 0.4f) - TWOTRACKRESONANCE_PIONPID_BITS - TWOTRACKRESONANCE_KAONPID_BITS -}; - -#undef TWOTRACKRESONANCE_DEFAULT_BITS -#undef TWOTRACKRESONANCE_KAONPID_BITS -#undef TWOTRACKRESONANCE_PIONPID_BITS - -#define TWOTRACKRESONANCE_DEFAULT_SELECTION(defaultPdgCode, defaultMassMin, defaultMassMax) \ - o2::framework::Configurable pdgCodeAbs{"pdgCodeAbs", defaultPdgCode, "Resonance PDG code. Set sign to minus 1 for antiparticle"}; \ - o2::framework::Configurable ptMin{"ptMin", 0.f, "Minimum pT"}; \ - o2::framework::Configurable ptMax{"ptMax", 6.f, "Maximum pT"}; \ - o2::framework::Configurable etaMin{"etaMin", -0.9f, "Minimum eta"}; \ - o2::framework::Configurable etaMax{"etaMax", 0.9f, "Maximum eta"}; \ - o2::framework::Configurable phiMin{"phiMin", 0.f, "Minimum phi"}; \ - o2::framework::Configurable phiMax{"phiMax", 1.f * o2::constants::math::TwoPI, "Maximum phi"}; \ - o2::framework::Configurable massMin{"massMin", defaultMassMin, "Minimum invariant mass for Resonance"}; \ - o2::framework::Configurable massMax{"massMax", defaultMassMax, "Maximum invariant mass for Resonance"}; \ - o2::framework::Configurable posDauBitForThres{"posDauBitForThres", 0x20u, "Bit marking momentum threshold for positive daughter"}; \ - o2::framework::Configurable posDauMaskBelowThres{"posDauMaskBelowThres", 0x10u, "Bitmask for positive daughter below threshold"}; \ - o2::framework::Configurable posDauMaskAboveThres{"posDauMaskAboveThres", 0x8u, "Bitmask for positive daughter above threshold"}; \ - o2::framework::Configurable negDauBitForThres{"negDauBitForThres", 0x4u, "Bit marking momentum threshold for negative daughter"}; \ - o2::framework::Configurable negDauMaskBelowThres{"negDauMaskBelowThres", 0x2u, "Bitmask for negative daughter below threshold"}; \ - o2::framework::Configurable negDauMaskAboveThres{"negDauMaskAboveThres", 0x1u, "Bitmask for negative daughter above threshold"}; +#define TWOTRACKRESONANCE_DEFAULT_SELECTION(defaultPdgCode, defaultMassMin, defaultMassMax) \ + o2::framework::Configurable pdgCodeAbs{"pdgCodeAbs", defaultPdgCode, "Resonance PDG code. Set sign to minus 1 for antiparticle"}; \ + o2::framework::Configurable ptMin{"ptMin", 0.f, "Minimum pT"}; \ + o2::framework::Configurable ptMax{"ptMax", 6.f, "Maximum pT"}; \ + o2::framework::Configurable etaMin{"etaMin", -0.9f, "Minimum eta"}; \ + o2::framework::Configurable etaMax{"etaMax", 0.9f, "Maximum eta"}; \ + o2::framework::Configurable phiMin{"phiMin", 0.f, "Minimum phi"}; \ + o2::framework::Configurable phiMax{"phiMax", 1.f * o2::constants::math::TwoPI, "Maximum phi"}; \ + o2::framework::Configurable massMin{"massMin", defaultMassMin, "Minimum invariant mass for Resonance"}; \ + o2::framework::Configurable massMax{"massMax", defaultMassMax, "Maximum invariant mass for Resonance"}; \ + o2::framework::Configurable posDauMaskBelowThres{"posDauMaskBelowThres", 0x10u, "Bitmask for positive daughter below threshold"}; \ + o2::framework::Configurable posDauMaskAboveThres{"posDauMaskAboveThres", 0x8u, "Bitmask for positive daughter above threshold"}; \ + o2::framework::Configurable negDauMaskBelowThres{"negDauMaskBelowThres", 0x2u, "Bitmask for negative daughter below threshold"}; \ + o2::framework::Configurable negDauMaskAboveThres{"negDauMaskAboveThres", 0x1u, "Bitmask for negative daughter above threshold"}; struct ConfPhiSelection : o2::framework::ConfigurableGroup { std::string prefix = std::string("PhiSelection"); @@ -166,289 +96,6 @@ struct ConfKstar0Selection : o2::framework::ConfigurableGroup { #undef TWOTRACKRESONANCE_DEFAULT_SELECTION -/// The different selections this task is capable of doing -enum TwoTrackResonanceSels { - - // common selections for both daughters - kDauEtaAbsMax, ///< max |eta| - kDauTpcClusterMin, ///< min number of TPC cluster - kDauDcaxyAbsMax, ///< max |DCA_xy| - kDauDcazAbsMax, ///< max |DCA_z| - - // selection for positive daughter - // add one bit for the momentum threshold - // when the partition for a resonance is build, we do not have information about the daughter tracks so have to store everything needed for the selection here - kPosDauMinMomForTof, ///< min p for TOF - kPosDauPtMin, ///< min pt - kPosDauPtMax, ///< max pt - kPosDauTpcPion, /// < max |nsigma_TPC| for pion - kPosDauTofPion, /// < max |nsigma_TOF| for pion - kPosDauTpctofPion, /// < max |nsigma_TPC+TOF| for pion - kPosDauTpcKaon, /// < max |nsigma_TPC| for kaon - kPosDauTofKaon, /// < max |nsigma_TOF| for kaon - kPosDauTpctofKaon, /// < max |nsigma_TPC+TOF| for kaon - - // selection for negative daughter - kNegDauMinMomForTof, ///< min p for TOF - kNegDauPtMin, ///< min pt - kNegDauPtMax, ///< max pt - kNegDauTpcPion, /// < max |nsigma_TPC| for pion - kNegDauTofPion, /// < max |nsigma_TOF| for pion - kNegDauTpctofPion, /// < max |nsigma_TPC+TOF| for pion - kNegDauTpcKaon, /// < max |nsigma_TPC| for kaon - kNegDauTofKaon, /// < max |nsigma_TOF| for kaon - kNegDauTpctofKaon, /// < max |nsigma_TPC+TOF| for kaon - - kResonanceSelsMax -}; - -constexpr char PhiSelHistName[] = "hPhiSelection"; -constexpr char RhoSelHistName[] = "hRhoSelection"; -constexpr char Kstar0SelHistName[] = "hKstar0Selection"; -constexpr char Kstar0barSelHistName[] = "hKstar0BarSelection"; -constexpr char TwoTrackResonanceSelsName[] = "TwoTrackResonance Selection Object"; -const std::unordered_map twoTrackResonanceSelectionNames = { - {kDauEtaAbsMax, "Max. |eta| of daughters"}, - {kDauTpcClusterMin, "Min. number of TPC clusters of daughters"}, - {kDauDcaxyAbsMax, "Max. |DCA_xy| of daughters"}, - {kDauDcazAbsMax, "Max. |DCA_z| of the daughters"}, - {kPosDauMinMomForTof, "Min. p of TOF PID of positive daughter"}, - {kPosDauPtMin, "Min. pt of positive daughter"}, - {kPosDauPtMax, "Max. pt of positive daughter"}, - {kPosDauTpcPion, "Max. |sigma_TPC| for pion of positive daughter"}, - {kPosDauTofPion, "Max. |sigma_TOF| for pion of positive daughter"}, - {kPosDauTpctofPion, "Max. |sigma_TPCTOF| for pion of positive daughter"}, - {kPosDauTpcKaon, "Max. |sigma_TPC| for kaon of positive daughter"}, - {kPosDauTofKaon, "Max. |sigma_TOF| for kaon of positive daughter"}, - {kPosDauTpctofKaon, "Max. |sigma_TPCTOF| for kaon of positive daughter"}, - {kNegDauMinMomForTof, "Min. p for TOF PID of negative daughter"}, - {kNegDauPtMin, "Min. pt of negative daughter"}, - {kNegDauPtMax, "Max. pt of negative daughter"}, - {kNegDauTpcPion, "Max. |sigma_TPC| for pion of negative daughter"}, - {kNegDauTofPion, "Max. |sigma_TOF| for pion of negative daughter"}, - {kNegDauTpctofPion, "Max. |sigma_TPCTOF| for pion of negative daughter"}, - {kNegDauTpcKaon, "Max. |sigma_TPC| for kaon of negative daughter"}, - {kNegDauTofKaon, "Max. |sigma_TOF| for kaon of negative daughter"}, - {kNegDauTpctofKaon, "Max. |sigma_TPCTOF| for kaon of negative daughter"}}; - -/// \class FemtoDreamTrackCuts -/// \brief Cut class to contain and execute all cuts applied to tracks -template -class TwoTrackResonanceSelection : public BaseSelection -{ - public: - TwoTrackResonanceSelection() = default; - ~TwoTrackResonanceSelection() = default; - - template - void configure(o2::framework::HistogramRegistry* registry, T1& config, T2& filter, T3& daughterFilter) - { - if constexpr (modes::isEqual(resoType, modes::TwoTrackResonance::kPhi)) { - mPosDaughterMass = o2::constants::physics::MassKPlus; - mNegDaughterMass = o2::constants::physics::MassKMinus; - this->addSelection(kPosDauTpcKaon, twoTrackResonanceSelectionNames.at(kPosDauTpcKaon), config.posDauTpcKaon.value, limits::kAbsUpperLimit, false, false, true); - this->addSelection(kPosDauTofKaon, twoTrackResonanceSelectionNames.at(kPosDauTofKaon), config.posDauTofKaon.value, limits::kAbsUpperLimit, false, false, true); - this->addSelection(kPosDauTpctofKaon, twoTrackResonanceSelectionNames.at(kPosDauTpctofKaon), config.posDauTpctofKaon.value, limits::kUpperLimit, false, false, true); - this->addSelection(kNegDauTpcKaon, twoTrackResonanceSelectionNames.at(kNegDauTpcKaon), config.negDauTpcKaon.value, limits::kAbsUpperLimit, false, false, true); - this->addSelection(kNegDauTofKaon, twoTrackResonanceSelectionNames.at(kNegDauTofKaon), config.negDauTofKaon.value, limits::kAbsUpperLimit, false, false, true); - this->addSelection(kNegDauTpctofKaon, twoTrackResonanceSelectionNames.at(kNegDauTpctofKaon), config.negDauTpctofKaon.value, limits::kUpperLimit, false, false, true); - } - if constexpr (modes::isEqual(resoType, modes::TwoTrackResonance::kRho0)) { - mPosDaughterMass = o2::constants::physics::MassPiPlus; - mNegDaughterMass = o2::constants::physics::MassPiMinus; - this->addSelection(kPosDauTpcPion, twoTrackResonanceSelectionNames.at(kPosDauTpcPion), config.posDauTpcPion.value, limits::kAbsUpperLimit, false, false, true); - this->addSelection(kPosDauTofPion, twoTrackResonanceSelectionNames.at(kPosDauTofPion), config.posDauTofPion.value, limits::kAbsUpperLimit, false, false, true); - this->addSelection(kPosDauTpctofPion, twoTrackResonanceSelectionNames.at(kPosDauTpctofPion), config.posDauTpctofPion.value, limits::kUpperLimit, false, false, true); - this->addSelection(kNegDauTpcPion, twoTrackResonanceSelectionNames.at(kNegDauTpcPion), config.negDauTpcPion.value, limits::kAbsUpperLimit, false, false, true); - this->addSelection(kNegDauTofPion, twoTrackResonanceSelectionNames.at(kNegDauTofPion), config.negDauTofPion.value, limits::kAbsUpperLimit, false, false, true); - this->addSelection(kNegDauTpctofPion, twoTrackResonanceSelectionNames.at(kNegDauTpctofPion), config.negDauTpctofPion.value, limits::kUpperLimit, false, false, true); - } - if constexpr (modes::isEqual(resoType, modes::TwoTrackResonance::kKstar0)) { - mPosDaughterMass = o2::constants::physics::MassKPlus; - mNegDaughterMass = o2::constants::physics::MassPiMinus; - this->addSelection(kPosDauTpcKaon, twoTrackResonanceSelectionNames.at(kPosDauTpcKaon), config.posDauTpcKaon.value, limits::kAbsUpperLimit, false, false, true); - this->addSelection(kPosDauTofKaon, twoTrackResonanceSelectionNames.at(kPosDauTofKaon), config.posDauTofKaon.value, limits::kAbsUpperLimit, false, false, true); - this->addSelection(kPosDauTpctofKaon, twoTrackResonanceSelectionNames.at(kPosDauTpctofKaon), config.posDauTpctofKaon.value, limits::kUpperLimit, false, false, true); - this->addSelection(kNegDauTpcPion, twoTrackResonanceSelectionNames.at(kNegDauTpcPion), config.negDauTpcPion.value, limits::kAbsUpperLimit, false, false, true); - this->addSelection(kNegDauTofPion, twoTrackResonanceSelectionNames.at(kNegDauTofPion), config.negDauTofPion.value, limits::kAbsUpperLimit, false, false, true); - this->addSelection(kNegDauTpctofPion, twoTrackResonanceSelectionNames.at(kNegDauTpctofPion), config.negDauTpctofPion.value, limits::kUpperLimit, false, false, true); - } - if constexpr (modes::isEqual(resoType, modes::TwoTrackResonance::kKstar0Bar)) { - mPosDaughterMass = o2::constants::physics::MassPiPlus; - mNegDaughterMass = o2::constants::physics::MassKMinus; - this->addSelection(kPosDauTpcPion, twoTrackResonanceSelectionNames.at(kPosDauTpcPion), config.posDauTpcPion.value, limits::kAbsUpperLimit, false, false, true); - this->addSelection(kPosDauTofPion, twoTrackResonanceSelectionNames.at(kPosDauTofPion), config.posDauTofPion.value, limits::kAbsUpperLimit, false, false, true); - this->addSelection(kPosDauTpctofPion, twoTrackResonanceSelectionNames.at(kPosDauTpctofPion), config.posDauTpctofPion.value, limits::kUpperLimit, false, false, true); - this->addSelection(kNegDauTpcKaon, twoTrackResonanceSelectionNames.at(kNegDauTpcKaon), config.negDauTpcKaon.value, limits::kAbsUpperLimit, false, false, true); - this->addSelection(kNegDauTofKaon, twoTrackResonanceSelectionNames.at(kNegDauTofKaon), config.negDauTofKaon.value, limits::kAbsUpperLimit, false, false, true); - this->addSelection(kNegDauTpctofKaon, twoTrackResonanceSelectionNames.at(kNegDauTpctofKaon), config.negDauTpctofKaon.value, limits::kUpperLimit, false, false, true); - } - - mMassMin = filter.massMin.value; - mMassMax = filter.massMax.value; - mPtMin = filter.ptMin.value; - mPtMax = filter.ptMax.value; - mEtaMin = filter.etaMin.value; - mEtaMax = filter.etaMax.value; - mPhiMin = filter.phiMin.value; - mPhiMax = filter.phiMax.value; - - this->addSelection(kDauEtaAbsMax, twoTrackResonanceSelectionNames.at(kDauEtaAbsMax), config.dauEtaMax.value, limits::kAbsUpperLimit, true, true, false); - this->addSelection(kDauTpcClusterMin, twoTrackResonanceSelectionNames.at(kDauTpcClusterMin), config.dauTpcClustersMin.value, limits::kLowerLimit, true, true, false); - this->addSelection(kDauDcaxyAbsMax, twoTrackResonanceSelectionNames.at(kDauDcaxyAbsMax), daughterFilter.ptMin.value, daughterFilter.ptMax.value, config.dauDcaxyMax.value, limits::kAbsUpperFunctionLimit, true, true, false); - this->addSelection(kDauDcazAbsMax, twoTrackResonanceSelectionNames.at(kDauDcazAbsMax), daughterFilter.ptMin.value, daughterFilter.ptMax.value, config.dauDcazMax.value, limits::kAbsUpperFunctionLimit, true, true, false); - this->addSelection(kPosDauMinMomForTof, twoTrackResonanceSelectionNames.at(kPosDauMinMomForTof), config.posDauMinMomForTof.value, limits::kUpperLimit, false, false, true); // momentum threshold for TOF is no minimal/optional cut - this->addSelection(kPosDauPtMin, twoTrackResonanceSelectionNames.at(kPosDauPtMin), config.posDauPtMin.value, limits::kLowerLimit, true, true, false); - this->addSelection(kPosDauPtMax, twoTrackResonanceSelectionNames.at(kPosDauPtMax), config.posDauPtMax.value, limits::kUpperLimit, true, true, false); - - this->addSelection(kNegDauMinMomForTof, twoTrackResonanceSelectionNames.at(kNegDauMinMomForTof), config.negDauMinMomForTof.value, limits::kUpperLimit, false, false, true); // momentum threshold for TOF is no minimal/optional cut - this->addSelection(kNegDauPtMin, twoTrackResonanceSelectionNames.at(kNegDauPtMin), config.negDauPtMin.value, limits::kLowerLimit, true, true, false); - this->addSelection(kNegDauPtMax, twoTrackResonanceSelectionNames.at(kNegDauPtMax), config.negDauPtMax.value, limits::kUpperLimit, true, true, false); - - this->setupContainers(registry); - }; - - template - void reconstructResonance(Tracks const& posDaughter, Tracks const& negDaughter) - { - - ROOT::Math::PtEtaPhiMVector vecPosDaughter{posDaughter.pt(), posDaughter.eta(), posDaughter.phi(), mPosDaughterMass}; - ROOT::Math::PtEtaPhiMVector vecNegDaughter{negDaughter.pt(), negDaughter.eta(), negDaughter.phi(), mNegDaughterMass}; - ROOT::Math::PtEtaPhiMVector vecResonance = vecPosDaughter + vecNegDaughter; - - // cache kinematics - mMass = vecResonance.M(); - mPt = vecResonance.Pt(); - mEta = vecResonance.Eta(); - mPhi = RecoDecay::constrainAngle(vecResonance.Phi()); - } - - bool checkFilters() const - { - return ((mMass > mMassMin && mMass < mMassMax) && - (mPt > mPtMin && mPt < mPtMax) && - (mEta > mEtaMin && mEta < mEtaMax) && - (mPhi > mPhiMin && mPhi < mPhiMax)); - } - - float getPt() const { return mPt; } - float getEta() const { return mEta; } - float getPhi() const { return mPhi; } - float getMass() const { return mMass; } - - template - void applySelections(Tracks const& posDaughter, Tracks const& negDaughter) - { - this->reset(); - // for resonances, topological selection are in general not possible, so only selections on the daughters are performed - - // common daugher selections - std::array etaDaughters = {std::fabs(posDaughter.eta()), std::fabs(negDaughter.eta())}; - this->evaluateObservable(kDauEtaAbsMax, *std::max_element(etaDaughters.begin(), etaDaughters.end())); - std::array tpcClusterDaughters = {1.f * posDaughter.tpcNClsFound(), 1.f * negDaughter.tpcNClsFound()}; - this->evaluateObservable(kDauTpcClusterMin, *std::min_element(tpcClusterDaughters.begin(), tpcClusterDaughters.end())); - - // check pt dependend dca cut on both daughters - // we apply the same cut to both daughters so we only want to store the result were both daughters survive the cut - // since momenta of daughters are different, we compute the bitmask for both, combine them with logical AND and keep the result - uint64_t bitmaskDcaPos, bitmaskDcaNeg, bitmaskDca; - this->updateLimits(kDauDcaxyAbsMax, posDaughter.pt()); - this->evaluateObservable(kDauDcaxyAbsMax, posDaughter.dcaXY()); - bitmaskDcaPos = this->getBitmask(kDauDcaxyAbsMax); - this->updateLimits(kDauDcaxyAbsMax, negDaughter.pt()); - this->evaluateObservable(kDauDcaxyAbsMax, negDaughter.dcaXY()); - bitmaskDcaNeg = this->getBitmask(kDauDcaxyAbsMax); - bitmaskDca = bitmaskDcaPos & bitmaskDcaNeg; - this->setBitmask(kDauDcaxyAbsMax, bitmaskDca); - - this->updateLimits(kDauDcazAbsMax, posDaughter.pt()); - this->evaluateObservable(kDauDcazAbsMax, posDaughter.dcaZ()); - bitmaskDcaPos = this->getBitmask(kDauDcazAbsMax); - this->updateLimits(kDauDcazAbsMax, negDaughter.pt()); - this->evaluateObservable(kDauDcazAbsMax, negDaughter.dcaZ()); - bitmaskDcaNeg = this->getBitmask(kDauDcazAbsMax); - bitmaskDca = bitmaskDcaPos & bitmaskDcaNeg; - this->setBitmask(kDauDcazAbsMax, bitmaskDca); - - // positive daughter selections - this->evaluateObservable(kPosDauMinMomForTof, posDaughter.p()); - this->evaluateObservable(kPosDauPtMin, posDaughter.pt()); - this->evaluateObservable(kPosDauPtMax, posDaughter.pt()); - - float tofThreshold = this->getLoosestSelection(kPosDauMinMomForTof); - if (posDaughter.p() <= tofThreshold) { - this->evaluateObservable(kPosDauTpcPion, posDaughter.tpcNSigmaPi()); - this->evaluateObservable(kPosDauTofPion, posDaughter.tofNSigmaPi()); - this->evaluateObservable(kPosDauTpctofPion, std::hypot(posDaughter.tpcNSigmaPi(), posDaughter.tofNSigmaPi())); - this->evaluateObservable(kPosDauTpcKaon, posDaughter.tpcNSigmaKa()); - this->evaluateObservable(kPosDauTofKaon, posDaughter.tofNSigmaKa()); - this->evaluateObservable(kPosDauTpctofKaon, std::hypot(posDaughter.tpcNSigmaKa(), posDaughter.tofNSigmaKa())); - } else if (posDaughter.p() > tofThreshold && posDaughter.hasTOF()) { - this->evaluateObservable(kPosDauTofPion, posDaughter.tofNSigmaPi()); - this->evaluateObservable(kPosDauTpctofPion, std::hypot(posDaughter.tpcNSigmaPi(), posDaughter.tofNSigmaPi())); - this->evaluateObservable(kPosDauTofKaon, posDaughter.tofNSigmaKa()); - this->evaluateObservable(kPosDauTpctofKaon, std::hypot(posDaughter.tpcNSigmaKa(), posDaughter.tofNSigmaKa())); - if (this->passesOptionalSelection(kPosDauTofPion) || - this->passesOptionalSelection(kPosDauTpctofPion) || - this->passesOptionalSelection(kPosDauTofKaon) || - this->passesOptionalSelection(kPosDauTpctofKaon)) { - this->evaluateObservable(kPosDauTpcPion, posDaughter.tpcNSigmaPi()); - this->evaluateObservable(kPosDauTpcKaon, posDaughter.tpcNSigmaKa()); - } - } - - // negative daughter selections - this->evaluateObservable(kNegDauMinMomForTof, negDaughter.p()); - this->evaluateObservable(kNegDauPtMin, negDaughter.pt()); - this->evaluateObservable(kNegDauPtMax, negDaughter.pt()); - - tofThreshold = this->getLoosestSelection(kNegDauMinMomForTof); - if (negDaughter.p() < tofThreshold) { - this->evaluateObservable(kNegDauTpcPion, negDaughter.tpcNSigmaPi()); - this->evaluateObservable(kNegDauTofPion, negDaughter.tofNSigmaPi()); - this->evaluateObservable(kNegDauTpctofPion, std::hypot(negDaughter.tpcNSigmaPi(), negDaughter.tofNSigmaPi())); - this->evaluateObservable(kNegDauTpcKaon, negDaughter.tpcNSigmaKa()); - this->evaluateObservable(kNegDauTofKaon, negDaughter.tofNSigmaKa()); - this->evaluateObservable(kNegDauTpctofKaon, std::hypot(negDaughter.tpcNSigmaKa(), negDaughter.tofNSigmaKa())); - } else if (negDaughter.p() > tofThreshold && negDaughter.hasTOF()) { - this->evaluateObservable(kNegDauTofPion, negDaughter.tofNSigmaPi()); - this->evaluateObservable(kNegDauTpctofPion, std::hypot(negDaughter.tpcNSigmaPi(), negDaughter.tofNSigmaPi())); - this->evaluateObservable(kNegDauTofKaon, negDaughter.tofNSigmaKa()); - this->evaluateObservable(kNegDauTpctofKaon, std::hypot(negDaughter.tpcNSigmaKa(), negDaughter.tofNSigmaKa())); - if (this->passesOptionalSelection(kNegDauTofPion) || - this->passesOptionalSelection(kNegDauTpctofPion) || - this->passesOptionalSelection(kNegDauTofKaon) || - this->passesOptionalSelection(kNegDauTpctofKaon)) { - this->evaluateObservable(kNegDauTpcPion, negDaughter.tpcNSigmaPi()); - this->evaluateObservable(kNegDauTpcKaon, negDaughter.tpcNSigmaKa()); - } - } - - this->assembleBitmask(); - }; - - protected: - // (cached) kinematic variables of the resonance - float mPt = 0.f; - float mEta = 0.f; - float mPhi = 0.f; - float mMass = 0.f; - - // kinematic selections of the resonance - float mMassMin = 0.f; - float mMassMax = 6.f; - float mPtMin = 0.f; - float mPtMax = 6.f; - float mEtaMin = -0.9f; - float mEtaMax = 0.9f; - float mPhiMin = 0.f; - float mPhiMax = o2::constants::math::TwoPI; - - // daughter masses - float mPosDaughterMass = 0.f; - float mNegDaughterMass = 0.f; -}; - struct TwoTrackResonanceBuilderProducts : o2::framework::ProducesGroup { o2::framework::Produces producedPhis; o2::framework::Produces producedPhiMasks; @@ -468,7 +115,7 @@ struct ConfTwoTrackResonanceTables : o2::framework::ConfigurableGroup { o2::framework::Configurable produceRho0Masks{"produceRho0Masks", -1, "Produce Rho0Masks (-1: auto; 0 off; 1 on)"}; }; -template +template class TwoTrackResonanceBuilder { public: @@ -476,27 +123,48 @@ class TwoTrackResonanceBuilder ~TwoTrackResonanceBuilder() = default; template - void init(o2::framework::HistogramRegistry* registry, T1& config, T2& filter, T3& daughterFilter, T4& table, T5 initContext) + void init(T1& confFilter, T2& confPosDauSelection, T3& confNegDauSelection, T4& confTable, T5& initContext) { + + mMassMin = confFilter.massMin.value; + mMassMax = confFilter.massMax.value; + mPtMin = confFilter.ptMin.value; + mPtMax = confFilter.ptMax.value; + mEtaMin = confFilter.etaMin.value; + mEtaMax = confFilter.etaMax.value; + mPhiMin = confFilter.phiMin.value; + mPhiMax = confFilter.phiMax.value; + + mPosDauThreshold = confPosDauSelection.pidThres.value; + mNegDauThreshold = confNegDauSelection.pidThres.value; + if constexpr (modes::isEqual(resoType, modes::TwoTrackResonance::kPhi)) { LOG(info) << "Initialize femto Phi builder..."; - mProducePhis = utils::enableTable("FPhis_001", table.producePhis.value, initContext); - mProducePhiMasks = utils::enableTable("FPhiMasks_001", table.producePhiMasks.value, initContext); + mPosDaughterMass = o2::constants::physics::MassKPlus; + mNegDaughterMass = o2::constants::physics::MassKMinus; + mProducePhis = utils::enableTable("FPhis_001", confTable.producePhis.value, initContext); + mProducePhiMasks = utils::enableTable("FPhiMasks_001", confTable.producePhiMasks.value, initContext); } if constexpr (modes::isEqual(resoType, modes::TwoTrackResonance::kKstar0) || modes::isEqual(resoType, modes::TwoTrackResonance::kKstar0Bar)) { if constexpr (modes::isEqual(resoType, modes::TwoTrackResonance::kKstar0)) { LOG(info) << "Initialize femto Kstar0 builder..."; + mPosDaughterMass = o2::constants::physics::MassKPlus; + mNegDaughterMass = o2::constants::physics::MassPiMinus; } if constexpr (modes::isEqual(resoType, modes::TwoTrackResonance::kKstar0Bar)) { LOG(info) << "Initialize femto Kstar0Bar builder..."; + mPosDaughterMass = o2::constants::physics::MassPiPlus; + mNegDaughterMass = o2::constants::physics::MassKMinus; } - mProduceKstar0s = utils::enableTable("FKstar0s_001", table.produceKstar0s.value, initContext); - mProduceKstar0Masks = utils::enableTable("FKstar0Masks_001", table.produceKstar0Masks.value, initContext); + mProduceKstar0s = utils::enableTable("FKstar0s_001", confTable.produceKstar0s.value, initContext); + mProduceKstar0Masks = utils::enableTable("FKstar0Masks_001", confTable.produceKstar0Masks.value, initContext); } if constexpr (modes::isEqual(resoType, modes::TwoTrackResonance::kRho0)) { LOG(info) << "Initialize femto Rho0 builder..."; - mProduceRho0s = utils::enableTable("FRho0s_001", table.produceRho0s.value, initContext); - mProduceRho0Masks = utils::enableTable("FRho0Masks_001", table.produceRho0Masks.value, initContext); + mPosDaughterMass = o2::constants::physics::MassPiPlus; + mNegDaughterMass = o2::constants::physics::MassPiMinus; + mProduceRho0s = utils::enableTable("FRho0s_001", confTable.produceRho0s.value, initContext); + mProduceRho0Masks = utils::enableTable("FRho0Masks_001", confTable.produceRho0Masks.value, initContext); } if (mProducePhis || mProducePhiMasks || mProduceKstar0s || mProduceKstar0Masks || mProduceRho0s || mProduceRho0Masks) { @@ -506,111 +174,147 @@ class TwoTrackResonanceBuilder LOG(info) << "Initialization done..."; return; } - mTwoTrackResonanceSelection.configure(registry, config, filter, daughterFilter); - mTwoTrackResonanceSelection.printSelections(TwoTrackResonanceSelsName); LOG(info) << "Initialization done..."; } - template - void fillResonances(T1 const& col, T2& collisionBuilder, T3& collisionProducts, T4& trackProducts, T5& resonanceProducts, T6 const& groupPositiveTracks, T7 const& groupNegativeTracks, T8 const& tracks, T9 const& tracksWithItsPid, T10& trackBuilder) + template + void fillResonances(T1 const& col, T2& resonanceProducts, T3& posDaughterPartition, T4& negDaughterPartition, T5 const& /*trackTable*/, T6& cache) { if (!mFillAnyTable) { return; } - for (auto const& [positiveTrack, negativeTrack] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(groupPositiveTracks, groupNegativeTracks))) { - auto positiveTrackWithItsPid = tracksWithItsPid.iteratorAt(positiveTrack.index() - tracks.offset()); - auto negativeTrackWithItsPid = tracksWithItsPid.iteratorAt(negativeTrack.index() - tracks.offset()); - - this->fillResonance(col, collisionBuilder, collisionProducts, trackProducts, resonanceProducts, positiveTrackWithItsPid, negativeTrackWithItsPid, trackBuilder); + auto posDaughterSlice = posDaughterPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + auto negDaughterSlice = negDaughterPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + // LOG(warn) << "Size: " << posDaughterSlice.size() << " " << negDaughterSlice.size(); + for (auto const& [posDaughter, negDaughter] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(posDaughterSlice, negDaughterSlice))) { + this->fillResonance(col, posDaughter, negDaughter, resonanceProducts); } } - template - void fillResonance(T1 const& col, T2& collisionBuilder, T3& collisionProducts, T4& trackProducts, T5& resonanceProducts, T6 const& posDaughter, T7 const& negDaughter, T8& trackBuilder) + private: + template + void reconstructResonance(T1 const& posDaughter, T2 const& negDaughter) { + ROOT::Math::PtEtaPhiMVector vecPosDaughter{posDaughter.pt(), posDaughter.eta(), posDaughter.phi(), mPosDaughterMass}; + ROOT::Math::PtEtaPhiMVector vecNegDaughter{negDaughter.pt(), negDaughter.eta(), negDaughter.phi(), mNegDaughterMass}; + ROOT::Math::PtEtaPhiMVector vecResonance = vecPosDaughter + vecNegDaughter; - mTwoTrackResonanceSelection.reconstructResonance(posDaughter, negDaughter); - if (!mTwoTrackResonanceSelection.checkFilters()) { - return; - } - mTwoTrackResonanceSelection.applySelections(posDaughter, negDaughter); // for resonances selection are only applied to daughter tracks + mPt = vecResonance.Pt(); + mEta = vecResonance.Eta(); + mPhi = RecoDecay::constrainAngle(vecResonance.Phi()); + mMass = vecResonance.M(); + } + + bool checkFilters() const + { + return ((mMass > mMassMin && mMass < mMassMax) && + (mPt > mPtMin && mPt < mPtMax) && + (mEta > mEtaMin && mEta < mEtaMax) && + (mPhi > mPhiMin && mPhi < mPhiMax)); + } - if (!mTwoTrackResonanceSelection.passesAllRequiredSelections()) { + template + void fillResonance(T1 const& col, T2 const& posDaughter, T3 const& negDaughter, T4& resonanceProducts) + { + reconstructResonance(posDaughter, negDaughter); + if (!checkFilters()) { return; } - int64_t posDaughterIndex = 0; - int64_t negDaughterIndex = 0; - - collisionBuilder.template fillCollision(collisionProducts, col); - - posDaughterIndex = trackBuilder.template getDaughterIndex(posDaughter, trackProducts, collisionProducts); - negDaughterIndex = trackBuilder.template getDaughterIndex(negDaughter, trackProducts, collisionProducts); + bool posDauHasHighMomentum = posDaughter.p() > mPosDauThreshold; + bool negDauHasHighMomentum = negDaughter.p() > mNegDauThreshold; if constexpr (modes::isEqual(resoType, modes::TwoTrackResonance::kRho0)) { if (mProduceRho0s) { - resonanceProducts.producedRhos( - collisionProducts.producedCollision.lastIndex(), - mTwoTrackResonanceSelection.getPt(), - mTwoTrackResonanceSelection.getEta(), - mTwoTrackResonanceSelection.getPhi(), - mTwoTrackResonanceSelection.getMass(), - posDaughterIndex, - negDaughterIndex); + resonanceProducts.producedRhos(col.globalIndex(), + mPt, + mEta, + mPhi, + mMass, + posDaughter.globalIndex(), + negDaughter.globalIndex()); } if (mProduceRho0Masks) { - resonanceProducts.producedRhoMasks(mTwoTrackResonanceSelection.getBitmask()); + resonanceProducts.producedRhoMasks(posDaughter.mask(), + posDauHasHighMomentum, + negDaughter.mask(), + negDauHasHighMomentum); } } if constexpr (modes::isEqual(resoType, modes::TwoTrackResonance::kPhi)) { if (mProducePhis) { - resonanceProducts.producedPhis( - collisionProducts.producedCollision.lastIndex(), - mTwoTrackResonanceSelection.getPt(), - mTwoTrackResonanceSelection.getEta(), - mTwoTrackResonanceSelection.getPhi(), - mTwoTrackResonanceSelection.getMass(), - posDaughterIndex, - negDaughterIndex); + resonanceProducts.producedPhis(col.globalIndex(), + mPt, + mEta, + mPhi, + mMass, + posDaughter.globalIndex(), + negDaughter.globalIndex()); } if (mProducePhiMasks) { - resonanceProducts.producedPhiMasks(mTwoTrackResonanceSelection.getBitmask()); + resonanceProducts.producedPhiMasks(posDaughter.mask(), + posDauHasHighMomentum, + negDaughter.mask(), + negDauHasHighMomentum); } } if constexpr (modes::isEqual(resoType, modes::TwoTrackResonance::kKstar0)) { if (mProduceKstar0s) { - resonanceProducts.producedKstars( - collisionProducts.producedCollision.lastIndex(), - mTwoTrackResonanceSelection.getPt(), - mTwoTrackResonanceSelection.getEta(), - mTwoTrackResonanceSelection.getPhi(), - mTwoTrackResonanceSelection.getMass(), - posDaughterIndex, - negDaughterIndex); + resonanceProducts.producedKstars(col.globalIndex(), + mPt, + mEta, + mPhi, + mMass, + posDaughter.globalIndex(), + negDaughter.globalIndex()); } if (mProduceKstar0Masks) { - resonanceProducts.producedKstarMasks(mTwoTrackResonanceSelection.getBitmask()); + resonanceProducts.producedKstarMasks(posDaughter.mask(), + posDauHasHighMomentum, + negDaughter.mask(), + negDauHasHighMomentum); } } if constexpr (modes::isEqual(resoType, modes::TwoTrackResonance::kKstar0Bar)) { if (mProduceKstar0s) { - resonanceProducts.producedKstars( - collisionProducts.producedCollision.lastIndex(), - -1.f * mTwoTrackResonanceSelection.getPt(), - mTwoTrackResonanceSelection.getEta(), - mTwoTrackResonanceSelection.getPhi(), - mTwoTrackResonanceSelection.getMass(), - posDaughterIndex, - negDaughterIndex); + resonanceProducts.producedKstars(col.globalIndex(), + mPt, + mEta, + mPhi, + mMass, + posDaughter.globalIndex(), + negDaughter.globalIndex()); } if (mProduceKstar0Masks) { - resonanceProducts.producedKstarMasks(mTwoTrackResonanceSelection.getBitmask()); + resonanceProducts.producedKstarMasks(posDaughter.mask(), + posDauHasHighMomentum, + negDaughter.mask(), + negDauHasHighMomentum); } } } - private: - TwoTrackResonanceSelection mTwoTrackResonanceSelection; + // cached kinamtics of the resonance + float mPt = 0; + float mEta = 0; + float mPhi = 0; + float mMass = 0; + + float mPosDaughterMass = 0.f; + float mNegDaughterMass = 0.f; + + float mPosDauThreshold = 0.f; + float mNegDauThreshold = 0.f; + + float mMassMin = 0.f; + float mMassMax = 0.f; + float mPtMin = 0.f; + float mPtMax = 0.f; + float mEtaMin = 0.f; + float mEtaMax = 0.f; + float mPhiMin = 0.f; + float mPhiMax = 0.f; + bool mFillAnyTable = false; bool mProducePhis = false; bool mProducePhiMasks = false; @@ -618,6 +322,7 @@ class TwoTrackResonanceBuilder bool mProduceKstar0Masks = false; bool mProduceRho0s = false; bool mProduceRho0Masks = false; + }; // namespace twotrackresonancebuilder } // namespace twotrackresonancebuilder diff --git a/PWGCF/Femto/DataModel/FemtoTables.h b/PWGCF/Femto/DataModel/FemtoTables.h index 23fd3e1e67c..5792f152278 100644 --- a/PWGCF/Femto/DataModel/FemtoTables.h +++ b/PWGCF/Femto/DataModel/FemtoTables.h @@ -331,7 +331,11 @@ using FTrackPids = soa::Join); using FPhis = FPhis_001; DECLARE_SOA_TABLE_STAGED_VERSIONED(FPhiMasks_001, "FPHIMASK", 1, //! mask for phis - femtotwotrackresonances::Mask); + femtotwotrackresonances::MaskPosDau, + femtotwotrackresonances::PosDauHasHighMomentum, + femtotwotrackresonances::MaskNegDau, + femtotwotrackresonances::NegDauHasHighMomentum); using FPhiMasks = FPhiMasks_001; // table for kstars @@ -376,7 +383,10 @@ DECLARE_SOA_TABLE_STAGED_VERSIONED(FKstar0s_001, "FKSTAR0", 1, //! femto k0star femtobase::dynamic::Theta); using FKstar0s = FKstar0s_001; DECLARE_SOA_TABLE_STAGED_VERSIONED(FKstar0Masks_001, "FKSTAR0MASK", 1, //! k0star masks - femtotwotrackresonances::Mask); + femtotwotrackresonances::MaskPosDau, + femtotwotrackresonances::PosDauHasHighMomentum, + femtotwotrackresonances::MaskNegDau, + femtotwotrackresonances::NegDauHasHighMomentum); using FKstar0Masks = FKstar0Masks_001; DECLARE_SOA_TABLE_STAGED_VERSIONED(FRho0s_001, "FRHO0", 1, //! femto rho0s @@ -395,7 +405,10 @@ DECLARE_SOA_TABLE_STAGED_VERSIONED(FRho0s_001, "FRHO0", 1, //! femto rho0s femtobase::dynamic::Theta); using FRho0s = FRho0s_001; DECLARE_SOA_TABLE_STAGED_VERSIONED(FRho0Masks_001, "FRHO0MASK", 1, //! rho0s masks - femtotwotrackresonances::Mask); + femtotwotrackresonances::MaskPosDau, + femtotwotrackresonances::PosDauHasHighMomentum, + femtotwotrackresonances::MaskNegDau, + femtotwotrackresonances::NegDauHasHighMomentum); using FRho0Masks = FRho0Masks_001; namespace femtov0s diff --git a/PWGCF/Femto/TableProducer/CMakeLists.txt b/PWGCF/Femto/TableProducer/CMakeLists.txt index 666b21a839c..8fb76cfc5fb 100644 --- a/PWGCF/Femto/TableProducer/CMakeLists.txt +++ b/PWGCF/Femto/TableProducer/CMakeLists.txt @@ -23,3 +23,8 @@ o2physics_add_dpl_workflow(femto-producer-kink-pt-converter SOURCES ./femtoProducerKinkPtConverter.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(femto-producer-resonances + SOURCES ./femtoProducerResonances.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGCF/Femto/TableProducer/femtoProducer.cxx b/PWGCF/Femto/TableProducer/femtoProducer.cxx index 4945edc358a..6d655cb02e2 100644 --- a/PWGCF/Femto/TableProducer/femtoProducer.cxx +++ b/PWGCF/Femto/TableProducer/femtoProducer.cxx @@ -10,7 +10,7 @@ // or submit itself to any jurisdiction. /// \file femtoProducer.cxx -/// \brief Tasks that produces all femto tables +/// \brief Tasks that produces most femto tables /// \author Anton Riedel, TU München, anton.riedel@tum.de #include "PWGCF/Femto/Core/cascadeBuilder.h" diff --git a/PWGCF/Femto/TableProducer/femtoProducerResonances.cxx b/PWGCF/Femto/TableProducer/femtoProducerResonances.cxx new file mode 100644 index 00000000000..1eaba0fa6bd --- /dev/null +++ b/PWGCF/Femto/TableProducer/femtoProducerResonances.cxx @@ -0,0 +1,110 @@ +// Copyright 2019-2025 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 femtoProducerResonances.cxx +/// \brief Tasks that produces femto tables for all resonances +/// \author Anton Riedel, TU München, anton.riedel@tum.de + +#include "PWGCF/Femto/Core/collisionBuilder.h" +#include "PWGCF/Femto/Core/collisionHistManager.h" +#include "PWGCF/Femto/Core/modes.h" +#include "PWGCF/Femto/Core/partitions.h" +#include "PWGCF/Femto/Core/trackBuilder.h" +#include "PWGCF/Femto/Core/twoTrackResonanceBuilder.h" +#include "PWGCF/Femto/DataModel/FemtoTables.h" + +#include +#include +#include +#include +#include +#include + +using namespace o2::analysis::femto; + +struct FemtoProducerResonances { + + using FemtoCollisions = o2::soa::Join; + using FilteredFemtoCollisions = o2::soa::Filtered; + using FilteredFemtoCollision = FilteredFemtoCollisions::iterator; + + using FemtoTracks = o2::soa::Join; + + o2::framework::SliceCache cache; + + // setup collisions + collisionbuilder::ConfCollisionSelection collisionSelection; + o2::framework::expressions::Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); + colhistmanager::ConfCollisionBinning confCollisionBinning; + + // setup for resonance daughter tracks + trackbuilder::ConfPionPlusSelection confPionPlusSelection; + o2::framework::Partition pionPlusPartition = MAKE_TRACK_PARTITION(confPionPlusSelection); + + trackbuilder::ConfPionMinusSelection confPionMinusSelection; + o2::framework::Partition pionMinusPartition = MAKE_TRACK_PARTITION(confPionMinusSelection); + + trackbuilder::ConfKaonPlusSelection confKaonPlusSelection; + o2::framework::Partition kaonPlusPartition = MAKE_TRACK_PARTITION(confKaonPlusSelection); + + trackbuilder::ConfKaonMinusSelection confKaonMinusSelection; + o2::framework::Partition kaonMinusPartition = MAKE_TRACK_PARTITION(confKaonMinusSelection); + + o2::framework::Preslice perColtracks = o2::aod::femtobase::stored::fColId; + + // resonance filters + twotrackresonancebuilder::ConfRhoFilters confRhoFilter; + twotrackresonancebuilder::ConfPhiFilters confPhiFilter; + twotrackresonancebuilder::ConfKstarFilters confKstarFilter; + + // resonance builders + twotrackresonancebuilder::ConfTwoTrackResonanceTables confTwoTrackResonanceTables; + twotrackresonancebuilder::TwoTrackResonanceBuilderProducts twoTrackResonanceBuilderProducts; + twotrackresonancebuilder::TwoTrackResonanceBuilder rho0Builder; + twotrackresonancebuilder::TwoTrackResonanceBuilder phiBuilder; + twotrackresonancebuilder::TwoTrackResonanceBuilder kstar0Builder; + twotrackresonancebuilder::TwoTrackResonanceBuilder kstar0BarBuilder; + + void init(o2::framework::InitContext& context) + { + // init builders + rho0Builder.init(confRhoFilter, confPionPlusSelection, confPionMinusSelection, confTwoTrackResonanceTables, context); + phiBuilder.init(confPhiFilter, confKaonPlusSelection, confKaonMinusSelection, confTwoTrackResonanceTables, context); + kstar0Builder.init(confKstarFilter, confKaonPlusSelection, confPionMinusSelection, confTwoTrackResonanceTables, context); + kstar0BarBuilder.init(confKstarFilter, confPionPlusSelection, confKaonMinusSelection, confTwoTrackResonanceTables, context); + } + + // proccess functions + void processRho0(FilteredFemtoCollision const& col, FemtoTracks const& tracks) + { + rho0Builder.fillResonances(col, twoTrackResonanceBuilderProducts, pionPlusPartition, pionMinusPartition, tracks, cache); + } + PROCESS_SWITCH(FemtoProducerResonances, processRho0, "Build Rho0 candidates", true); + + void processPhi(FilteredFemtoCollision const& col, FemtoTracks const& tracks) + { + phiBuilder.fillResonances(col, twoTrackResonanceBuilderProducts, kaonPlusPartition, kaonMinusPartition, tracks, cache); + } + PROCESS_SWITCH(FemtoProducerResonances, processPhi, "Build Phi candidates", true); + + void processKstar0(FilteredFemtoCollision const& col, FemtoTracks const& tracks) + { + kstar0Builder.fillResonances(col, twoTrackResonanceBuilderProducts, kaonPlusPartition, pionMinusPartition, tracks, cache); + kstar0BarBuilder.fillResonances(col, twoTrackResonanceBuilderProducts, pionPlusPartition, kaonMinusPartition, tracks, cache); + } + PROCESS_SWITCH(FemtoProducerResonances, processKstar0, "Build Kstar0/Kstar0bar candidates", true); +}; + +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +{ + o2::framework::WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; + return workflow; +} diff --git a/PWGCF/Femto/Tasks/femtoKinkQa.cxx b/PWGCF/Femto/Tasks/femtoKinkQa.cxx index 89a53dbf72e..08e04a72d86 100644 --- a/PWGCF/Femto/Tasks/femtoKinkQa.cxx +++ b/PWGCF/Femto/Tasks/femtoKinkQa.cxx @@ -23,7 +23,6 @@ #include "PWGCF/Femto/Core/partitions.h" #include "PWGCF/Femto/Core/trackHistManager.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "PWGLF/DataModel/LFKinkDecayTables.h" #include #include