diff --git a/PWGCF/Femto/Core/femtoUtils.h b/PWGCF/Femto/Core/femtoUtils.h index 22dc4fa37e9..9b9c16c4884 100644 --- a/PWGCF/Femto/Core/femtoUtils.h +++ b/PWGCF/Femto/Core/femtoUtils.h @@ -16,8 +16,10 @@ #ifndef PWGCF_FEMTO_CORE_FEMTOUTILS_H_ #define PWGCF_FEMTO_CORE_FEMTOUTILS_H_ +#include "Common/Core/RecoDecay.h" #include "Common/Core/TableHelper.h" +#include #include #include #include @@ -173,6 +175,18 @@ concept HasEventShapeRow = requires(T row) { template concept HasEventShape = HasEventShapeRow> || (requires { typename std::decay_t::iterator; } && HasEventShapeRow::iterator>); +/// Azimuth of the momentum of a charged particle at the primary vertex, from its azimuth at the decay vertex. +/// The decay vertex (xDecay, yDecay) has to be given relative to the primary vertex. In a solenoidal field the transverse +/// trajectory is a circle through both points, and the tangents at the two ends of a chord make the same angle with it: +/// phiPV = 2*phiChord - phiDecay (independent of polarity). +inline float phiAtPrimaryVertex(float phiDecay, float xDecay, float yDecay) +{ + if (std::abs(xDecay) < o2::constants::math::Epsilon && std::abs(yDecay) < o2::constants::math::Epsilon) { + return phiDecay; + } + return RecoDecay::constrainAngle(2.f * std::atan2(yDecay, xDecay) - phiDecay); +} + /// Recalculate the pT of a kink mother from its direction and the charged daughter momentum inline float calcPtnew(float pxMother, float pyMother, float pzMother, float pxDaughter, float pyDaughter, float pzDaughter, float massMother, float massChargedDaughter, float massNeutralDaughter) diff --git a/PWGCF/Femto/Core/kinkBuilder.h b/PWGCF/Femto/Core/kinkBuilder.h index 34728fbdcec..84d518dbe15 100644 --- a/PWGCF/Femto/Core/kinkBuilder.h +++ b/PWGCF/Femto/Core/kinkBuilder.h @@ -53,6 +53,7 @@ struct ConfKinkFilters : o2::framework::ConfigurableGroup { o2::framework::Configurable etaMax{"etaMax", 10.f, "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 kinkPhiAtPv{"kinkPhiAtPv", true, "Kinks and PCM SigmaPlus: store the azimuth of the Sigma momentum at the primary vertex"}; 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"}; @@ -234,6 +235,7 @@ enum KinkFilters { kPhiMax, kMassMin, kMassMax, + kPhiAtPv, kMlScoreMin, kKinkFiltersMax }; @@ -250,6 +252,7 @@ const std::unordered_map kinkFilterNames = { {kPhiMax, "phiMax"}, {kMassMin, "massMin"}, {kMassMax, "massMax"}, + {kPhiAtPv, "kinkPhiAtPv"}, {kMlScoreMin, "mlScoreMin"}}; /// \class KinkCuts @@ -272,6 +275,7 @@ class KinkSelection : public baseselection::BaseSelection(mKinkPhiAtPv)}, }); } if constexpr (modes::isEqual(kinkType, modes::Kink::kSigmaPlus)) { @@ -331,6 +336,7 @@ class KinkSelection : public baseselection::BaseSelection(mKinkPhiAtPv)}, }); } }; @@ -421,6 +427,9 @@ class KinkSelection : public baseselection::BaseSelectiontemplate fillFilter(kPhiMax, p); pass &= p; + this->template fillFilter(kPhiAtPv, mKinkPhiAtPv); + if constexpr (modes::isEqual(kinkType, modes::Kink::kSigma)) { float sigmaMass = kinkCand.mSigmaMinus(); @@ -517,6 +528,7 @@ class KinkSelection : public baseselection::BaseSelection(mPhiAtPv)}, {kinkFilterNames.at(kMlScoreMin), mMlScoreMin}, }); }; - template - void computeKinematics(T const& sigmaPlusPcmCand) + template + void computeKinematics(T1 const& sigmaPlusPcmCand, T2 const& col) { std::array momMother = {sigmaPlusPcmCand.pxSigmaPlus(), sigmaPlusPcmCand.pySigmaPlus(), sigmaPlusPcmCand.pzSigmaPlus()}; mPt = RecoDecay::pt(momMother); mEta = RecoDecay::eta(momMother); mPhi = RecoDecay::phi(momMother); + if (mPhiAtPv) { + mPhi = utils::phiAtPrimaryVertex(mPhi, sigmaPlusPcmCand.xDecVtx() - col.posX(), sigmaPlusPcmCand.yDecVtx() - col.posY()); + } mMass = sigmaPlusPcmCand.massSigmaPlus(); mMlScore = sigmaPlusPcmCand.mlScore(); } @@ -897,6 +914,8 @@ class SigmaPlusPcmSelection : public baseselection::BaseSelectiontemplate fillFilter(kPhiMax, p); pass &= p; + this->template fillFilter(kPhiAtPv, mPhiAtPv); + p = mMass > mMassLowerLimit; this->template fillFilter(kMassMin, p); pass &= p; @@ -951,6 +970,7 @@ class SigmaPlusPcmSelection : public baseselection::BaseSelection(doprocessTracksV0sCascadesKinksRun3pp) + static_cast(doprocessTracksV0sCascadesKinksPhotonsRun3pp) + static_cast(doprocessTracksSigmaPlusPcmsRun3pp) + + static_cast(doprocessTracksKinksSigmaPlusPcmsRun3pp) + static_cast(doprocessTracksD0sRun3pp) + static_cast(doprocessTracksD0sRun3PbPb) + static_cast(doprocessTracksRun3ppMc) + @@ -390,6 +393,7 @@ struct FemtoProducer { static_cast(doprocessTracksKinksRun3ppMc) + static_cast(doprocessTracksV0sKinksRun3ppMc) + static_cast(doprocessTracksSigmaPlusPcmsRun3ppMc) + + static_cast(doprocessTracksKinksSigmaPlusPcmsRun3ppMc) + static_cast(doprocessTracksD0sRun3ppMc) + static_cast(doprocessTracksD0sRun3PbPbMc) + static_cast(doprocessTracksLcsRun3pp) + @@ -833,6 +837,29 @@ struct FemtoProducer { } PROCESS_SWITCH(FemtoProducer, processTracksSigmaPlusPcmsRun3pp, "Provide tracks and sigma plus reconstructed with a PCM photon", false); + void processTracksKinksSigmaPlusPcmsRun3pp(rawinputs::Run3PpCollisions const& cols, + o2::aod::BCsWithTimestamps const& bcs, + rawinputs::Run3FullPidTracks const& tracks, + rawinputs::Run3Kinks const& kinks, + rawinputs::Run3SigmaPlusPcms const& sigmaPlusPcms) + { + builders.trackBuilder.reset(tracks); + for (auto const& col : cols) { + auto tracksThisCol = tracks.sliceBy(preslices.perColTracks, col.globalIndex()); + if (!processCollisions(col, bcs, tracksThisCol)) { + continue; + } + auto tracksWithItsPid = o2::soa::Attach(tracksThisCol); + processTracks(col, tracksWithItsPid); + auto kinksThisCol = kinks.sliceBy(preslices.perColRecoKinks, col.globalIndex()); + processKinks(col, tracksThisCol, kinksThisCol); + auto sigmaPlusPcmsThisCol = sigmaPlusPcms.sliceBy(preslices.perColSigmaPlusPcms, col.globalIndex()); + processSigmaPlusPcms(col, tracksThisCol, sigmaPlusPcmsThisCol); + } + } + PROCESS_SWITCH(FemtoProducer, processTracksKinksSigmaPlusPcmsRun3pp, "Provide tracks, kinks and sigma plus reconstructed with a PCM photon", false); + void processTracksV0sCascadesKinksRun3pp(rawinputs::Run3PpCollisions const& cols, o2::aod::BCsWithTimestamps const& bcs, rawinputs::Run3FullPidTracks const& tracks, @@ -1168,6 +1195,37 @@ struct FemtoProducer { } PROCESS_SWITCH(FemtoProducer, processTracksSigmaPlusPcmsRun3ppMc, "Provide reconstructed and generated tracks and sigma plus reconstructed with a PCM photon", false); + void processTracksKinksSigmaPlusPcmsRun3ppMc(rawinputs::Run3PpMcGenCollisions const& mcCols, + rawinputs::Run3PpMcRecoCollisions const& cols, + o2::aod::BCsWithTimestamps const& bcs, + rawinputs::Run3McRecoTracks const& tracks, + rawinputs::Run3Kinks const& kinks, + rawinputs::Run3RecoSigmaPlusPcms const& sigmaPlusPcms, + rawinputs::Run3McGenParticles const& mcParticles) + { + builders.mcBuilder.reset(mcCols, mcParticles); + builders.trackBuilder.reset(tracks); + if (builders.mcBuilder.isPassThrough()) { + builders.mcBuilder.fillMcPassThrough(mcCols, mcParticles, preslices.perMcCollision, mcProducts); + } + + for (const auto& col : cols) { + auto tracksThisCol = tracks.sliceBy(preslices.perColRecoTracks, col.globalIndex()); + if (!processMcCollisions(col, mcCols, bcs, tracksThisCol)) { + continue; + } + auto tracksWithItsPid = o2::soa::Attach(tracksThisCol); + processMcTracks(col, mcCols, tracksThisCol, tracksWithItsPid, mcParticles); + + auto kinksThisCol = kinks.sliceBy(preslices.perColRecoKinks, col.globalIndex()); + processMcKinks(col, mcCols, tracks, kinksThisCol, mcParticles); + auto sigmaPlusPcmsThisCol = sigmaPlusPcms.sliceBy(preslices.perColRecoSigmaPlusPcms, col.globalIndex()); + processMcSigmaPlusPcms(col, mcCols, tracks, sigmaPlusPcmsThisCol, mcParticles); + } + } + PROCESS_SWITCH(FemtoProducer, processTracksKinksSigmaPlusPcmsRun3ppMc, "Provide reconstructed and generated tracks, kinks and sigma plus reconstructed with a PCM photon", false); + void processTracksV0sKinksRun3ppMc(rawinputs::Run3PpMcGenCollisions const& mcCols, rawinputs::Run3PpMcRecoCollisions const& cols, o2::aod::BCsWithTimestamps const& bcs,