diff --git a/PWGCF/Femto/Core/femtoUtils.h b/PWGCF/Femto/Core/femtoUtils.h index 16c8be6bd6c..28c380adb27 100644 --- a/PWGCF/Femto/Core/femtoUtils.h +++ b/PWGCF/Femto/Core/femtoUtils.h @@ -153,6 +153,9 @@ inline float getMass(int pdgCode) case kSigmaMinus: mass = o2::constants::physics::MassSigmaMinus; break; + case kSigmaPlus: + mass = o2::constants::physics::MassSigmaPlus; + break; case kXiMinus: mass = o2::constants::physics::MassXiMinus; break; diff --git a/PWGCF/Femto/Core/kinkBuilder.h b/PWGCF/Femto/Core/kinkBuilder.h index c17d94ec89e..0a70c40b4c3 100644 --- a/PWGCF/Femto/Core/kinkBuilder.h +++ b/PWGCF/Femto/Core/kinkBuilder.h @@ -58,6 +58,8 @@ struct ConfKinkFilters : o2::framework::ConfigurableGroup { o2::framework::Configurable phiMax{"phiMax", 1.f * o2::constants::math::TwoPI, "Maximum phi"}; o2::framework::Configurable massMinSigma{"massMinSigma", 1.1f, "Minimum mass for Sigma hypothesis"}; o2::framework::Configurable massMaxSigma{"massMaxSigma", 1.3f, "Maximum mass for Sigma hypothesis"}; + o2::framework::Configurable massMinSigmaPlus{"massMinSigmaPlus", 1.1f, "Minimum mass for SigmaPlus hypothesis"}; + o2::framework::Configurable massMaxSigmaPlus{"massMaxSigmaPlus", 1.3f, "Maximum mass for SigmaPlus hypothesis"}; }; // selections bits for all kinks @@ -68,6 +70,7 @@ struct ConfKinkFilters : o2::framework::ConfigurableGroup { o2::framework::Configurable> dauAbsEtaMax{"dauAbsEtaMax", {0.8f}, "Maximum absolute pseudorapidity for daughter track"}; \ o2::framework::Configurable> dauDcaPvMin{"dauDcaPvMin", {0.0f}, "Minimum DCA of daughter from primary vertex (cm)"}; \ o2::framework::Configurable> mothDcaPvMax{"mothDcaPvMax", {1.0f}, "Maximum DCA of mother from primary vertex (cm)"}; \ + o2::framework::Configurable> alphaAPMin{"alphaAPMin", {-1.0f}, "Minimum Alpha_AP for Sigma candidates"}; \ o2::framework::Configurable> alphaAPMax{"alphaAPMax", {0.0f}, "Maximum Alpha_AP for Sigma candidates"}; \ o2::framework::Configurable> qtAPMin{"qtAPMin", {0.15f}, "Minimum qT_AP for Sigma candidates"}; \ o2::framework::Configurable> qtAPMax{"qtAPMax", {0.2f}, "Maximum qT_AP for Sigma candidates"}; \ @@ -80,6 +83,15 @@ struct ConfSigmaBits : o2::framework::ConfigurableGroup { o2::framework::Configurable> chaDauTpcPion{"chaDauTpcPion", {5.f}, "Maximum |nsigma_Pion| TPC for charged daughter tracks"}; }; +// derived selection bits for sigma plus +struct ConfSigmaPlusBits : o2::framework::ConfigurableGroup { + std::string prefix = std::string("SigmaPlusBits"); + KINK_DEFAULT_BITS + o2::framework::Configurable> chaDauTpcProton{"chaDauTpcProton", {5.f}, "Maximum |nsigma_Proton| TPC for charged daughter tracks"}; + o2::framework::Configurable> chaDauTpctofProton{"chaDauTpctofProton", {5.f}, "Maximum combined |nsigma_Proton| (TPC+TOF) for charged daughter tracks"}; + o2::framework::Configurable pidThres{"pidThres", 0.75f, "Momentum threshold for using TOF/combined pid for daughter tracks (GeV/c)"}; +}; + #undef KINK_DEFAULT_BITS // base selection for analysis task for kinks @@ -100,13 +112,27 @@ template struct ConfSigmaSelection : o2::framework::ConfigurableGroup { std::string prefix = Prefix; KINK_DEFAULT_SELECTIONS(1.1, 1.3, 3112) - o2::framework::Configurable sign{"sign", 1, "Sign of the Sigma mother track (e.g. -1 for Sigma- or +1 for AntiSigma-)"}; + o2::framework::Configurable sign{"sign", -1, "Sign of the Sigma mother track (e.g. -1 for Sigma- or +1 for AntiSigma-)"}; +}; + +// base selection for analysis task for sigma plus +template +struct ConfSigmaPlusSelection : o2::framework::ConfigurableGroup { + std::string prefix = Prefix; + KINK_DEFAULT_SELECTIONS(1.1, 1.3, 3222) + o2::framework::Configurable sign{"sign", 1, "Sign of the Sigma mother track (e.g. +1 for Sigma+ or -1 for AntiSigma+)"}; }; #undef KINK_DEFAULT_SELECTIONS constexpr const char PrefixSigmaSelection1[] = "SigmaSelection1"; +constexpr const char PrefixSigmaSelection2[] = "SigmaSelection2"; using ConfSigmaSelection1 = ConfSigmaSelection; +using ConfSigmaSelection2 = ConfSigmaSelection; +constexpr const char PrefixSigmaPlusSelection1[] = "SigmaPlusSelection1"; +constexpr const char PrefixSigmaPlusSelection2[] = "SigmaPlusSelection2"; +using ConfSigmaPlusSelection1 = ConfSigmaPlusSelection; +using ConfSigmaPlusSelection2 = ConfSigmaPlusSelection; /// The different selections for kinks enum KinkSeles { @@ -119,7 +145,10 @@ enum KinkSeles { kMothDcaPvMax, kChaDaughTpcPion, + kChaDaughTpcProton, + kChaDaughTpctofProton, + kAlphaAPMin, kAlphaAPMax, kQtAPMin, kQtAPMax, @@ -137,6 +166,9 @@ const std::unordered_map kinkSelsToStrings = { {kDauDcaPvMin, "dauDcaPvMin"}, {kMothDcaPvMax, "mothDcaPvMax"}, {kChaDaughTpcPion, "chaDauTpcPion"}, + {kChaDaughTpcProton, "chaDauTpcProton"}, + {kChaDaughTpctofProton, "chaDauTpctofProton"}, + {kAlphaAPMin, "alphaAPMin"}, {kAlphaAPMax, "alphaAPMax"}, {kQtAPMin, "qtAPMin"}, {kQtAPMax, "qtAPMax"}, @@ -148,8 +180,8 @@ template class KinkSelection : public BaseSelection { public: - KinkSelection() = default; - ~KinkSelection() = default; + KinkSelection() {} + virtual ~KinkSelection() = default; template void configure(T1& config, T2& filter) @@ -168,12 +200,21 @@ class KinkSelection : public BaseSelectionaddSelection(config.chaDauTpcPion.value, kChaDaughTpcPion, limits::kAbsUpperLimit, true, true); } + if constexpr (modes::isEqual(kinkType, modes::Kink::kSigmaPlus)) { + mMassSigmaPlusLowerLimit = filter.massMinSigmaPlus.value; + mMassSigmaPlusUpperLimit = filter.massMaxSigmaPlus.value; + mPidThreshold = config.pidThres.value; + this->addSelection(config.chaDauTpcProton.value, kChaDaughTpcProton, limits::kAbsUpperLimit, true, true); + this->addSelection(config.chaDauTpctofProton.value, kChaDaughTpctofProton, limits::kUpperLimit, true, true); + } + this->addSelection(config.kinkTopoDcaMax.value, kKinkTopoDcaMax, limits::kUpperLimit, true, true); this->addSelection(config.transRadMin.value, kTransRadMin, limits::kLowerLimit, true, true); this->addSelection(config.transRadMax.value, kTransRadMax, limits::kUpperLimit, true, true); this->addSelection(config.dauAbsEtaMax.value, kDauAbsEtaMax, limits::kAbsUpperLimit, true, true); this->addSelection(config.dauDcaPvMin.value, kDauDcaPvMin, limits::kLowerLimit, true, true); this->addSelection(config.mothDcaPvMax.value, kMothDcaPvMax, limits::kUpperLimit, true, true); + this->addSelection(config.alphaAPMin.value, kAlphaAPMin, limits::kLowerLimit, true, true); this->addSelection(config.alphaAPMax.value, kAlphaAPMax, limits::kUpperLimit, true, true); this->addSelection(config.qtAPMin.value, kQtAPMin, limits::kLowerLimit, true, true); this->addSelection(config.qtAPMax.value, kQtAPMax, limits::kUpperLimit, true, true); @@ -193,6 +234,7 @@ class KinkSelection : public BaseSelectionevaluateObservable(kAlphaAPMin, alphaAP); this->evaluateObservable(kAlphaAPMax, alphaAP); // qT_AP @@ -228,7 +270,19 @@ class KinkSelection : public BaseSelectionevaluateObservable(kMothDcaPvMax, std::abs(kinkCand.dcaMothPv())); auto chaDaughter = kinkCand.template trackDaug_as(); - this->evaluateObservable(kChaDaughTpcPion, chaDaughter.tpcNSigmaPi()); + + if constexpr (modes::isEqual(kinkType, modes::Kink::kSigma)) { + this->evaluateObservable(kChaDaughTpcPion, chaDaughter.tpcNSigmaPi()); + } + if constexpr (modes::isEqual(kinkType, modes::Kink::kSigmaPlus)) { + if (pDaug < mPidThreshold) { + this->evaluateObservable(kChaDaughTpcProton, chaDaughter.tpcNSigmaPr()); + } else { + if (chaDaughter.hasTOF()) { + this->evaluateObservable(kChaDaughTpctofProton, std::hypot(chaDaughter.tpcNSigmaPr(), chaDaughter.tofNSigmaPr())); + } + } + } this->assembleBitmask(); }; @@ -236,11 +290,11 @@ class KinkSelection : public BaseSelection bool checkFilters(const T& kink) const { + float pt = kink.ptMoth(); // Compute mother eta and phi float px = kink.pxMoth(); float py = kink.pyMoth(); float pz = kink.pzMoth(); - float pt = std::hypot(px, py); float p = std::sqrt(px * px + py * py + pz * pz); float eta = (p > 0.f) ? 0.5f * std::log((p + pz) / (p - pz)) : 0.f; float phi = RecoDecay::constrainAngle(std::atan2(py, px)); @@ -254,29 +308,23 @@ class KinkSelection : public BaseSelection mMassSigmaLowerLimit && sigmaMass < mMassSigmaUpperLimit); } + + if constexpr (modes::isEqual(kinkType, modes::Kink::kSigmaPlus)) { + float sigmaMass = kinkCand.mSigmaPlus(); + return (sigmaMass > mMassSigmaPlusLowerLimit && sigmaMass < mMassSigmaPlusUpperLimit); + } return false; } - protected: + public: float mMassSigmaLowerLimit = 1.15f; float mMassSigmaUpperLimit = 1.25f; + float mMassSigmaPlusLowerLimit = 1.15f; + float mMassSigmaPlusUpperLimit = 1.25f; + float mPidThreshold = 0.75f; // kinematic filters float mPtMin = 0.f; @@ -291,6 +339,9 @@ struct KinkBuilderProducts : o2::framework::ProducesGroup { o2::framework::Produces producedSigmas; o2::framework::Produces producedSigmaMasks; o2::framework::Produces producedSigmaExtras; + o2::framework::Produces producedSigmaPlus; + o2::framework::Produces producedSigmaPlusMasks; + o2::framework::Produces producedSigmaPlusExtras; }; struct ConfKinkTables : o2::framework::ConfigurableGroup { @@ -298,14 +349,17 @@ struct ConfKinkTables : o2::framework::ConfigurableGroup { o2::framework::Configurable produceSigmas{"produceSigmas", -1, "Produce Sigmas (-1: auto; 0 off; 1 on)"}; o2::framework::Configurable produceSigmaMasks{"produceSigmaMasks", -1, "Produce SigmaMasks (-1: auto; 0 off; 1 on)"}; o2::framework::Configurable produceSigmaExtras{"produceSigmaExtras", -1, "Produce SigmaExtras (-1: auto; 0 off; 1 on)"}; + o2::framework::Configurable produceSigmaPlus{"produceSigmaPlus", -1, "Produce SigmaPlus (-1: auto; 0 off; 1 on)"}; + o2::framework::Configurable produceSigmaPlusMasks{"produceSigmaPlusMasks", -1, "Produce SigmaPlusMasks (-1: auto; 0 off; 1 on)"}; + o2::framework::Configurable produceSigmaPlusExtras{"produceSigmaPlusExtras", -1, "Produce SigmaPlusExtras (-1: auto; 0 off; 1 on)"}; }; template class KinkBuilder { public: - KinkBuilder() = default; - ~KinkBuilder() = default; + KinkBuilder() {} + virtual ~KinkBuilder() = default; template void init(T1& config, T2& filter, T3& table, T4& initContext) @@ -318,30 +372,60 @@ class KinkBuilder mProduceSigmaExtras = utils::enableTable("FSigmaExtras_001", table.produceSigmaExtras.value, initContext); } - if (mProduceSigmas || mProduceSigmaMasks || mProduceSigmaExtras) { + if constexpr (modes::isEqual(kinkType, modes::Kink::kSigmaPlus)) { + LOG(info) << "Initialize femto SigmaPlus builder..."; + mProduceSigmaPlus = utils::enableTable("FSigmaPlus_001", table.produceSigmaPlus.value, initContext); + mProduceSigmaPlusMasks = utils::enableTable("FSigmaPlusMasks_001", table.produceSigmaPlusMasks.value, initContext); + mProduceSigmaPlusExtras = utils::enableTable("FSigmaPlusExtras_001", table.produceSigmaPlusExtras.value, initContext); + } + + if (mProduceSigmas || mProduceSigmaMasks || mProduceSigmaExtras || mProduceSigmaPlus || mProduceSigmaPlusMasks || mProduceSigmaPlusExtras) { mFillAnyTable = true; mKinkSelection.printSelections(kinkSelsName, kinkSelsToStrings); + if constexpr (modes::isEqual(kinkType, modes::Kink::kSigma)) { + LOG(info) << "Sigma tables enabled: Sigmas=" << mProduceSigmas << " Masks=" << mProduceSigmaMasks << " Extras=" << mProduceSigmaExtras; + } + if constexpr (modes::isEqual(kinkType, modes::Kink::kSigmaPlus)) { + LOG(info) << "SigmaPlus tables enabled: SigmaPlus=" << mProduceSigmaPlus << " Masks=" << mProduceSigmaPlusMasks << " Extras=" << mProduceSigmaPlusExtras; + } + } else { + LOG(info) << "No tables configured"; } + LOG(info) << "Initialization done..."; } template void fillKinks(T1& collisionProducts, T2& trackProducts, T3& kinkProducts, T4 const& kinks, T5 const& tracks, T6& trackBuilder, T7& indexMap) { if (!mFillAnyTable) { + LOG(info) << "KinkBuilder: No tables configured to be filled"; return; } int64_t daughterIndex = 0; + for (const auto& kink : kinks) { if (!mKinkSelection.checkFilters(kink)) { continue; } + + if (!mKinkSelection.checkHypothesis(kink)) { + continue; + } + + // Apply selections mKinkSelection.applySelections(kink, tracks); - if (mKinkSelection.passesAllRequiredSelections() && mKinkSelection.checkHypothesis(kink)) { - auto daughter = kink.template trackDaug_as(); - daughterIndex = trackBuilder.template getDaughterIndex(daughter, trackProducts, collisionProducts, indexMap); - if constexpr (modes::isEqual(kinkType, modes::Kink::kSigma)) { - fillSigma(collisionProducts, kinkProducts, kink, daughterIndex); - } + + if (!mKinkSelection.passesAllRequiredSelections()) { + continue; + } + + auto daughter = kink.template trackDaug_as(); + daughterIndex = trackBuilder.template getDaughterIndex(daughter, trackProducts, collisionProducts, indexMap); + if constexpr (modes::isEqual(kinkType, modes::Kink::kSigma)) { + fillSigma(collisionProducts, kinkProducts, kink, daughterIndex); + } + if constexpr (modes::isEqual(kinkType, modes::Kink::kSigmaPlus)) { + fillSigmaPlus(collisionProducts, kinkProducts, kink, daughterIndex); } } } @@ -349,27 +433,14 @@ class KinkBuilder template void fillSigma(T1& collisionProducts, T2& kinkProducts, T3 const& kink, int daughterIndex) { - // Compute mass - float pxmoth = kink.pxMoth(); - float pymoth = kink.pyMoth(); - float pzmoth = kink.pzMoth(); - float pxch = kink.pxDaug(); - float pych = kink.pyDaug(); - float pzch = kink.pzDaug(); - float pxneut = pxmoth - pxch; - float pyneut = pymoth - pych; - float pzneut = pzmoth - pzch; - - float mass = RecoDecay::m( - std::array{std::array{pxch, pych, pzch}, std::array{pxneut, pyneut, pzneut}}, - std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassNeutron}); + float mass = kink.mSigmaMinus(); if (mProduceSigmas) { + float pt = kink.ptMoth(); // Compute mother eta and phi float px = kink.pxMoth(); float py = kink.pyMoth(); float pz = kink.pzMoth(); - float pt = std::hypot(px, py); float p = std::sqrt(px * px + py * py + pz * pz); float eta = (p > 0.f) ? 0.5f * std::log((p + pz) / (p - pz)) : 0.f; float phi = RecoDecay::constrainAngle(std::atan2(py, px)); @@ -385,7 +456,14 @@ class KinkBuilder kinkProducts.producedSigmaMasks(mKinkSelection.getBitmask()); } if (mProduceSigmaExtras) { - // Compute kink angle and transRadius + // Compute kink angle using momentum components + float pxmoth = kink.pxMoth(); + float pymoth = kink.pyMoth(); + float pzmoth = kink.pzMoth(); + float pxch = kink.pxDaug(); + float pych = kink.pyDaug(); + float pzch = kink.pzDaug(); + float pMoth = std::sqrt(pxmoth * pxmoth + pymoth * pymoth + pzmoth * pzmoth); float pDaug = std::sqrt(pxch * pxch + pych * pych + pzch * pzch); float kinkAngle = 0.f; @@ -408,6 +486,64 @@ class KinkBuilder transRadius); } } + + template + void fillSigmaPlus(T1& collisionProducts, T2& kinkProducts, T3 const& kink, int daughterIndex) + { + float mass = kink.mSigmaPlus(); + + if (mProduceSigmaPlus) { + float pt = kink.ptMoth(); + // Compute mother eta and phi + float px = kink.pxMoth(); + float py = kink.pyMoth(); + float pz = kink.pzMoth(); + float p = std::sqrt(px * px + py * py + pz * pz); + float eta = (p > 0.f) ? 0.5f * std::log((p + pz) / (p - pz)) : 0.f; + float phi = RecoDecay::constrainAngle(std::atan2(py, px)); + + kinkProducts.producedSigmaPlus(collisionProducts.producedCollision.lastIndex(), + kink.mothSign() * pt, + eta, + phi, + mass, + daughterIndex); + } + if (mProduceSigmaPlusMasks) { + kinkProducts.producedSigmaPlusMasks(mKinkSelection.getBitmask()); + } + if (mProduceSigmaPlusExtras) { + // Compute kink angle using momentum components + float pxmoth = kink.pxMoth(); + float pymoth = kink.pyMoth(); + float pzmoth = kink.pzMoth(); + float pxch = kink.pxDaug(); + float pych = kink.pyDaug(); + float pzch = kink.pzDaug(); + + float pMoth = std::sqrt(pxmoth * pxmoth + pymoth * pymoth + pzmoth * pzmoth); + float pDaug = std::sqrt(pxch * pxch + pych * pych + pzch * pzch); + float kinkAngle = 0.f; + if (pMoth > 0.f && pDaug > 0.f) { + float dotProduct = pxmoth * pxch + pymoth * pych + pzmoth * pzch; + float cosAngle = dotProduct / (pMoth * pDaug); + cosAngle = std::max(-1.0f, std::min(1.0f, cosAngle)); // Clamp + kinkAngle = std::acos(cosAngle); + } + + float transRadius = std::hypot(kink.xDecVtx(), kink.yDecVtx()); + + kinkProducts.producedSigmaPlusExtras( + kinkAngle, + kink.dcaDaugPv(), + kink.dcaMothPv(), + kink.xDecVtx(), + kink.yDecVtx(), + kink.zDecVtx(), + transRadius); + } + } + bool fillAnyTable() { return mFillAnyTable; } private: @@ -416,7 +552,11 @@ class KinkBuilder bool mProduceSigmas = false; bool mProduceSigmaMasks = false; bool mProduceSigmaExtras = false; + bool mProduceSigmaPlus = false; + bool mProduceSigmaPlusMasks = false; + bool mProduceSigmaPlusExtras = false; }; + } // namespace kinkbuilder } // namespace o2::analysis::femto #endif // PWGCF_FEMTO_CORE_KINKBUILDER_H_ diff --git a/PWGCF/Femto/Core/kinkHistManager.h b/PWGCF/Femto/Core/kinkHistManager.h index 78b92b3b0d9..d52d5cb08ec 100644 --- a/PWGCF/Femto/Core/kinkHistManager.h +++ b/PWGCF/Femto/Core/kinkHistManager.h @@ -74,11 +74,19 @@ struct ConfSigmaBinning : o2::framework::ConfigurableGroup { std::string prefix = Prefix; KINK_DEFAULT_BINNING(1.1, 1.3) }; +template +struct ConfSigmaPlusBinning : o2::framework::ConfigurableGroup { + std::string prefix = Prefix; + KINK_DEFAULT_BINNING(1.1, 1.3) +}; #undef KINK_DEFAULT_BINNING constexpr const char PrefixSigmaBinning1[] = "SigmaBinning1"; using ConfSigmaBinning1 = ConfSigmaBinning; +constexpr const char PrefixSigmaPlusBinning1[] = "SigmaPlusBinning1"; +using ConfSigmaPlusBinning1 = ConfSigmaPlusBinning; + template struct ConfKinkQaBinning : o2::framework::ConfigurableGroup { std::string prefix = Prefix; @@ -93,6 +101,9 @@ struct ConfKinkQaBinning : o2::framework::ConfigurableGroup { constexpr const char PrefixSigmaQaBinning1[] = "SigmaQaBinning1"; using ConfSigmaQaBinning1 = ConfKinkQaBinning; +constexpr const char PrefixSigmaPlusQaBinning1[] = "SigmaPlusQaBinning1"; +using ConfSigmaPlusQaBinning1 = ConfKinkQaBinning; + // must be in sync with enum KinkHist // the enum gives the correct index in the array constexpr std::array, kKinkHistLast> HistTable = { @@ -153,6 +164,9 @@ std::map> makeKinkQaHistSpecMap(T1 co constexpr char PrefixSigmaQa[] = "SigmaQA/"; constexpr char PrefixSigma1[] = "Sigma1/"; constexpr char PrefixSigma2[] = "Sigma2/"; +constexpr char PrefixSigmaPlusQa[] = "SigmaPlusQA/"; +constexpr char PrefixSigmaPlus1[] = "SigmaPlus1/"; +constexpr char PrefixSigmaPlus2[] = "SigmaPlus2/"; constexpr std::string_view AnalysisDir = "Kinematics/"; constexpr std::string_view QaDir = "QA/"; @@ -259,7 +273,7 @@ class KinkHistManager mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(AnalysisDir) + HIST(getHistName(kPhi, HistTable)), kinkcandidate.phi()); mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(AnalysisDir) + HIST(getHistName(kMass, HistTable)), kinkcandidate.mass()); - if constexpr (isEqual(kink, modes::Kink::kSigma)) { + if constexpr (isEqual(kink, modes::Kink::kSigma) || isEqual(kink, modes::Kink::kSigmaPlus)) { mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(AnalysisDir) + HIST(getHistName(kSign, HistTable)), kinkcandidate.sign()); } } diff --git a/PWGCF/Femto/Core/modes.h b/PWGCF/Femto/Core/modes.h index 6fe0f9a71b3..e4104c7f343 100644 --- a/PWGCF/Femto/Core/modes.h +++ b/PWGCF/Femto/Core/modes.h @@ -113,7 +113,8 @@ enum class V0 : o2::aod::femtodatatypes::V0Type { }; enum class Kink : o2::aod::femtodatatypes::KinkType { - kSigma + kSigma, + kSigmaPlus }; enum class Cascade : o2::aod::femtodatatypes::CascadeType { diff --git a/PWGCF/Femto/Core/partitions.h b/PWGCF/Femto/Core/partitions.h index 6d5cf0dac81..d399729d66b 100644 --- a/PWGCF/Femto/Core/partitions.h +++ b/PWGCF/Femto/Core/partitions.h @@ -126,4 +126,17 @@ (femtobase::stored::mass < selection.massMax) && \ ncheckbit(femtokinks::mask, selection.mask) +#define MAKE_SIGMAPLUS_PARTITION(selection) \ + ifnode(selection.sign.node() != 0, \ + ifnode(selection.sign.node() > 0, femtobase::stored::signedPt > 0.f, femtobase::stored::signedPt < 0.f), true) && \ + (nabs(femtobase::stored::signedPt) > selection.ptMin) && \ + (nabs(femtobase::stored::signedPt) < selection.ptMax) && \ + (femtobase::stored::eta > selection.etaMin) && \ + (femtobase::stored::eta < selection.etaMax) && \ + (femtobase::stored::phi > selection.phiMin) && \ + (femtobase::stored::phi < selection.phiMax) && \ + (femtobase::stored::mass > selection.massMin) && \ + (femtobase::stored::mass < selection.massMax) && \ + ncheckbit(femtokinks::mask, selection.mask) + #endif // PWGCF_FEMTO_CORE_PARTITIONS_H_ diff --git a/PWGCF/Femto/DataModel/FemtoTables.h b/PWGCF/Femto/DataModel/FemtoTables.h index f17d7c3d1ae..968a60b4b19 100644 --- a/PWGCF/Femto/DataModel/FemtoTables.h +++ b/PWGCF/Femto/DataModel/FemtoTables.h @@ -513,7 +513,7 @@ DECLARE_SOA_COLUMN(TransRadius, transRadius, float); //! Transverse decay radius DECLARE_SOA_INDEX_COLUMN_FULL(ChaDau, chaDau, int32_t, FTracks, "_ChaDau"); //! } // namespace femtokinks -// table for basic sigma minus information +// table for basic sigma information DECLARE_SOA_TABLE_STAGED_VERSIONED(FSigmas_001, "FSIGMA", 1, o2::soa::Index<>, femtobase::stored::FColId, // use sign to differentiate between sigma minus (-1) and anti sigma minus (+1) @@ -546,6 +546,39 @@ DECLARE_SOA_TABLE_STAGED_VERSIONED(FSigmaExtras_001, "FSIGMAEXTRAS", 1, using FSigmaExtras = FSigmaExtras_001; +// table for basic sigma plus information +DECLARE_SOA_TABLE_STAGED_VERSIONED(FSigmaPlus_001, "FSIGMAPLUS", 1, + o2::soa::Index<>, + femtobase::stored::FColId, // use sign to differentiate between sigma minus (-1) and anti sigma minus (+1) + femtobase::stored::SignedPt, + femtobase::stored::Eta, + femtobase::stored::Phi, + femtobase::stored::Mass, + femtokinks::ChaDauId, + femtobase::dynamic::Sign, + femtobase::dynamic::Pt, + femtobase::dynamic::P, + femtobase::dynamic::Px, + femtobase::dynamic::Py, + femtobase::dynamic::Pz, + femtobase::dynamic::Theta); +using FSigmaPlus = FSigmaPlus_001; + +DECLARE_SOA_TABLE_STAGED_VERSIONED(FSigmaPlusMasks_001, "FSIGMAPLUSMASKS", 1, + femtokinks::Mask); +using FSigmaPlusMasks = FSigmaPlusMasks_001; + +DECLARE_SOA_TABLE_STAGED_VERSIONED(FSigmaPlusExtras_001, "FSIGMAPLUSEXTRAS", 1, + femtokinks::KinkAngle, + femtokinks::DcaDaugToPV, + femtokinks::DcaMothToPV, + femtokinks::DecayVtxX, + femtokinks::DecayVtxY, + femtokinks::DecayVtxZ, + femtokinks::TransRadius); + +using FSigmaPlusExtras = FSigmaPlusExtras_001; + namespace femtocascades { // columns for cascade bit masks diff --git a/PWGCF/Femto/TableProducer/femtoProducer.cxx b/PWGCF/Femto/TableProducer/femtoProducer.cxx index 561963ce797..b6e0b021b4e 100644 --- a/PWGCF/Femto/TableProducer/femtoProducer.cxx +++ b/PWGCF/Femto/TableProducer/femtoProducer.cxx @@ -121,6 +121,8 @@ struct FemtoProducer { kinkbuilder::ConfKinkFilters confKinkFilters; kinkbuilder::ConfSigmaBits confSigmaBits; kinkbuilder::KinkBuilder sigmaBuilder; + kinkbuilder::ConfSigmaPlusBits confSigmaPlusBits; + kinkbuilder::KinkBuilder sigmaPlusBuilder; // resonance daughter filters and partitions twotrackresonancebuilder::ConfTwoTrackResonanceDaughterFilters confResonanceDaughterFilters; @@ -182,6 +184,7 @@ struct FemtoProducer { // configure kink builder sigmaBuilder.init(confSigmaBits, confKinkFilters, confKinkTables, context); + sigmaPlusBuilder.init(confSigmaPlusBits, confKinkFilters, confKinkTables, context); // cascade selections xiBuilder.init(confXiBits, confCascadeFilters, confCascadeTables, context); @@ -199,7 +202,7 @@ struct FemtoProducer { if ((lambdaBuilder.fillAnyTable() || antilambdaBuilder.fillAnyTable() || k0shortBuilder.fillAnyTable()) && (!doprocessTracksV0sCascadesRun3pp && !doprocessTracksV0sRun3pp && !doprocessTracksV0sCascadesKinksRun3pp)) { LOG(fatal) << "At least one v0 table is enabled, but wrong process function is enabled. Breaking..."; } - if (sigmaBuilder.fillAnyTable() && (!doprocessTracksKinksRun3pp && !doprocessTracksV0sCascadesKinksRun3pp)) { + if ((sigmaBuilder.fillAnyTable() || sigmaPlusBuilder.fillAnyTable()) && (!doprocessTracksKinksRun3pp && !doprocessTracksV0sCascadesKinksRun3pp)) { LOG(fatal) << "At least one kink table is enabled, but wrong process function is enabled. Breaking..."; } } @@ -248,6 +251,7 @@ struct FemtoProducer { void processKinks(T1 const& tracks, T2 const& kinks) { sigmaBuilder.fillKinks(collisionBuilderProducts, trackBuilderProducts, kinkBuilderProducts, kinks, tracks, trackBuilder, indexMapTracks); + sigmaPlusBuilder.fillKinks(collisionBuilderProducts, trackBuilderProducts, kinkBuilderProducts, kinks, tracks, trackBuilder, indexMapTracks); } // add cascades diff --git a/PWGCF/Femto/Tasks/femtoKinkQa.cxx b/PWGCF/Femto/Tasks/femtoKinkQa.cxx index 6f19b159984..e2fe8146b30 100644 --- a/PWGCF/Femto/Tasks/femtoKinkQa.cxx +++ b/PWGCF/Femto/Tasks/femtoKinkQa.cxx @@ -61,6 +61,7 @@ struct FemtoKinkQa { // Define kink/sigma tables (joining tables for comprehensive information) using FemtoSigmas = o2::soa::Join; + using FemtoSigmaPlus = o2::soa::Join; using FemtoTracks = o2::soa::Join; SliceCache cache; @@ -80,6 +81,21 @@ struct FemtoKinkQa { modes::Kink::kSigma> sigmaHistManager; + // setup for sigma plus + kinkbuilder::ConfSigmaPlusSelection1 confSigmaPlusSelection; + + Partition sigmaPlusPartition = MAKE_SIGMAPLUS_PARTITION(confSigmaPlusSelection); + Preslice perColSigmaPlus = femtobase::stored::fColId; + + kinkhistmanager::ConfSigmaPlusBinning1 confSigmaPlusBinning; + kinkhistmanager::ConfSigmaPlusQaBinning1 confSigmaPlusQaBinning; + kinkhistmanager::KinkHistManager< + kinkhistmanager::PrefixSigmaPlusQa, + trackhistmanager::PrefixKinkChaDaughterQa, + modes::Mode::kAnalysis_Qa, + modes::Kink::kSigmaPlus> + sigmaPlusHistManager; + // setup for daughters trackhistmanager::ConfKinkChaDauBinning confKinkChaDaughterBinning; trackhistmanager::ConfKinkChaDauQaBinning confKinkChaDaughterQaBinning; @@ -88,16 +104,27 @@ struct FemtoKinkQa { void init(InitContext&) { - auto sigmaHistSpec = kinkhistmanager::makeKinkQaHistSpecMap(confSigmaBinning, confSigmaQaBinning); + // create a map for histogram specs + auto colHistSpec = colhistmanager::makeColQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); + colHistManager.init(&hRegistry, colHistSpec, confCollisionQaBinning); + auto chaDauHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confKinkChaDaughterBinning, confKinkChaDaughterQaBinning); - sigmaHistManager.init(&hRegistry, sigmaHistSpec, confSigmaQaBinning, chaDauHistSpec, confKinkChaDaughterQaBinning); + if ((doprocessSigma + doprocessSigmaPlus > 1)) { + LOG(fatal) << "Only one process can be activated"; + } + + if (doprocessSigma) { + auto sigmaHistSpec = kinkhistmanager::makeKinkQaHistSpecMap(confSigmaBinning, confSigmaQaBinning); + sigmaHistManager.init(&hRegistry, sigmaHistSpec, confSigmaQaBinning, chaDauHistSpec, confKinkChaDaughterQaBinning); + } - auto collisionHistSpec = colhistmanager::makeColQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); - colHistManager.init(&hRegistry, collisionHistSpec, confCollisionQaBinning); + if (doprocessSigmaPlus) { + auto sigmaPlusHistSpec = kinkhistmanager::makeKinkQaHistSpecMap(confSigmaPlusBinning, confSigmaPlusQaBinning); + sigmaPlusHistManager.init(&hRegistry, sigmaPlusHistSpec, confSigmaPlusQaBinning, chaDauHistSpec, confKinkChaDaughterQaBinning); + } }; - // Process function for sigma particles from femto tables void processSigma(FilteredFemtoCollision const& col, FemtoSigmas const& /*sigmas*/, FemtoTracks const& tracks) { colHistManager.fill(col); @@ -107,6 +134,18 @@ struct FemtoKinkQa { } } PROCESS_SWITCH(FemtoKinkQa, processSigma, "Process sigmas", true); + + void processSigmaPlus(FilteredFemtoCollision const& col, FemtoSigmaPlus const& /*sigmaplus*/, FemtoTracks const& tracks) + { + colHistManager.fill(col); + + auto sigmaplusSlice = sigmaPlusPartition->sliceByCached(femtobase::stored::fColId, col.globalIndex(), cache); + + for (auto const& sp : sigmaplusSlice) { + sigmaPlusHistManager.fill(sp, tracks); + } + } + PROCESS_SWITCH(FemtoKinkQa, processSigmaPlus, "Process sigma plus", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx b/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx index c58364149a7..b09207a1e88 100644 --- a/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx +++ b/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx @@ -59,6 +59,7 @@ struct FemtoPairTrackKink { using Tracks = o2::soa::Join; using Sigmas = o2::soa::Join; + using SigmaPlus = o2::soa::Join; SliceCache cache; @@ -82,6 +83,12 @@ struct FemtoPairTrackKink { Partition sigmaPartition = MAKE_SIGMA_PARTITION(sigmaSelection); Preslice perColSigmas = aod::femtobase::stored::fColId; + // setup for sigma plus + kinkbuilder::ConfSigmaPlusSelection1 sigmaPlusSelection; + kinkhistmanager::ConfSigmaPlusBinning1 confSigmaPlusBinning; + Partition sigmaPlusPartition = MAKE_SIGMAPLUS_PARTITION(sigmaPlusSelection); + Preslice perColSigmaPlus = aod::femtobase::stored::fColId; + // setup pairs pairhistmanager::ConfPairBinning confPairBinning; pairhistmanager::ConfPairCuts confPairCuts; @@ -98,6 +105,18 @@ struct FemtoPairTrackKink { modes::Kink::kSigma> pairTrackSigmaBuilder; + pairbuilder::PairTrackKinkBuilder< + trackhistmanager::PrefixTrack1, + kinkhistmanager::PrefixSigmaPlus1, + trackhistmanager::PrefixKinkChaDaughter, + pairhistmanager::PrefixTrackKinkSe, + pairhistmanager::PrefixTrackKinkMe, + closepairrejection::PrefixTrackKinkSe, + closepairrejection::PrefixTrackKinkMe, + modes::Mode::kAnalysis, + modes::Kink::kSigmaPlus> + pairTrackSigmaPlusBuilder; + // setup mixing std::vector defaultVtxBins{10, -10, 10}; std::vector defaultMultBins{50, 0, 200}; @@ -129,10 +148,21 @@ struct FemtoPairTrackKink { auto cprHistSpec = closepairrejection::makeCprHistSpecMap(confCpr); // setup for sigma - // if (doprocessSigmaSameEvent || doprocessSigmaMixedEvent) { - if (doprocessSigmaSameEvent) { + if (doprocessSigmaSameEvent || doprocessSigmaMixedEvent) { auto sigmaHistSpec = kinkhistmanager::makeKinkHistSpecMap(confSigmaBinning); - pairTrackSigmaBuilder.init(&hRegistry, trackSelection, sigmaSelection, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaHistSpec, chaDauSpec, pairHistSpec, cprHistSpec); + auto pairTrackSigmaHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning); + pairTrackSigmaBuilder.init(&hRegistry, trackSelection, sigmaSelection, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaHistSpec, chaDauSpec, pairTrackSigmaHistSpec, cprHistSpec); + } + + // setup for sigma plus + if (doprocessSigmaPlusSameEvent || doprocessSigmaPlusMixedEvent) { + auto sigmaplusHistSpec = kinkhistmanager::makeKinkHistSpecMap(confSigmaPlusBinning); + auto pairTrackSigmaPlusHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning); + pairTrackSigmaPlusBuilder.init(&hRegistry, trackSelection, sigmaPlusSelection, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaplusHistSpec, chaDauSpec, pairTrackSigmaPlusHistSpec, cprHistSpec); + } + + if (((doprocessSigmaSameEvent || doprocessSigmaMixedEvent) + (doprocessSigmaPlusSameEvent || doprocessSigmaPlusMixedEvent)) > 1) { + LOG(fatal) << "Can only process sigma-tracks Or sigmaplus-tracks"; } }; @@ -147,6 +177,18 @@ struct FemtoPairTrackKink { pairTrackSigmaBuilder.processMixedEvent(cols, tracks, trackPartition, sigmaPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackKink, processSigmaMixedEvent, "Enable processing mixed event processing for tracks and sigmas", true); + // + void processSigmaPlusSameEvent(FilteredCollision const& col, Tracks const& tracks, SigmaPlus const& sigmaplus) + { + pairTrackSigmaPlusBuilder.processSameEvent(col, tracks, trackPartition, sigmaplus, sigmaPlusPartition, cache); + } + PROCESS_SWITCH(FemtoPairTrackKink, processSigmaPlusSameEvent, "Enable processing same event processing for tracks and sigma plus", false); + + void processSigmaPlusMixedEvent(FilteredCollisions const& cols, Tracks const& tracks, SigmaPlus const& /*sigmaplus*/) + { + pairTrackSigmaPlusBuilder.processMixedEvent(cols, tracks, trackPartition, sigmaPlusPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + } + PROCESS_SWITCH(FemtoPairTrackKink, processSigmaPlusMixedEvent, "Enable processing mixed event processing for tracks and sigma plus", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)