diff --git a/PWGCF/Femto/Core/closeTripletRejection.h b/PWGCF/Femto/Core/closeTripletRejection.h index dd1bd0182c0..0e05c865a6f 100644 --- a/PWGCF/Femto/Core/closeTripletRejection.h +++ b/PWGCF/Femto/Core/closeTripletRejection.h @@ -46,6 +46,21 @@ constexpr char PrefixTrack2V0Se[] = "CPR_Track2V0/SE/"; constexpr char PrefixTrack1V0Me[] = "CPR_Track1V0/ME/"; constexpr char PrefixTrack2V0Me[] = "CPR_Track2V0/ME/"; +constexpr char PrefixTrack1CascadeSe[] = "CPR_Track1Cascade/SE/"; +constexpr char PrefixTrack2CascadeSe[] = "CPR_Track2Cascade/SE/"; +constexpr char PrefixTrack1CascadeMe[] = "CPR_Track1Cascade/ME/"; +constexpr char PrefixTrack2CascadeMe[] = "CPR_Track2Cascade/ME/"; + +constexpr char PrefixTrack1V0DaughterSe[] = "CPR_Track1V0Dau/SE/"; +constexpr char PrefixTrack2V0DaughterSe[] = "CPR_Track2V0Dau/SE/"; +constexpr char PrefixTrack1V0DaughterMe[] = "CPR_Track1V0Dau/ME/"; +constexpr char PrefixTrack2V0DaughterMe[] = "CPR_Track2V0Dau/ME/"; + +constexpr char PrefixTrack1CascadeBachelorSe[] = "CPR_Track1CascadeBachelor/SE/"; +constexpr char PrefixTrack2CascadeBachelorSe[] = "CPR_TrackCascadeBachelor/SE/"; +constexpr char PrefixTrack1CascadeBachelorMe[] = "CPR_TrackCascadeBachelor/ME/"; +constexpr char PrefixTrack2CascadeBachelorMe[] = "CPR_TrackCascadeBachelor/ME/"; + template @@ -151,6 +166,64 @@ class CloseTripletRejectionTrackTrackV0 closepairrejection::ClosePairRejectionTrackV0 mCtrTrack2V0; }; +template +class CloseTripletRejectionTrackTrackCascade +{ + public: + CloseTripletRejectionTrackTrackCascade() = default; + ~CloseTripletRejectionTrackTrackCascade() = default; + + template + void init(o2::framework::HistogramRegistry* registry, + std::map> const& specs, + std::map> const& specsBachelor, + std::map> const& specsV0Daughter, + T1 const& confCpr, + T2 const& confCprBachelor, + T3 const& confCprV0Daughter, + int absChargeTrack1, + int absChargeTrack2) + { + mCtrTrack12.init(registry, specs, confCpr, absChargeTrack1, absChargeTrack2); + mCtrTrack1Cascade.init(registry, specsBachelor, specsV0Daughter, confCprBachelor, confCprV0Daughter, absChargeTrack1); + mCtrTrack2Cascade.init(registry, specsBachelor, specsV0Daughter, confCprBachelor, confCprV0Daughter, absChargeTrack2); + } + + void setMagField(float magField) + { + mCtrTrack12.setMagField(magField); + mCtrTrack1Cascade.setMagField(magField); + mCtrTrack2Cascade.setMagField(magField); + } + template + void setTriplet(T1 const& track1, T2 const& track2, T3 const& cascade, T4 const& trackTable) + { + mCtrTrack12.setPair(track1, track2, trackTable); + mCtrTrack1Cascade.setPair(track1, cascade, trackTable); + mCtrTrack2Cascade.setPair(track2, cascade, trackTable); + } + bool isCloseTriplet() const + { + return mCtrTrack12.isClosePair() || mCtrTrack1Cascade.isClosePair() || mCtrTrack2Cascade.isClosePair(); + } + + void fill(float q3) + { + mCtrTrack12.fill(q3); + mCtrTrack1Cascade.fill(q3); + mCtrTrack2Cascade.fill(q3); + } + + private: + closepairrejection::ClosePairRejectionTrackTrack mCtrTrack12; + closepairrejection::ClosePairRejectionTrackCascade mCtrTrack1Cascade; + closepairrejection::ClosePairRejectionTrackCascade mCtrTrack2Cascade; +}; + }; // namespace closetripletrejection }; // namespace o2::analysis::femto #endif // PWGCF_FEMTO_CORE_CLOSETRIPLETREJECTION_H_ diff --git a/PWGCF/Femto/Core/tripletBuilder.h b/PWGCF/Femto/Core/tripletBuilder.h index 909934a1b69..427ec4fbb20 100644 --- a/PWGCF/Femto/Core/tripletBuilder.h +++ b/PWGCF/Femto/Core/tripletBuilder.h @@ -16,10 +16,12 @@ #ifndef PWGCF_FEMTO_CORE_TRIPLETBUILDER_H_ #define PWGCF_FEMTO_CORE_TRIPLETBUILDER_H_ +#include "PWGCF/Femto/Core/cascadeHistManager.h" #include "PWGCF/Femto/Core/closeTripletRejection.h" #include "PWGCF/Femto/Core/collisionHistManager.h" #include "PWGCF/Femto/Core/modes.h" #include "PWGCF/Femto/Core/pairHistManager.h" +#include "PWGCF/Femto/Core/particleCleaner.h" #include "PWGCF/Femto/Core/trackHistManager.h" #include "PWGCF/Femto/Core/tripletCleaner.h" #include "PWGCF/Femto/Core/tripletHistManager.h" @@ -623,6 +625,288 @@ class TripletTrackTrackV0Builder std::uniform_int_distribution<> mDist; }; +template +class TripletTrackTrackCascadeBuilder +{ + public: + TripletTrackTrackCascadeBuilder() = default; + ~TripletTrackTrackCascadeBuilder() = default; + + template + + void init(o2::framework::HistogramRegistry* registry, + T1 const& confCollisionBinning, + T2 const& confTrackSelection1, + T3 const& confTrackSelection2, + T4 const& confTrackCleaner, + T5 const& confCtr, + T6 const& confCascadeSelection, + T7 const& confCascadeCleaner, + T8 const& confCprBachelor, + T9 const& confCprV0Daughter, + T10 const& confMixing, + T11 const& confTripletBinning, + T12 const& confTripletCuts, + std::map>& colHistSpec, + std::map>& trackHistSpec1, + std::map>& trackHistSpec2, + std::map>& cascadeHistSpec, + std::map>& bachelorHistSpec, + std::map>& posDauHistSpec, + std::map>& negDauHistSpec, + std::map>& tripletHistSpec, + std::map>& cprHistSpecBachelor, + std::map>& cprHistSpecV0Daughter, + std::map>& ctrHistSpec) + { + // check if correlate the same tracks or not + mTrack1Track2AreSameSpecies = confMixing.particle12AreSameSpecies.value; + + mColHistManager.template init(registry, colHistSpec, confCollisionBinning); + mTripletHistManagerSe.template init(registry, tripletHistSpec, confTripletBinning, confTripletCuts); + mTripletHistManagerMe.template init(registry, tripletHistSpec, confTripletBinning, confTripletCuts); + + mTc.template init(confTripletCuts); + + if (mTrack1Track2AreSameSpecies) { + // Track1 & Track2 & are the same particle species and track 3 is something else + mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); + mCascadeHistManager.template init(registry, cascadeHistSpec, confCascadeSelection, bachelorHistSpec, posDauHistSpec, negDauHistSpec); + + mTrackCleaner.init(confTrackCleaner); + mCascadeCleaner.init(confCascadeCleaner); + + mTripletHistManagerSe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection1.pdgCodeAbs.value, confCascadeSelection.pdgCodeAbs.value); + mTripletHistManagerSe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value, 1); + mCtrSe.init(registry, ctrHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter, confCtr, confCprBachelor, confCprV0Daughter, confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value); + + mTripletHistManagerMe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection1.pdgCodeAbs.value, confCascadeSelection.pdgCodeAbs.value); + mTripletHistManagerMe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value, 1); + mCtrMe.init(registry, ctrHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter, confCtr, confCprBachelor, confCprV0Daughter, confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value); + } else { + // all three tracks are different + mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); + mTrackHistManager2.template init(registry, trackHistSpec2, confTrackSelection2); + mCascadeHistManager.template init(registry, cascadeHistSpec, confCascadeSelection, bachelorHistSpec, posDauHistSpec, negDauHistSpec); + + mTripletHistManagerSe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection2.pdgCodeAbs.value, confCascadeSelection.pdgCodeAbs.value); + mTripletHistManagerSe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection2.chargeAbs.value, 1); + mCtrSe.init(registry, ctrHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter, confCtr, confCprBachelor, confCprV0Daughter, confTrackSelection1.chargeAbs.value, confTrackSelection2.chargeAbs.value); + + mTripletHistManagerMe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection2.pdgCodeAbs.value, confCascadeSelection.pdgCodeAbs.value); + mTripletHistManagerMe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection2.chargeAbs.value, 1); + mCtrMe.init(registry, ctrHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter, confCtr, confCprBachelor, confCprV0Daughter, confTrackSelection1.chargeAbs.value, confTrackSelection2.chargeAbs.value); + } + + // setup mixing + mMixingPolicy = static_cast(confMixing.policy.value); + mMixingDepth = confMixing.depth.value; + + // setup rng if necessary + if (confMixing.seed.value >= 0) { + uint64_t randomSeed = 0; + mMixIdenticalParticles = true; + if (confMixing.seed.value == 0) { + randomSeed = static_cast(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); + } else { + randomSeed = static_cast(confMixing.seed.value); + } + mRng = std::mt19937(randomSeed); + mDist = std::uniform_int_distribution<>(tripletprocesshelpers::kOrder123, tripletprocesshelpers::kOrder213); + } + } + + // data + template + void processSameEvent(T1 const& col, T2& trackTable, T3& partition1, T4& partition2, T5& partition3, T6& cache) + { + tripletprocesshelpers::TripletOrder tripletOrder = tripletprocesshelpers::kOrder123; + if (mTrack1Track2AreSameSpecies) { + auto trackSlice1 = partition1->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + auto cascadeSlice = partition3->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + if (trackSlice1.size() < nLimitPartitionIdenticalParticles12 || cascadeSlice.size() < nLimitPartitionParticles) { + return; + } + mColHistManager.template fill(col); + mCtrSe.setMagField(col.magField()); + if (mMixIdenticalParticles) { + tripletOrder = static_cast(mDist(mRng)); + } + tripletprocesshelpers::processSameEvent(trackSlice1, cascadeSlice, trackTable, col, mTrackHistManager1, mCascadeHistManager, mTripletHistManagerSe, mCtrSe, mTc, tripletOrder); + } else { + auto trackSlice1 = partition1->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + auto trackSlice2 = partition2->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + auto cascadeSlice = partition3->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + if (trackSlice1.size() < nLimitPartitionParticles || trackSlice2.size() < nLimitPartitionParticles || cascadeSlice.size() < nLimitPartitionParticles) { + return; + } + mColHistManager.template fill(col); + mCtrSe.setMagField(col.magField()); + tripletprocesshelpers::processSameEvent(trackSlice1, trackSlice2, cascadeSlice, trackTable, col, mTrackHistManager1, mTrackHistManager2, mCascadeHistManager, mTripletHistManagerSe, mCtrSe, mTc); + } + } + + // mc + template + void processSameEvent(T1 const& col, T2 const& mcCols, T3& trackTable, T4& partition1, T5& partition2, T6& partition3, T7 const& mcParticles, T8 const& mcMothers, T9 const& mcPartonicMothers, T10& cache) + { + tripletprocesshelpers::TripletOrder tripletOrder = tripletprocesshelpers::kOrder123; + if (mTrack1Track2AreSameSpecies) { + auto trackSlice1 = partition1->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + auto cascadeSlice = partition3->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + if (trackSlice1.size() < nLimitPartitionIdenticalParticles12 || cascadeSlice.size() < nLimitPartitionParticles) { + return; + } + mColHistManager.template fill(col, mcCols); + mCtrSe.setMagField(col.magField()); + if (mMixIdenticalParticles) { + tripletOrder = static_cast(mDist(mRng)); + } + tripletprocesshelpers::processSameEvent(trackSlice1, cascadeSlice, trackTable, mcParticles, mcMothers, mcPartonicMothers, col, mcCols, mTrackHistManager1, mCascadeHistManager, mTripletHistManagerSe, mCtrSe, mTc, tripletOrder); + } else { + auto trackSlice1 = partition1->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + auto trackSlice2 = partition2->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + auto cascadeSlice = partition3->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + if (trackSlice1.size() < nLimitPartitionParticles || trackSlice2.size() < nLimitPartitionParticles || cascadeSlice.size() < nLimitPartitionParticles) { + return; + } + mColHistManager.template fill(col, mcCols); + mCtrSe.setMagField(col.magField()); + tripletprocesshelpers::processSameEvent(trackSlice1, trackSlice2, cascadeSlice, trackTable, mcParticles, mcMothers, mcPartonicMothers, col, mcCols, mTrackHistManager1, mTrackHistManager2, mCascadeHistManager, mTripletHistManagerSe, mCtrSe, mTc); + } + } + + template + void processMixedEvent(T1 const& cols, T2& trackTable, T3& partition1, T4& partition2, T5& partition3, T6& cache, T7& binsVtxMult, T8& binsVtxCent, T9& binsVtxMultCent) + { + if (mTrack1Track2AreSameSpecies) { + switch (mMixingPolicy) { + case static_cast(pairhistmanager::kVtxMult): + tripletprocesshelpers::processMixedEvent(cols, partition1, partition1, partition3, trackTable, cache, binsVtxMult, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + + break; + case static_cast(pairhistmanager::kVtxCent): + tripletprocesshelpers::processMixedEvent(cols, partition1, partition1, partition3, trackTable, cache, binsVtxCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + case static_cast(pairhistmanager::kVtxMultCent): + tripletprocesshelpers::processMixedEvent(cols, partition1, partition1, partition3, trackTable, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } else { + switch (mMixingPolicy) { + case static_cast(pairhistmanager::kVtxMult): + tripletprocesshelpers::processMixedEvent(cols, partition1, partition2, partition3, trackTable, cache, binsVtxMult, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + case static_cast(pairhistmanager::kVtxCent): + tripletprocesshelpers::processMixedEvent(cols, partition1, partition2, partition3, trackTable, cache, binsVtxCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + case static_cast(pairhistmanager::kVtxMultCent): + tripletprocesshelpers::processMixedEvent(cols, partition1, partition2, partition3, trackTable, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + } + + template + void processMixedEvent(T1 const& cols, T2 const& mcCols, T3& trackTable, T4& partition1, T5& partition2, T6& partition3, T7 const& mcParticles, T8& cache, T9& binsVtxMult, T10& binsVtxCent, T11& binsVtxMultCent) + { + if (mTrack1Track2AreSameSpecies) { + switch (mMixingPolicy) { + case static_cast(pairhistmanager::kVtxMult): + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition1, partition3, trackTable, mcParticles, cache, binsVtxMult, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + case static_cast(pairhistmanager::kVtxCent): + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition1, partition3, trackTable, mcParticles, cache, binsVtxCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + case static_cast(pairhistmanager::kVtxMultCent): + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition1, partition3, trackTable, mcParticles, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } else { + switch (mMixingPolicy) { + case static_cast(pairhistmanager::kVtxMult): + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition2, partition3, trackTable, mcParticles, cache, binsVtxMult, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + case static_cast(pairhistmanager::kVtxCent): + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition2, partition3, trackTable, mcParticles, cache, binsVtxCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + case static_cast(pairhistmanager::kVtxMultCent): + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition2, partition3, trackTable, mcParticles, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + } + + private: + colhistmanager::CollisionHistManager mColHistManager; + trackhistmanager::TrackHistManager mTrackHistManager1; + trackhistmanager::TrackHistManager mTrackHistManager2; + cascadehistmanager::CascadeHistManager mCascadeHistManager; + particlecleaner::ParticleCleaner mTrackCleaner; + particlecleaner::ParticleCleaner mCascadeCleaner; + triplethistmanager::TripletHistManager mTripletHistManagerSe; + triplethistmanager::TripletHistManager mTripletHistManagerMe; + + closetripletrejection::CloseTripletRejectionTrackTrackCascade mCtrSe; + closetripletrejection::CloseTripletRejectionTrackTrackCascade mCtrMe; + tripletcleaner::TrackTrackCascadeTripletCleaner mTc; + triplethistmanager::MixingPolicy mMixingPolicy = triplethistmanager::MixingPolicy::kVtxMult; + bool mTrack1Track2AreSameSpecies = false; + int mMixingDepth = 5; + bool mMixIdenticalParticles = false; + std::mt19937 mRng; + std::uniform_int_distribution<> mDist; +}; + } // namespace tripletbuilder } // namespace o2::analysis::femto diff --git a/PWGCF/Femto/Core/tripletCleaner.h b/PWGCF/Femto/Core/tripletCleaner.h index d6f38c78709..a92b78eccc6 100644 --- a/PWGCF/Femto/Core/tripletCleaner.h +++ b/PWGCF/Femto/Core/tripletCleaner.h @@ -99,6 +99,49 @@ class TrackTrackV0TripletCleaner : public paircleaner::BasePairCleaner } }; +class TrackTrackCascadeTripletCleaner : public paircleaner::BasePairCleaner +{ + public: + TrackTrackCascadeTripletCleaner() = default; + ~TrackTrackCascadeTripletCleaner() = default; + + template + bool isCleanTriplet(T1 const& track1, T2 const& track2, T3 const& cascade, T4 const& trackTable) const + { + auto bachelor = trackTable.rawIteratorAt(cascade.bachelorId() - trackTable.offset()); + auto posDaughter = trackTable.rawIteratorAt(cascade.posDauId() - trackTable.offset()); + auto negDaughter = trackTable.rawIteratorAt(cascade.negDauId() - trackTable.offset()); + return this->isCleanTrackPair(track1, track2) && + this->isCleanTrackPair(track1, posDaughter) && + this->isCleanTrackPair(track1, negDaughter) && + this->isCleanTrackPair(track1, bachelor) && + this->isCleanTrackPair(track2, posDaughter) && + this->isCleanTrackPair(track2, negDaughter) && + this->isCleanTrackPair(track2, bachelor); + } + + template + bool isCleanTriplet(T1 const& track1, T2 const& track2, T3 const& cascade, T4 const& trackTable, T5 const& partonicMothers) const + { + if (!this->isCleanTriplet(track1, track2, cascade, trackTable)) { + return false; + } + // pair is clean + // no check if we require common or non-common ancestry + if (mMixPairsWithCommonAncestor) { + return this->pairHasCommonAncestor(track1, track2, partonicMothers) && + this->pairHasCommonAncestor(track1, cascade, partonicMothers) && + this->pairHasCommonAncestor(track2, cascade, partonicMothers); + } + if (mMixPairsWithNonCommonAncestor) { + return this->pairHasNonCommonAncestor(track1, track2, partonicMothers) && + this->pairHasNonCommonAncestor(track1, cascade, partonicMothers) && + this->pairHasNonCommonAncestor(track2, cascade, partonicMothers); + } + return true; + } +}; + } // namespace tripletcleaner } // namespace o2::analysis::femto diff --git a/PWGCF/Femto/Core/tripletHistManager.h b/PWGCF/Femto/Core/tripletHistManager.h index 8e6674f0c10..c6dba6ce17a 100644 --- a/PWGCF/Femto/Core/tripletHistManager.h +++ b/PWGCF/Femto/Core/tripletHistManager.h @@ -199,6 +199,9 @@ constexpr char PrefixTrackTrackTrackMe[] = "TrackTrackTrack/ME/"; constexpr char PrefixTrackTrackLambdaSe[] = "TrackTrackLambda/SE/"; constexpr char PrefixTrackTrackLambdaMe[] = "TrackTrackLambda/ME/"; +constexpr char PrefixTrackTrackCascadeSe[] = "TrackTrackCascade/SE/"; +constexpr char PrefixTrackTrackCascadeMe[] = "TrackTrackCascade/ME/"; + constexpr std::string_view AnalysisDir = "Analysis/"; constexpr std::string_view QaDir = "QA/"; constexpr std::string_view McDir = "MC/"; diff --git a/PWGCF/Femto/Tasks/CMakeLists.txt b/PWGCF/Femto/Tasks/CMakeLists.txt index e2069762030..9f213c0645b 100644 --- a/PWGCF/Femto/Tasks/CMakeLists.txt +++ b/PWGCF/Femto/Tasks/CMakeLists.txt @@ -78,3 +78,8 @@ o2physics_add_dpl_workflow(femto-triplet-track-track-v0 SOURCES femtoTripletTrackTrackV0.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(femto-triplet-track-track-cascade + SOURCES femtoTripletTrackTrackCascade.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGCF/Femto/Tasks/femtoTripletTrackTrackCascade.cxx b/PWGCF/Femto/Tasks/femtoTripletTrackTrackCascade.cxx new file mode 100644 index 00000000000..d37e4741cf2 --- /dev/null +++ b/PWGCF/Femto/Tasks/femtoTripletTrackTrackCascade.cxx @@ -0,0 +1,312 @@ +// 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 femtoTripletTrackTrackCascade.cxx +/// \brief Tasks that computes correlation between two tracks and a cascade +/// \author Roberta Ferioli roberta.ferioli@cern.ch, Raffaele Del Grande raffaele.del.grande@cern.ch, CTU Prague + +#include "PWGCF/Femto/Core/cascadeBuilder.h" +#include "PWGCF/Femto/Core/cascadeHistManager.h" +#include "PWGCF/Femto/Core/closePairRejection.h" +#include "PWGCF/Femto/Core/closeTripletRejection.h" +#include "PWGCF/Femto/Core/collisionBuilder.h" +#include "PWGCF/Femto/Core/collisionHistManager.h" +#include "PWGCF/Femto/Core/modes.h" +#include "PWGCF/Femto/Core/particleCleaner.h" +#include "PWGCF/Femto/Core/partitions.h" +#include "PWGCF/Femto/Core/trackBuilder.h" +#include "PWGCF/Femto/Core/trackHistManager.h" +#include "PWGCF/Femto/Core/tripletBuilder.h" +#include "PWGCF/Femto/Core/tripletHistManager.h" +#include "PWGCF/Femto/DataModel/FemtoTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace o2::analysis::femto; + +struct FemtoTripletTrackTrackCascade { + + // setup tables + using FemtoCollisions = o2::soa::Join; + using FilteredFemtoCollisions = o2::soa::Filtered; + using FilteredFemtoCollision = FilteredFemtoCollisions::iterator; + + using FemtoCollisionsWithLabel = o2::soa::Join; + using FilteredFemtoCollisionsWithLabel = o2::soa::Filtered; + using FilteredFemtoCollisionWithLabel = FilteredFemtoCollisionsWithLabel::iterator; + + using FemtoTracks = o2::soa::Join; + using FemtoXis = o2::soa::Join; + using FemtoOmegas = o2::soa::Join; + + using FemtoTracksWithLabel = o2::soa::Join; + using FemtoXisWithLabel = o2::soa::Join; + using FemtoOmegasWithLabel = 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 tracks + trackbuilder::ConfTrackSelection1 confTrackSelections1; + trackhistmanager::ConfTrackBinning1 confTrackBinning1; + trackbuilder::ConfTrackSelection2 confTrackSelections2; + trackhistmanager::ConfTrackBinning2 confTrackBinning2; + + o2::framework::Partition trackPartition1 = MAKE_TRACK_PARTITION(confTrackSelections1); + o2::framework::Partition trackPartition2 = MAKE_TRACK_PARTITION(confTrackSelections2); + o2::framework::Preslice perColtracks = o2::aod::femtobase::stored::fColId; + + o2::framework::Partition trackWithLabelPartition1 = MAKE_TRACK_PARTITION(confTrackSelections1); + o2::framework::Partition trackWithLabelPartition2 = MAKE_TRACK_PARTITION(confTrackSelections2); + o2::framework::Preslice perColtracksWithLabel = o2::aod::femtobase::stored::fColId; + + // setup for daughters + trackhistmanager::ConfCascadePosDauBinning confPosDauBinning; + trackhistmanager::ConfCascadeNegDauBinning confNegDauBinning; + trackhistmanager::ConfCascadeBachelorBinning confBachelorBinning; + + // setup xis + cascadebuilder::ConfXiSelection confXiSelection; + cascadehistmanager::ConfXiBinning confXiBinning; + particlecleaner::ConfXiCleaner1 confXiCleaner; + particlecleaner::ConfTrackCleaner1 confTrackCleaner1; + particlecleaner::ConfTrackCleaner2 confTrackCleaner2; + + o2::framework::Partition xiPartition = MAKE_CASCADE_PARTITION(confXiSelection); + o2::framework::Preslice perColXis = o2::aod::femtobase::stored::fColId; + + o2::framework::Partition xiWithLabelPartition = MAKE_CASCADE_PARTITION(confXiSelection); + o2::framework::Preslice perColXisWithLabel = o2::aod::femtobase::stored::fColId; + + // setup omegas + cascadebuilder::ConfOmegaSelection confOmegaSelection; + cascadehistmanager::ConfOmegaBinning confOmegaBinning; + particlecleaner::ConfOmegaCleaner1 confOmegaCleaner; + + o2::framework::Partition omegaPartition = MAKE_CASCADE_PARTITION(confOmegaSelection); + o2::framework::Preslice perColOmegas = o2::aod::femtobase::stored::fColId; + + o2::framework::Partition omegaWithLabelPartition = MAKE_CASCADE_PARTITION(confOmegaSelection); + o2::framework::Preslice perColOmegasWithLabel = o2::aod::femtobase::stored::fColId; + + // setup triplets + triplethistmanager::ConfTripletBinning confTripletBinning; + triplethistmanager::ConfTripletCuts confTripletCuts; + + closetripletrejection::ConfCtrTrackTrackTrack confCtr; + + tripletbuilder::TripletTrackTrackCascadeBuilder< + modes::Cascade::kXi, + trackhistmanager::PrefixTrack1, + trackhistmanager::PrefixTrack2, + cascadehistmanager::PrefixXi, + trackhistmanager::PrefixCascadeBachelor, + trackhistmanager::PrefixCascadePosDaughter, + trackhistmanager::PrefixCascadeNegDaughter, + triplethistmanager::PrefixTrackTrackCascadeSe, + triplethistmanager::PrefixTrackTrackCascadeMe, + closetripletrejection::PrefixTrack1Track2Se, + closetripletrejection::PrefixTrack1CascadeBachelorSe, + closetripletrejection::PrefixTrack2CascadeBachelorSe, + closetripletrejection::PrefixTrack1V0DaughterSe, + closetripletrejection::PrefixTrack2V0DaughterSe, + closetripletrejection::PrefixTrack1Track2Me, + closetripletrejection::PrefixTrack1CascadeBachelorMe, + closetripletrejection::PrefixTrack2CascadeBachelorMe, + closetripletrejection::PrefixTrack1V0DaughterMe, + closetripletrejection::PrefixTrack2V0DaughterMe> + tripletTrackTrackXiBuilder; + + tripletbuilder::TripletTrackTrackCascadeBuilder< + modes::Cascade::kOmega, + trackhistmanager::PrefixTrack1, + trackhistmanager::PrefixTrack2, + cascadehistmanager::PrefixOmega, + trackhistmanager::PrefixCascadeBachelor, + trackhistmanager::PrefixCascadePosDaughter, + trackhistmanager::PrefixCascadeNegDaughter, + triplethistmanager::PrefixTrackTrackCascadeSe, + triplethistmanager::PrefixTrackTrackCascadeMe, + closetripletrejection::PrefixTrack1Track2Se, + closetripletrejection::PrefixTrack1CascadeBachelorSe, + closetripletrejection::PrefixTrack2CascadeBachelorSe, + closetripletrejection::PrefixTrack1V0DaughterSe, + closetripletrejection::PrefixTrack2V0DaughterSe, + closetripletrejection::PrefixTrack1Track2Me, + closetripletrejection::PrefixTrack1CascadeBachelorMe, + closetripletrejection::PrefixTrack2CascadeBachelorMe, + closetripletrejection::PrefixTrack1V0DaughterMe, + closetripletrejection::PrefixTrack2V0DaughterMe> + tripletTrackTrackOmegaBuilder; + + // setup mixing + std::vector defaultVtxBins{10, -10, 10}; + std::vector defaultMultBins{50, 0, 200}; + std::vector defaultCentBins{10, 0, 100}; + o2::framework::ColumnBinningPolicy mixBinsVtxMult{{defaultVtxBins, defaultMultBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxCent{{defaultVtxBins, defaultCentBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxMultCent{{defaultVtxBins, defaultMultBins, defaultCentBins}, true}; + triplethistmanager::ConfMixing confMixing; + + o2::framework::HistogramRegistry hRegistry{"FemtoTrackTrackCascade", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject}; + + // setup cpr + closepairrejection::ConfCprTrackCascadeBachelor confCprBachelor; + closepairrejection::ConfCprTrackV0Daughter confCprV0Daughter; + + void init(o2::framework::InitContext&) + { + if ((doprocessXiSameEvent + doprocessXiSameEventMc) > 1 || (doprocessXiMixedEvent + doprocessXiMixedEventMc) > 1 || (doprocessOmegaSameEvent + doprocessOmegaSameEventMc) > 1 || (doprocessOmegaMixedEvent + doprocessOmegaMixedEventMc) > 1) { + LOG(fatal) << "More than 1 same or mixed event process function is activated. Breaking..."; + } + bool processData = doprocessXiSameEvent || doprocessXiMixedEvent || doprocessOmegaSameEvent || doprocessOmegaMixedEvent; + bool processMc = doprocessXiSameEventMc || doprocessXiMixedEventMc || doprocessOmegaSameEventMc || doprocessOmegaMixedEventMc; + if (processData && processMc) { + LOG(fatal) << "Both data and mc processing is activated. Breaking..."; + } + + bool processXi = doprocessXiSameEvent || doprocessXiSameEventMc || doprocessXiMixedEvent || doprocessXiMixedEventMc; + bool processOmega = doprocessOmegaSameEvent || doprocessOmegaSameEventMc || doprocessOmegaMixedEvent || doprocessOmegaMixedEventMc; + + if (processXi && processOmega) { + LOG(fatal) << "Both xi-track and omega-track processing is enabled. Breaking..."; + } + + // 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 histogram specs + std::map> colHistSpec; + std::map> trackHistSpec1; + std::map> trackHistSpec2; + std::map> bachelorHistSpec; + + std::map> posDauSpec; + std::map> negDauSpec; + std::map> xiHistSpec; + std::map> omegaHistSpec; + std::map> tripletTrackTrackCascadeHistSpec; + + std::map> cprHistSpecBachelor = closepairrejection::makeCprHistSpecMap(confCprBachelor); + std::map> cprHistSpecV0Daughter = closepairrejection::makeCprHistSpecMap(confCprV0Daughter); + std::map> ctrHistSpec = closepairrejection::makeCprHistSpecMap(confCtr); + + if (processData) { + colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); + trackHistSpec1 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning1); + trackHistSpec2 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning2); + omegaHistSpec = cascadehistmanager::makeCascadeHistSpecMap(confOmegaBinning); + posDauSpec = trackhistmanager::makeTrackHistSpecMap(confPosDauBinning); + negDauSpec = trackhistmanager::makeTrackHistSpecMap(confNegDauBinning); + tripletTrackTrackCascadeHistSpec = triplethistmanager::makeTripletHistSpecMap(confTripletBinning); + + if (processXi) { + xiHistSpec = cascadehistmanager::makeCascadeHistSpecMap(confXiBinning); + tripletTrackTrackXiBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confTrackCleaner1, confCtr, confXiSelection, confXiCleaner, confCprBachelor, confCprV0Daughter, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, xiHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, tripletTrackTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter, ctrHistSpec); + } else { + omegaHistSpec = cascadehistmanager::makeCascadeHistSpecMap(confOmegaBinning); + tripletTrackTrackOmegaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confTrackCleaner1, confCtr, confOmegaSelection, confOmegaCleaner, confCprBachelor, confCprV0Daughter, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, omegaHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, tripletTrackTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter, ctrHistSpec); + } + } else { + colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); + trackHistSpec1 = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning1); + trackHistSpec2 = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning2); + bachelorHistSpec = trackhistmanager::makeTrackMcHistSpecMap(confBachelorBinning); + posDauSpec = trackhistmanager::makeTrackMcHistSpecMap(confPosDauBinning); + negDauSpec = trackhistmanager::makeTrackMcHistSpecMap(confNegDauBinning); + tripletTrackTrackCascadeHistSpec = triplethistmanager::makeTripletMcHistSpecMap(confTripletBinning); + if (processXi) { + xiHistSpec = cascadehistmanager::makeCascadeMcHistSpecMap(confXiBinning); + tripletTrackTrackXiBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confTrackCleaner1, confCtr, confXiSelection, confXiCleaner, confCprBachelor, confCprV0Daughter, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, xiHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, tripletTrackTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter, ctrHistSpec); + } else { + omegaHistSpec = cascadehistmanager::makeCascadeMcHistSpecMap(confOmegaBinning); + tripletTrackTrackOmegaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confTrackCleaner1, confCtr, confOmegaSelection, confOmegaCleaner, confCprBachelor, confCprV0Daughter, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, omegaHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, tripletTrackTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter, ctrHistSpec); + } + } + hRegistry.print(); + }; + + void processXiSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoXis const& /*xis*/) + { + tripletTrackTrackXiBuilder.processSameEvent(col, tracks, trackPartition1, trackPartition2, xiPartition, cache); + } + PROCESS_SWITCH(FemtoTripletTrackTrackCascade, processXiSameEvent, "Enable processing same event processing for tracks and xis", true); + + void processXiSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoXisWithLabel const& /*xis*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + { + tripletTrackTrackXiBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, xiWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); + } + PROCESS_SWITCH(FemtoTripletTrackTrackCascade, processXiSameEventMc, "Enable processing same event processing for tracks and xis with mc information", false); + + void processXiMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks, FemtoXis const& /*xis*/) + { + tripletTrackTrackXiBuilder.processMixedEvent(cols, tracks, trackPartition1, trackPartition2, xiPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + } + PROCESS_SWITCH(FemtoTripletTrackTrackCascade, processXiMixedEvent, "Enable processing mixed event processing for tracks and xis", true); + + void processXiMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoXisWithLabel const& /*xis*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& /*mcMothers*/, o2::aod::FMcPartMoths const& /*mcPartonicMothers*/) + { + tripletTrackTrackXiBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, xiWithLabelPartition, mcParticles, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + } + PROCESS_SWITCH(FemtoTripletTrackTrackCascade, processXiMixedEventMc, "Enable processing mixed event processing for tracks and xis with mc information", false); + + void processOmegaSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoOmegas const& /*omegas*/) + { + tripletTrackTrackOmegaBuilder.processSameEvent(col, tracks, trackPartition1, trackPartition2, omegaPartition, cache); + } + PROCESS_SWITCH(FemtoTripletTrackTrackCascade, processOmegaSameEvent, "Enable processing same event processing for tracks and omegas", false); + + void processOmegaSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoOmegasWithLabel const& /*omegas*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + { + tripletTrackTrackOmegaBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, omegaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); + } + PROCESS_SWITCH(FemtoTripletTrackTrackCascade, processOmegaSameEventMc, "Enable processing same event processing for tracks and omegas with mc information", false); + + void processOmegaMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks, FemtoOmegas const& /*omegas*/) + { + tripletTrackTrackOmegaBuilder.processMixedEvent(cols, tracks, trackPartition1, trackPartition2, omegaPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + } + PROCESS_SWITCH(FemtoTripletTrackTrackCascade, processOmegaMixedEvent, "Enable processing mixed event processing for tracks and omegas", false); + + void processOmegaMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoXisWithLabel const& /*xis*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& /*mcMothers*/, o2::aod::FMcPartMoths const& /*mcPartonicMothers*/) + { + tripletTrackTrackOmegaBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, omegaWithLabelPartition, mcParticles, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + } + PROCESS_SWITCH(FemtoTripletTrackTrackCascade, processOmegaMixedEventMc, "Enable processing mixed event processing for tracks and omegas with mc information", false); +}; + +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +{ + o2::framework::WorkflowSpec workflow{ + adaptAnalysisTask(cfgc), + }; + return workflow; +}