diff --git a/PWGCF/Femto/Core/closePairRejection.h b/PWGCF/Femto/Core/closePairRejection.h index 4a693b89267..84b60eefee9 100644 --- a/PWGCF/Femto/Core/closePairRejection.h +++ b/PWGCF/Femto/Core/closePairRejection.h @@ -65,6 +65,8 @@ constexpr char PrefixTrackTrackSe[] = "CPR_TrackTrack/SE/"; constexpr char PrefixTrackTrackMe[] = "CPR_TrackTrack/ME/"; constexpr char PrefixTrackV0Se[] = "CPR_TrackV0/SE/"; constexpr char PrefixTrackV0Me[] = "CPR_TrackV0/ME/"; +constexpr char PrefixTrackKinkSe[] = "CPR_TrackKink/SE/"; +constexpr char PrefixTrackKinkMe[] = "CPR_TrackKink/ME/"; // must be in sync with enum TrackVariables // the enum gives the correct index in the array @@ -260,6 +262,50 @@ class ClosePairRejectionTrackV0 // can also be used for any particle type that h bool mIsActivated = true; }; +template +class ClosePairRejectionTrackKink +{ + public: + void init(o2::framework::HistogramRegistry* registry, std::map>& specs, float detaMax, float dphistarMax, int signTrack, int absChargeTrack, bool isActivated) + { + mIsActivated = isActivated; + mSignTrack = signTrack; + + // initialize CPR with charge of the track and the charged daughter particle + // For kinks, we compare the primary track with the charged daughter + // The charged daughter has absolute charge of 1, so we can pass the sign directly + mCtr.init(registry, specs, detaMax, dphistarMax, signTrack * absChargeTrack, mSignTrack); + } + + void setMagField(float magField) + { + mCtr.setMagField(magField); + } + + template + void setPair(const T1& track, const T2& kink, const T3 /*trackTable*/) + { + if (mSignTrack == 1 || mSignTrack == -1) { + auto daughter = kink.template chaDau_as(); + mCtr.compute(track, daughter); + } else { + LOG(warn) << "CPR Track-Kink: Wrong track sign"; + } + } + + bool isClosePair() const { return mCtr.isClosePair(); } + void fill() + { + mCtr.fill(); + } + bool isActivated() const { return mIsActivated; } + + private: + CloseTrackRejection mCtr; + int mSignTrack = 0; + bool mIsActivated = true; +}; + }; // namespace closepairrejection }; // namespace o2::analysis::femto #endif // PWGCF_FEMTO_CORE_CLOSEPAIRREJECTION_H_ diff --git a/PWGCF/Femto/Core/femtoUtils.h b/PWGCF/Femto/Core/femtoUtils.h index 13a8bfb981f..f853d5e0c4b 100644 --- a/PWGCF/Femto/Core/femtoUtils.h +++ b/PWGCF/Femto/Core/femtoUtils.h @@ -145,6 +145,9 @@ inline float getMass(int pdgCode) case o2::constants::physics::Pdg::kHelium3: mass = o2::constants::physics::MassHelium3; break; + case kSigmaMinus: + mass = o2::constants::physics::MassSigmaMinus; + break; default: LOG(fatal) << "PDG code is not suppored"; } diff --git a/PWGCF/Femto/Core/kinkHistManager.h b/PWGCF/Femto/Core/kinkHistManager.h index 8371a78d5e3..c32e23ba5dd 100644 --- a/PWGCF/Femto/Core/kinkHistManager.h +++ b/PWGCF/Femto/Core/kinkHistManager.h @@ -150,9 +150,8 @@ std::map> makeKinkQaHistSpecMap(T1 co } constexpr char PrefixSigmaQa[] = "SigmaQA/"; -constexpr char PrefixSigma[] = "Sigma/"; -constexpr char PrefixKinkChaDaughter[] = "KinkChaDau/"; -constexpr char PrefixKinkChaDaughterQa[] = "KinkChaDauQa/"; +constexpr char PrefixSigma1[] = "Sigma1/"; +constexpr char PrefixSigma2[] = "Sigma2/"; constexpr std::string_view AnalysisDir = "Kinematics/"; constexpr std::string_view QaDir = "QA/"; diff --git a/PWGCF/Femto/Core/pairBuilder.h b/PWGCF/Femto/Core/pairBuilder.h index 2d82529ca87..7e38b1ff98c 100644 --- a/PWGCF/Femto/Core/pairBuilder.h +++ b/PWGCF/Femto/Core/pairBuilder.h @@ -18,6 +18,7 @@ #include "PWGCF/Femto/Core/closePairRejection.h" #include "PWGCF/Femto/Core/collisionHistManager.h" +#include "PWGCF/Femto/Core/kinkHistManager.h" #include "PWGCF/Femto/Core/modes.h" #include "PWGCF/Femto/Core/pairCleaner.h" #include "PWGCF/Femto/Core/pairHistManager.h" @@ -296,6 +297,107 @@ class PairTrackV0Builder int mMixingDepth = 5; }; +template < + const char* prefixTrack, + const char* prefixKink, + const char* prefixChaDau, + const char* prefixSe, + const char* prefixMe, + const char* prefixCprSe, + const char* prefixCprMe, + modes::Mode mode, + modes::Kink kinkType> +class PairTrackKinkBuilder +{ + public: + PairTrackKinkBuilder() = default; + + template + void init(o2::framework::HistogramRegistry* registry, + T1& confTrackSelection, + T2& confKinkSelection, + T3& confCpr, + T4& confMixing, + std::map>& colHistSpec, + std::map>& trackHistSpec, + std::map>& kinkHistSpec, + std::map>& chaDauHistSpec, + std::map>& pairHistSpec, + std::map>& cprHistSpec) + { + mColHistManager.init(registry, colHistSpec); + + mTrackHistManager.init(registry, trackHistSpec); + mKinkHistManager.init(registry, kinkHistSpec, chaDauHistSpec); + + mPairHistManagerSe.init(registry, pairHistSpec); + mPairHistManagerSe.setMass(confTrackSelection.pdgCode.value, confKinkSelection.pdgCode.value); + mPairHistManagerSe.setCharge(confTrackSelection.absCharge.value, 1); + mCprSe.init(registry, cprHistSpec, confCpr.detaMax.value, confCpr.dphistarMax.value, confTrackSelection.sign.value, confTrackSelection.absCharge.value, confCpr.on.value); + + mPairHistManagerMe.init(registry, pairHistSpec); + mPairHistManagerMe.setMass(confTrackSelection.pdgCode.value, confKinkSelection.pdgCode.value); + mPairHistManagerMe.setCharge(confTrackSelection.absCharge.value, 1); + mCprMe.init(registry, cprHistSpec, confCpr.detaMax.value, confCpr.dphistarMax.value, confTrackSelection.sign.value, confTrackSelection.absCharge.value, confCpr.on.value); + + // setup mixing + mMixingPolicy = static_cast(confMixing.policy.value); + mMixingDepth = confMixing.depth.value; + } + + template + void processSameEvent(T1 const& col, T2& trackTable, T3& trackPartition, T4& /*kinktable*/, T5& kinkPartition, T6& cache) + { + auto trackSlice = trackPartition->sliceByCached(o2::aod::femtobase::stored::collisionId, col.globalIndex(), cache); + auto kinkSlice = kinkPartition->sliceByCached(o2::aod::femtobase::stored::collisionId, col.globalIndex(), cache); + if (trackSlice.size() == 0 || kinkSlice.size() == 0) { + return; + } + mColHistManager.fill(col); + mCprSe.setMagField(col.magField()); + pairprocesshelpers::processSameEvent(trackSlice, kinkSlice, trackTable, mTrackHistManager, mKinkHistManager, mPairHistManagerSe, mCprSe, mPc); + } + + template + void processMixedEvent(T1 const& cols, T2& trackTable, T3& trackPartition, T4& kinkPartition, T5& cache, T6& binsVtxMult, T7& binsVtxCent, T8& binsVtxMultCent) + { + switch (mMixingPolicy) { + case static_cast(pairhistmanager::kVtxMult): + pairprocesshelpers::processMixedEvent(cols, trackPartition, kinkPartition, trackTable, cache, binsVtxMult, mMixingDepth, mPairHistManagerMe, mCprMe, mPc); + break; + case static_cast(pairhistmanager::kVtxCent): + pairprocesshelpers::processMixedEvent(cols, trackPartition, kinkPartition, trackTable, cache, binsVtxCent, mMixingDepth, mPairHistManagerMe, mCprMe, mPc); + break; + case static_cast(pairhistmanager::kVtxMultCent): + pairprocesshelpers::processMixedEvent(cols, trackPartition, kinkPartition, trackTable, cache, binsVtxMultCent, mMixingDepth, mPairHistManagerMe, mCprMe, mPc); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + + private: + colhistmanager::CollisionHistManager mColHistManager; + trackhistmanager::TrackHistManager mTrackHistManager; + kinkhistmanager::KinkHistManager mKinkHistManager; + pairhistmanager::PairHistManager mPairHistManagerSe; + pairhistmanager::PairHistManager mPairHistManagerMe; + closepairrejection::ClosePairRejectionTrackKink mCprSe; + closepairrejection::ClosePairRejectionTrackKink mCprMe; + paircleaner::TrackKinkPairCleaner mPc; + pairhistmanager::MixingPoliciy mMixingPolicy = pairhistmanager::MixingPoliciy::kVtxMult; + int mMixingDepth = 5; +}; + } // namespace pairbuilder } // namespace o2::analysis::femto diff --git a/PWGCF/Femto/Core/pairCleaner.h b/PWGCF/Femto/Core/pairCleaner.h index 47608056acf..81e0918552b 100644 --- a/PWGCF/Femto/Core/pairCleaner.h +++ b/PWGCF/Femto/Core/pairCleaner.h @@ -58,6 +58,18 @@ class TrackV0PairCleaner : public BasePairCleaner return this->isCleanTrackPair(posDaughter, track) && this->isCleanTrackPair(negDaughter, track); } }; + +class TrackKinkPairCleaner : public BasePairCleaner +{ + public: + TrackKinkPairCleaner() = default; + template + bool isCleanPair(const T1& track, const T2& kink, const T3& /*trackTable */) const + { + auto chaDaughter = kink.template chaDau_as(); + return this->isCleanTrackPair(chaDaughter, track); + } +}; } // namespace paircleaner } // namespace o2::analysis::femto diff --git a/PWGCF/Femto/Core/pairHistManager.h b/PWGCF/Femto/Core/pairHistManager.h index c256c09b9af..5f6d8bbdf9b 100644 --- a/PWGCF/Femto/Core/pairHistManager.h +++ b/PWGCF/Femto/Core/pairHistManager.h @@ -121,6 +121,9 @@ constexpr char PrefixTrackTrackMe[] = "TrackTrack/ME/"; constexpr char PrefixTrackV0Se[] = "TrackV0/SE/"; constexpr char PrefixTrackV0Me[] = "TrackV0/ME/"; +constexpr char PrefixTrackKinkSe[] = "TrackKink/SE/"; +constexpr char PrefixTrackKinkMe[] = "TrackKink/ME/"; + constexpr std::string_view AnalysisDir = "Analysis/"; constexpr std::string_view QaDir = "QA/"; diff --git a/PWGCF/Femto/Tasks/CMakeLists.txt b/PWGCF/Femto/Tasks/CMakeLists.txt index 0eacf23db6b..1763a60b7bc 100644 --- a/PWGCF/Femto/Tasks/CMakeLists.txt +++ b/PWGCF/Femto/Tasks/CMakeLists.txt @@ -43,3 +43,8 @@ o2physics_add_dpl_workflow(femto-pair-track-v0 SOURCES femtoPairTrackV0.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(femto-pair-track-kink + SOURCES femtoPairTrackKink.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx b/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx new file mode 100644 index 00000000000..b3945633f85 --- /dev/null +++ b/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx @@ -0,0 +1,153 @@ +// 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 femtoPairTrackKink.cxx +/// \brief Tasks that computes correlation between tracks and kinks +/// \author Anton Riedel, TU München, anton.riedel@cern.ch +/// \author Henrik Fribert, TU München, henrik.fribert@cern.ch + +#include "PWGCF/Femto/Core/closePairRejection.h" +#include "PWGCF/Femto/Core/collisionBuilder.h" +#include "PWGCF/Femto/Core/collisionHistManager.h" +#include "PWGCF/Femto/Core/kinkBuilder.h" +#include "PWGCF/Femto/Core/kinkHistManager.h" +#include "PWGCF/Femto/Core/modes.h" +#include "PWGCF/Femto/Core/pairBuilder.h" +#include "PWGCF/Femto/Core/pairHistManager.h" +#include "PWGCF/Femto/Core/partitions.h" +#include "PWGCF/Femto/Core/trackBuilder.h" +#include "PWGCF/Femto/Core/trackHistManager.h" +#include "PWGCF/Femto/DataModel/FemtoTables.h" + +#include "Framework/ASoA.h" +#include "Framework/AnalysisTask.h" +#include "Framework/Configurable.h" +#include "Framework/Expressions.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + +#include +#include + +using namespace o2; +using namespace o2::aod; +using namespace o2::soa; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::analysis::femto; + +struct FemtoPairTrackKink { + + // setup tables + using Collisions = Join; + using Collision = Collisions::iterator; + + using FilteredCollisions = o2::soa::Filtered; + using FilteredCollision = FilteredCollisions::iterator; + + using Tracks = o2::soa::Join; + using Sigmas = o2::soa::Join; + + SliceCache cache; + + // setup collisions + collisionbuilder::ConfCollisionSelection collisionSelection; + Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); + colhistmanager::ConfCollisionBinning confCollisionBinning; + + // setup tracks + trackbuilder::ConfTrackSelection1 trackSelection; + trackhistmanager::ConfTrackBinning1 confTrackBinning; + Partition trackPartition = MAKE_TRACK_PARTITION(trackSelection); + Preslice perColTracks = aod::femtobase::stored::collisionId; + + // setup for daughters + trackhistmanager::ConfKinkChaDauBinning confChaDauBinning; + + // setup sigmas + kinkbuilder::ConfSigmaSelection1 sigmaSelection; + kinkhistmanager::ConfSigmaBinning1 confSigmaBinning; + Partition sigmaPartition = MAKE_SIGMA_PARTITION(sigmaSelection); + Preslice perColSigmas = aod::femtobase::stored::collisionId; + + // setup pairs + pairhistmanager::ConfPairBinning confPairBinning; + + pairbuilder::PairTrackKinkBuilder< + trackhistmanager::PrefixTrack1, + kinkhistmanager::PrefixSigma1, + trackhistmanager::PrefixKinkChaDaughter, + pairhistmanager::PrefixTrackKinkSe, + pairhistmanager::PrefixTrackKinkMe, + closepairrejection::PrefixTrackKinkSe, + closepairrejection::PrefixTrackKinkMe, + modes::Mode::kAnalysis, + modes::Kink::kSigma> + pairTrackSigmaBuilder; + + // setup mixing + std::vector defaultVtxBins{10, -10, 10}; + std::vector defaultMultBins{50, 0, 200}; + std::vector defaultCentBins{10, 0, 100}; + ColumnBinningPolicy mixBinsVtxMult{{defaultVtxBins, defaultMultBins}, true}; + ColumnBinningPolicy mixBinsVtxCent{{defaultVtxBins, defaultCentBins}, true}; + ColumnBinningPolicy mixBinsVtxMultCent{{defaultVtxBins, defaultMultBins, defaultCentBins}, true}; + pairhistmanager::ConfMixing confMixing; + + HistogramRegistry hRegistry{"FemtoTrackKink", {}, OutputObjHandlingPolicy::AnalysisObject}; + + // setup cpr + closepairrejection::ConfCpr confCpr; + + void init(InitContext&) + { + + // setup columnpolicy for binning + // default values are used during instantiation, so we need to explicity update them here + mixBinsVtxMult = {{confMixing.vtxBins, confMixing.multBins.value}, true}; + mixBinsVtxCent = {{confMixing.vtxBins.value, confMixing.centBins.value}, true}; + mixBinsVtxMultCent = {{confMixing.vtxBins.value, confMixing.multBins.value, confMixing.centBins.value}, true}; + + // setup histograms + auto colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); + auto trackHistSpec = trackhistmanager::makeTrackHistSpecMap(confTrackBinning); + auto chaDauSpec = trackhistmanager::makeTrackHistSpecMap(confChaDauBinning); + auto pairHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning, confTrackBinning, confSigmaBinning); + auto cprHistSpec = closepairrejection::makeCprHistSpecMap(confCpr); + + // setup for sigma + // if (doprocessSigmaSameEvent || doprocessSigmaMixedEvent) { + if (doprocessSigmaSameEvent) { + auto sigmaHistSpec = kinkhistmanager::makeKinkHistSpecMap(confSigmaBinning); + pairTrackSigmaBuilder.init(&hRegistry, trackSelection, sigmaSelection, confCpr, confMixing, colHistSpec, trackHistSpec, sigmaHistSpec, chaDauSpec, pairHistSpec, cprHistSpec); + } + }; + + void processSigmaSameEvent(FilteredCollision const& col, Tracks const& tracks, Sigmas const& sigmas) + { + pairTrackSigmaBuilder.processSameEvent(col, tracks, trackPartition, sigmas, sigmaPartition, cache); + } + PROCESS_SWITCH(FemtoPairTrackKink, processSigmaSameEvent, "Enable processing same event processing for tracks and sigmas", true); + + void processSigmaMixedEvent(FilteredCollisions const& cols, Tracks const& tracks, Sigmas const& /*sigmas*/) + { + pairTrackSigmaBuilder.processMixedEvent(cols, tracks, trackPartition, sigmaPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + } + PROCESS_SWITCH(FemtoPairTrackKink, processSigmaMixedEvent, "Enable processing mixed event processing for tracks and sigmas", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{ + adaptAnalysisTask(cfgc), + }; + return workflow; +}