From 4a6f75aec97056c1d900f95a859802057d7cd296 Mon Sep 17 00:00:00 2001 From: Anton Riedel Date: Thu, 18 Sep 2025 13:18:15 +0200 Subject: [PATCH 1/4] Feat: general fixes --- PWGCF/Femto/Core/closePairRejection.h | 248 +++++++++++++ PWGCF/Femto/Core/collisionBuilder.h | 28 +- PWGCF/Femto/Core/collisionHistManager.h | 23 +- PWGCF/Femto/Core/dataTypes.h | 2 +- PWGCF/Femto/Core/pairCleaner.h | 107 ++++++ PWGCF/Femto/Core/pairHistManager.h | 215 ++++++++++++ PWGCF/Femto/Core/pairProcessHelpers.h | 331 ++++++++++++++++++ PWGCF/Femto/Core/partitions.h | 16 +- PWGCF/Femto/DataModel/FemtoTables.h | 30 +- PWGCF/Femto/Tasks/CMakeLists.txt | 18 +- PWGCF/Femto/Tasks/femtoCascadeQa.cxx | 6 +- PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx | 212 +++++++++++ PWGCF/Femto/Tasks/femtoPairTrackV0.cxx | 247 +++++++++++++ PWGCF/Femto/Tasks/femtoTrackQa.cxx | 5 +- .../Femto/Tasks/femtoTwotrackresonanceQa.cxx | 6 +- PWGCF/Femto/Tasks/femtoV0Qa.cxx | 4 +- 16 files changed, 1443 insertions(+), 55 deletions(-) create mode 100644 PWGCF/Femto/Core/closePairRejection.h create mode 100644 PWGCF/Femto/Core/pairCleaner.h create mode 100644 PWGCF/Femto/Core/pairHistManager.h create mode 100644 PWGCF/Femto/Core/pairProcessHelpers.h create mode 100644 PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx create mode 100644 PWGCF/Femto/Tasks/femtoPairTrackV0.cxx diff --git a/PWGCF/Femto/Core/closePairRejection.h b/PWGCF/Femto/Core/closePairRejection.h new file mode 100644 index 00000000000..b1bb7656b3a --- /dev/null +++ b/PWGCF/Femto/Core/closePairRejection.h @@ -0,0 +1,248 @@ +// Copyright 2019-2022 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 closePairRejection.h +/// \brief Definition of ClosePairRejection class +/// \author Anton Riedel, TU München, anton.riedel@tum.de + +#ifndef PWGCF_FEMTO_CORE_CLOSEPAIRREJECTION_H_ +#define PWGCF_FEMTO_CORE_CLOSEPAIRREJECTION_H_ + +#include "PWGCF/Femto/Core/dataTypes.h" +#include "PWGCF/Femto/Core/femtoUtils.h" +#include "PWGCF/Femto/Core/histManager.h" +#include "PWGCF/Femto/Core/modes.h" +#include "PWGCF/Femto/DataModel/FemtoTables.h" + +#include "Framework/HistogramRegistry.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace o2::analysis::femto +{ +namespace closepairrejection +{ +// enum for track histograms +enum CprHist { + // kinemtics + kAverage, + kRadius0, + kRadius1, + kRadius2, + kRadius3, + kRadius4, + kRadius5, + kRadius6, + kRadius7, + kRadius8, + kCprHistogramLast +}; + +struct ConfCpr : o2::framework::ConfigurableGroup { + std::string prefix = std::string("ClosePairRejection"); + o2::framework::Configurable on{"on", true, "Turn on CPR"}; + o2::framework::Configurable detaMax{"detaMax", 0.01f, "Maximium deta"}; + o2::framework::Configurable dphistarMax{"dphistarMax", 0.01f, "Maximum dphistar"}; + o2::framework::ConfigurableAxis binningDeta{"binningDeta", {{200, -0.2, 0.2}}, "deta"}; + o2::framework::ConfigurableAxis binningDphistar{"binningDphistar", {{200, -0.2, 0.2}}, "dphi"}; +}; + +// tpc radii for computing phistar +constexpr int kNradii = 9; +constexpr std::array kTpcRadius = {85., 105., 125., 145., 165., 185., 205., 225., 245.}; + +// directory names +constexpr char PrefixTrackTrackSe[] = "CPR_TrackTrack/SE/"; +constexpr char PrefixTrackTrackMe[] = "CPR_TrackTrack/ME/"; +constexpr char PrefixTrackPosDauSe[] = "CPR_TrackPosDau/SE/"; +constexpr char PrefixTrackNegDauSe[] = "CPR_TrackNegDau/SE/"; +constexpr char PrefixTrackPosDauMe[] = "CPR_TrackPosDau/ME/"; +constexpr char PrefixTrackNegDauMe[] = "CPR_TrackNegDau/ME/"; + +// must be in sync with enum TrackVariables +// the enum gives the correct index in the array +constexpr std::array, kCprHistogramLast> HistTable = { + {{kAverage, o2::framework::kTH2F, "hAverage", "#Delta #eta vs #Delta #phi* (averaged over all radii); #Delta #eta; #Delta #phi*"}, + {kRadius0, o2::framework::kTH2F, "hRadius0", "Radius 0: #Delta #eta vs #Delta #phi*; #Delta #eta; #Delta #phi*"}, + {kRadius1, o2::framework::kTH2F, "hRadius1", "Radius 1: #Delta #eta vs #Delta #phi*; #Delta #eta; #Delta #phi*"}, + {kRadius2, o2::framework::kTH2F, "hRadius2", "Radius 2: #Delta #eta vs #Delta #phi*; #Delta #eta; #Delta #phi*"}, + {kRadius3, o2::framework::kTH2F, "hRadius3", "Radius 3: #Delta #eta vs #Delta #phi*; #Delta #eta; #Delta #phi*"}, + {kRadius4, o2::framework::kTH2F, "hRadius4", "Radius 4: #Delta #eta vs #Delta #phi*; #Delta #eta; #Delta #phi*"}, + {kRadius5, o2::framework::kTH2F, "hRadius5", "Radius 5: #Delta #eta vs #Delta #phi*; #Delta #eta; #Delta #phi*"}, + {kRadius6, o2::framework::kTH2F, "hRadius6", "Radius 6: #Delta #eta vs #Delta #phi*; #Delta #eta; #Delta #phi*"}, + {kRadius7, o2::framework::kTH2F, "hRadius7", "Radius 7: #Delta #eta vs #Delta #phi*; #Delta #eta; #Delta #phi*"}, + {kRadius8, o2::framework::kTH2F, "hRadius8", "Radius 8: #Delta #eta vs #Delta #phi*; #Delta #eta; #Delta #phi*"}}}; + +template +auto makeCprHistSpecMap(const T& confCpr) +{ + std::map> specs; + for (int i = 0; i < kCprHistogramLast; ++i) { + specs[static_cast(i)] = {confCpr.binningDeta, confCpr.binningDphistar}; + } + return specs; +}; + +template +class CloseTrackRejection +{ + public: + CloseTrackRejection() {} + + void init(o2::framework::HistogramRegistry* registry, std::map>& specs, float detaMax, float dphistarMax) + { + mHistogramRegistry = registry; + mDetaMax = detaMax; + mDphistarMax = dphistarMax; + + for (int i = 0; i < kCprHistogramLast; ++i) { + auto hist = static_cast(i); + mHistogramRegistry->add(std::string(prefix) + GetHistNamev2(hist, HistTable), GetHistDesc(hist, HistTable), GetHistType(hist, HistTable), {specs.at(hist)}); + } + } + + void setMagField(float magField) { mMagField = magField; } + + void reset() + { + mSameCharge = false; + mAverageDphistar = 0.f; + mDeta = 0.f; + mDphistar.fill(0.f); + } + + template + void compute(const T1& track1, const T2& track2) + { + reset(); + if (track1.sign() != track2.sign()) { + return; + } + mSameCharge = true; + mDeta = track1.eta() - track2.eta(); + for (size_t i = 0; i < kTpcRadius.size(); ++i) { + auto phistar1 = utils::dphistar(mMagField, kTpcRadius[i], track1.sign(), track1.pt(), track1.phi()); + auto phistar2 = utils::dphistar(mMagField, kTpcRadius[i], track2.sign(), track2.pt(), track2.phi()); + + if (phistar1 && phistar2) { + // if the calculation for one phistar fails, keep the default value, which is 0 + // this makes it more likelier for the pair to be rejected sind the averave will be biased towards lower values + mDphistar[i] = phistar1.value() - phistar2.value(); + } + } + mAverageDphistar = std::accumulate(mDphistar.begin(), mDphistar.end(), 0.f) / mDphistar.size(); + } + + void fill() + { + // fill average hist + mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(kAverage, HistTable)), mDeta, mAverageDphistar); + + // fill radii hists + for (int i = 0; i < kNradii; ++i) { + mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(static_cast(kRadius0 + 1), HistTable)), mDeta, mDphistar.at(i)); + } + } + + bool isClosePair() const + { + if (!mSameCharge) { + return false; + } else { + return ((mAverageDphistar * mAverageDphistar) / (mDphistarMax * mDphistarMax) + (mDeta * mDeta) / (mDetaMax * mDetaMax)) < 1.f; + } + } + + private: + float mMagField = 0.f; + float mAverageDphistar = 0.f; + bool mSameCharge = false; + float mDeta = 0.f; + float mDetaMax = 0.f; + float mDphistarMax = 0.f; + std::array mDphistar = {}; + + o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; +}; + +template +class ClosePairRejectionTrackTrack +{ + public: + void init(o2::framework::HistogramRegistry* registry, std::map>& specs, float detaMax, float dphistarMax, bool isActivated) + { + mIsActivated = isActivated; + mCtr.init(registry, specs, detaMax, dphistarMax); + } + + void setMagField(float magField) { mCtr.setMagField(magField); } + template + void setPair(const T1& track1, const T2& track2) + { + mCtr.compute(track1, track2); + } + bool isClosePair() const { return mCtr.isClosePair(); } + void fill() { mCtr.fill(); } + bool isActivated() const { return mIsActivated; } + + private: + CloseTrackRejection mCtr; + bool mIsActivated = true; +}; + +template +class ClosePairRejectionTrackV0 // can also be used for any particle type that has pos/neg daughters, like resonances +{ + public: + void init(o2::framework::HistogramRegistry* registry, std::map>& specs, float detaMax, float dphistarMax, bool isActivated) + { + mIsActivated = isActivated; + mCtrPosDau.init(registry, specs, detaMax, dphistarMax); + mCtrNegDau.init(registry, specs, detaMax, dphistarMax); + } + + void setMagField(float magField) + { + mCtrPosDau.setMagField(magField); + mCtrNegDau.setMagField(magField); + } + template + void setPair(const T1& track, const T2& v0, const T3 /*trackTable*/) + { + auto posDaughter = v0.template posDau_as(); + auto negDaughter = v0.template negDau_as(); + mCtrPosDau.compute(track, posDaughter); + mCtrNegDau.compute(track, negDaughter); + } + bool isClosePair() const { return mCtrPosDau.isClosePair() || mCtrNegDau.isClosePair(); } + void fill() + { + mCtrPosDau.fill(); + mCtrNegDau.fill(); + } + bool isActivated() const { return mIsActivated; } + + private: + CloseTrackRejection mCtrPosDau; + CloseTrackRejection mCtrNegDau; + bool mIsActivated = true; +}; + +}; // namespace closepairrejection +}; // namespace o2::analysis::femto +#endif // PWGCF_FEMTO_CORE_CLOSEPAIRREJECTION_H_ diff --git a/PWGCF/Femto/Core/collisionBuilder.h b/PWGCF/Femto/Core/collisionBuilder.h index b33619dcf6f..b7ebf38824b 100644 --- a/PWGCF/Femto/Core/collisionBuilder.h +++ b/PWGCF/Femto/Core/collisionBuilder.h @@ -17,6 +17,7 @@ #define PWGCF_FEMTO_CORE_COLLISIONBUILDER_H_ #include "PWGCF/Femto/Core/baseSelection.h" +#include "PWGCF/Femto/Core/dataTypes.h" #include "PWGCF/Femto/Core/femtoUtils.h" #include "PWGCF/Femto/Core/modes.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" @@ -79,6 +80,24 @@ struct ConfCollisionTriggers : o2::framework::ConfigurableGroup { o2::framework::Configurable triggers{"triggers", std::string("fPPP,fPPL"), "Comma seperated list of all triggers to be used"}; }; +// configurables for collision selection +struct ConfCollisionSelection : o2::framework::ConfigurableGroup { + std::string prefix = std::string("CollisionSelection"); + o2::framework::Configurable vtxZMin{"vtxZMin", -10.f, "Minimum vertex Z position (cm)"}; + o2::framework::Configurable vtxZMax{"vtxZMax", 10.f, "Maximum vertex Z position (cm)"}; + o2::framework::Configurable multMin{"multMin", 0.f, "Minimum multiplicity"}; + o2::framework::Configurable multMax{"multMax", 999.f, "Maximum multiplicity"}; + o2::framework::Configurable centMin{"centMin", 0.f, "Minimum centrality (multiplicity percentile)"}; + o2::framework::Configurable centMax{"centMax", 999.f, "Maximum centrality (multiplicity percentile)"}; + o2::framework::Configurable spherMin{"spherMin", 0.f, "Minimum centrality (multiplicity percentile)"}; + o2::framework::Configurable spherMax{"spherMax", 2.f, "Maximum centrality (multiplicity percentile)"}; + o2::framework::Configurable magFieldMin{"magFieldMin", -1.f, "Minimum magnetic field strength (T)"}; + o2::framework::Configurable magFieldMax{"magFieldMax", 1.f, "Maximum magnetic field strength (T)"}; + o2::framework::Configurable occupancyMin{"occupancyMin", 0.f, "Minimum occupancy (Optional)"}; + o2::framework::Configurable occupancyMax{"occupancyMax", 1e6f, "Maximum occupancy (Optional)"}; + o2::framework::Configurable collisionMask{"collisionMask", 0, "Bitmask for collision (Optional)"}; +}; + /// enum for all collision selections enum CollisionSels { // collsion selection flags @@ -115,7 +134,7 @@ const std::unordered_map colSelsToString = { {kIsGoodItsLayer0123, "Is good ITS layer 0-3"}, {kIsGoodItsLayersAll, "Is good ITS layer all"}}; -class CollisionSelection : public BaseSelection +class CollisionSelection : public BaseSelection { public: CollisionSelection() {} @@ -267,7 +286,7 @@ class CollisionSelection : public BaseSelection producedCollision; - o2::framework::Produces produceCollisionMask; + o2::framework::Produces producedCollisionMask; o2::framework::Produces producedOccupancy; o2::framework::Produces producedQns; o2::framework::Produces producedPositions; @@ -356,11 +375,12 @@ class CollisionBuilder mCollisionSelection.getSphericity(), mCollisionSelection.getMagneticField()); } - + if (mProducedCollisionMasks) { + collisionProducts.producedCollisionMask(mCollisionSelection.getBitmask()); + } if (mProduceOccupancy) { collisionProducts.producedOccupancy(col.trackOccupancyInTimeRange()); } - if (mProducedPositions) { collisionProducts.producedPositions(col.posX(), col.posY()); diff --git a/PWGCF/Femto/Core/collisionHistManager.h b/PWGCF/Femto/Core/collisionHistManager.h index 83c9d1ef64b..35daec9fa3a 100644 --- a/PWGCF/Femto/Core/collisionHistManager.h +++ b/PWGCF/Femto/Core/collisionHistManager.h @@ -35,12 +35,17 @@ namespace colhistmanager { enum ColHist { - kPosz, + kPosZ, kMult, kCent, kMagField, kSphericity, - // 2d qa + // qa + kPosX, + kPosY, + kPos, + kOccupancy, + // 2d kPoszVsMult, kPoszVsCent, kCentVsMult, @@ -54,11 +59,15 @@ constexpr std::string_view ColQaDir = "Collisions/QA/"; constexpr std::array, kColHistLast> HistTable = { { - {kPosz, o2::framework::kTH1F, "hPosz", "Vertex Z; V_{Z} (cm); Entries"}, + {kPosZ, o2::framework::kTH1F, "hPosZ", "Vertex Z; V_{Z} (cm); Entries"}, {kMult, o2::framework::kTH1F, "hMult", "Multiplicity; Multiplicity; Entries"}, {kCent, o2::framework::kTH1F, "hCent", "Centrality; Centrality (%); Entries"}, {kMagField, o2::framework::kTH1F, "hMagField", "Magnetic Field; B (T); Entries"}, {kSphericity, o2::framework::kTH1F, "hSphericity", "Sphericity; Sphericity; Entries"}, + {kPosX, o2::framework::kTH1F, "hPosX", "Vertex X; V_{X} (cm); Entries"}, + {kPosY, o2::framework::kTH1F, "hPosY", "Vertex Z; V_{Y} (cm); Entries"}, + {kPos, o2::framework::kTH1F, "hPos", "Primary vertex; V_{pos} (cm); Entries"}, + {kOccupancy, o2::framework::kTH1F, "hOccupancy", "Occupancy; Occupancy; Entries"}, {kPoszVsMult, o2::framework::kTH2F, "hPoszVsMult", "Vertex Z vs Multiplicity; V_{Z} (cm); Multiplicity"}, {kPoszVsCent, o2::framework::kTH2F, "hPoszVsCent", "Vertex Z vs Centrality; V_{Z} (cm); Centrality (%)"}, {kCentVsMult, o2::framework::kTH2F, "hCentVsMult", "Centrality vs Multiplicity; Centrality (%); Multiplicity"}, @@ -70,7 +79,7 @@ template auto makeColHistSpecMap(const BinningStruct& binning) { return std::map>{ - {kPosz, {binning.vtZ}}, + {kPosZ, {binning.vtZ}}, {kMult, {binning.mult}}, {kCent, {binning.cent}}, {kSphericity, {binning.spher}}, @@ -91,8 +100,6 @@ struct ConfCollisionBinning : o2::framework::ConfigurableGroup { o2::framework::ConfigurableAxis magField{"magField", {2, -1, 1}, "Magnetic field binning"}; }; -/// \class FemtoDreamEventHisto -/// \brief Class for histogramming event properties template class CollisionHistManager { @@ -106,7 +113,7 @@ class CollisionHistManager mHistogramRegistry = registry; if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { std::string analysisDir = std::string(ColAnalysisDir); - mHistogramRegistry->add(analysisDir + GetHistNamev2(kPosz, HistTable), GetHistDesc(kPosz, HistTable), GetHistType(kPosz, HistTable), {Specs[kPosz]}); + mHistogramRegistry->add(analysisDir + GetHistNamev2(kPosZ, HistTable), GetHistDesc(kPosZ, HistTable), GetHistType(kPosZ, HistTable), {Specs[kPosZ]}); mHistogramRegistry->add(analysisDir + GetHistNamev2(kMult, HistTable), GetHistDesc(kMult, HistTable), GetHistType(kMult, HistTable), {Specs[kMult]}); mHistogramRegistry->add(analysisDir + GetHistNamev2(kCent, HistTable), GetHistDesc(kCent, HistTable), GetHistType(kCent, HistTable), {Specs[kCent]}); mHistogramRegistry->add(analysisDir + GetHistNamev2(kSphericity, HistTable), GetHistDesc(kSphericity, HistTable), GetHistType(kSphericity, HistTable), {Specs[kSphericity]}); @@ -128,7 +135,7 @@ class CollisionHistManager void fill(T const& col) { if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { - mHistogramRegistry->fill(HIST(ColAnalysisDir) + HIST(GetHistName(kPosz, HistTable)), col.posZ()); + mHistogramRegistry->fill(HIST(ColAnalysisDir) + HIST(GetHistName(kPosZ, HistTable)), col.posZ()); mHistogramRegistry->fill(HIST(ColAnalysisDir) + HIST(GetHistName(kMult, HistTable)), col.mult()); mHistogramRegistry->fill(HIST(ColAnalysisDir) + HIST(GetHistName(kCent, HistTable)), col.cent()); mHistogramRegistry->fill(HIST(ColAnalysisDir) + HIST(GetHistName(kSphericity, HistTable)), col.sphericity()); diff --git a/PWGCF/Femto/Core/dataTypes.h b/PWGCF/Femto/Core/dataTypes.h index f8e349a77d3..f1c317fae73 100644 --- a/PWGCF/Femto/Core/dataTypes.h +++ b/PWGCF/Femto/Core/dataTypes.h @@ -25,7 +25,7 @@ namespace femtodatatypes // Note: Length of the bitmask is the limit of how many selections can be configured // datatypes for collsions -using CollsionsMaskType = uint64_t; +using CollisionMaskType = uint16_t; // datatypes for tracks using TrackMaskType = uint64_t; diff --git a/PWGCF/Femto/Core/pairCleaner.h b/PWGCF/Femto/Core/pairCleaner.h new file mode 100644 index 00000000000..d613db5971a --- /dev/null +++ b/PWGCF/Femto/Core/pairCleaner.h @@ -0,0 +1,107 @@ +// Copyright 2019-2022 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 pairCleaner.h +/// \brief pair cleaner class +/// \author anton.riedel@tum.de, TU München, anton.riedel@tum.de + +#ifndef PWGCF_FEMTO_CORE_PAIRCLEANER_H_ +#define PWGCF_FEMTO_CORE_PAIRCLEANER_H_ + +#include "PWGCF/Femto/Core/dataTypes.h" +#include "PWGCF/Femto/Core/histManager.h" +#include "PWGCF/Femto/Core/modes.h" +#include "PWGCF/Femto/DataModel/FemtoTables.h" + +namespace o2::analysis::femto +{ +namespace paircleaner +{ + +class BasePairCleaner +{ + public: + BasePairCleaner() = default; + virtual ~BasePairCleaner() = default; + + protected: + template + bool isCleanTrackPair(const T1& track1, const T2& track2) const + { + return track1.globalIndex() != track2.globalIndex(); + }; +}; + +class TrackTrackPairCleaner : public BasePairCleaner +{ + public: + TrackTrackPairCleaner() = default; + template + bool isCleanPair(const T& track1, const T& track2) const + { + return this->isCleanTrackPair(track1, track2); + } +}; + +class TrackV0PairCleaner : public BasePairCleaner +{ + public: + TrackV0PairCleaner() = default; + template + bool isCleanPair(const T1& track, const T2& v0, const T3& /*trackTable */) const + { + auto posDaughter = v0.template posDau_as(); + auto negDaughter = v0.template negDau_as(); + return this->isCleanTrackPair(posDaughter, track) && this->isCleanTrackPair(negDaughter, track); + } +}; + +// template +// template +// class PairCleaner +// { +// public: +// /// Destructor +// virtual ~PairCleaner() = default; +// +// template +// bool isCleanPair(const T1& particle1, const T2& particle2) +// { +// if constexpr (modes::isEqual(pair, modes::Pairs::kTrackTrack)) { +// return particle1.globalIndex() != particle2.globalIndex(); +// } +// return true; +// }; +// +// template +// bool isCleanPair(const T1& particle1, const T2& particle2, const T3& /*trackTable*/) +// { +// if constexpr (modes::isEqual(pair, modes::Pairs::kTrackV0) || modes::isEqual(pair, modes::Pairs::kTrackResonance)) { +// auto posDaughter = particle2.template posDau_as(); +// auto negDaughter = particle2.template negDau_as(); +// return (particle1.globalIndex() != posDaughter.globalIndex() && particle1.globalIndex() != negDaughter.globalIndex()); +// } +// if constexpr (modes::isEqual(pair, modes::Pairs::kTrackCascade)) { +// auto posDaughter = particle2.template posDau_as(); +// auto negDaughter = particle2.template negDau_as(); +// auto bachelor = particle2.template bachelor_as(); +// return (particle1.globalIndex() != posDaughter.globalIndex() && +// particle1.globalIndex() != negDaughter.globalIndex() && +// particle1.globalIndex() != bachelor.globalIndex()); +// } +// return true; +// }; +// +// private: +// }; +}; // namespace paircleaner +}; // namespace o2::analysis::femto +#endif // PWGCF_FEMTOUNITED_CORE_PAIRCLEANER_H_ diff --git a/PWGCF/Femto/Core/pairHistManager.h b/PWGCF/Femto/Core/pairHistManager.h new file mode 100644 index 00000000000..7c4546adbb9 --- /dev/null +++ b/PWGCF/Femto/Core/pairHistManager.h @@ -0,0 +1,215 @@ +// 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 pairHistManager.h +/// \brief histogram manager for pair tasks +/// \author anton.riedel@tum.de, TU München, anton.riedel@tum.de + +#ifndef PWGCF_FEMTO_CORE_PAIRHISTMANAGER_H_ +#define PWGCF_FEMTO_CORE_PAIRHISTMANAGER_H_ + +#include "PWGCF/Femto/Core/femtoUtils.h" +#include "PWGCF/Femto/Core/histManager.h" +#include "PWGCF/Femto/Core/modes.h" +#include "PWGCF/Femto/DataModel/FemtoTables.h" + +#include "Framework/Configurable.h" +#include "Framework/GroupedCombinations.h" +#include "Framework/HistogramRegistry.h" + +#include "Math/Boost.h" +#include "Math/Vector4D.h" +#include "TMath.h" + +#include +#include +#include +#include +#include + +namespace o2::analysis::femto +{ +namespace pairhistmanager +{ +// enum for pair histograms +enum PairHist { + // kinemtics + kKstar, + kKt, + kMt, + // 2d qa + kPt1VsPt2, + kPt1VsKstar, + kPt2VsKstar, + kPt1VsKt, + kPt2VsKt, + kPt1VsMt, + kPt2VsMt, + kPairHistogramLast +}; + +enum MixingPoliciy { + kVtxMult, + kVtxCent, + kVtxMultCent, + kMixingPolicyLast +}; + +// Mixing configurables +struct ConfMixing : o2::framework::ConfigurableGroup { + std::string prefix = std::string("Mixing"); + o2::framework::ConfigurableAxis multBins{"multBins", {o2::framework::VARIABLE_WIDTH, 0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f, 40.0f, 44.0f, 48.0f, 52.0f, 56.0f, 60.0f, 64.0f, 68.0f, 72.0f, 76.0f, 80.0f, 84.0f, 88.0f, 92.0f, 96.0f, 100.0f, 200.0f}, "Mixing bins - multiplicity"}; + o2::framework::ConfigurableAxis centBins{"centBins", {o2::framework::VARIABLE_WIDTH, 0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f}, "Mixing bins - centrality"}; + o2::framework::ConfigurableAxis vtxBins{"vtxBins", {o2::framework::VARIABLE_WIDTH, -10.0f, -8.f, -6.f, -4.f, -2.f, 0.f, 2.f, 4.f, 6.f, 8.f, 10.f}, "Mixing bins - z-vertex"}; + o2::framework::Configurable depth{"depth", 5, "Number of events for mixing"}; + o2::framework::Configurable policy{"policy", 0, "Binning policy for mixing (alywas in combination with z-vertex) -> 0: multiplicity, -> 1: centrality, -> 2: both"}; + o2::framework::Configurable sameSpecies{"sameSpecies", false, "Enable if partilce 1 and particle 2 are the same"}; + o2::framework::Configurable seed{"seed", -1, "Seed to randomize particle 1 and particle 2 (if they are identical). Set to negative value to deactivate. Set to 0 to generate unique seed in time."}; +}; + +struct ConfPairBinning : o2::framework::ConfigurableGroup { + std::string prefix = std::string("PairBinning"); + o2::framework::ConfigurableAxis kstar{"kstar", {{600, 0, 6}}, "kstar"}; + o2::framework::ConfigurableAxis kt{"kt", {{600, 0, 6}}, "kt"}; + o2::framework::ConfigurableAxis mt{"mt", {{500, 0.8, 5.8}}, "mt"}; +}; + +// the enum gives the correct index in the array +constexpr std::array, kPairHistogramLast> HistTable = { + {{kKstar, o2::framework::kTH1F, "hKstar", "k*; k* (GeV/#it{c}); Entries"}, + {kKt, o2::framework::kTH1F, "hKt", "transverse momentum; k_{T} (GeV/#it{c}); Entries"}, + {kMt, o2::framework::kTH1F, "hMt", "transverse mass; m_{T} (GeV/#it{c}^{2}); Entries"}, + {kPt1VsPt2, o2::framework::kTH2F, "hPt1VsPt2", "track1 p_{T} vs track2 p_{T}; track1 p_T (GeV/#it{c}); track2 p_{T} (GeV/#it{c})"}, + {kPt1VsKstar, o2::framework::kTH2F, "hPt1VsKstar", "p_{T,1} vs k*; p_{T,2} (GeV/#it{c}); k* (GeV/#it{c})"}, + {kPt2VsKstar, o2::framework::kTH2F, "hPt2VsKstar", "p_{T,2} vs k*; p_{T,2} (GeV/#it{c}); k* (GeV/#it{c})"}, + {kPt1VsKt, o2::framework::kTH2F, "hPt1VsKt", "p_{T,1} vs k_{T}; p_{T,1} (GeV/#it{c}); k_{T} (GeV/#it{c})"}, + {kPt2VsKt, o2::framework::kTH2F, "hPt2VsKt", "p_{T,2} vs k_{T}; p_{T,2} (GeV/#it{c}); k_{T} (GeV/#it{c})"}, + {kPt1VsMt, o2::framework::kTH2F, "hPt1VsMt", "p_{T,1} vs m_{T}; p_{T,1} (GeV/#it{c}); m_{T} (GeV/#it{c})"}, + {kPt2VsMt, o2::framework::kTH2F, "hPt2VsMt", "p_{T,2} vs m_{T}; p_{T,2} (GeV/#it{c}); m_{T} (GeV/#it{c})"}}}; + +template +auto makePairHistSpecMap(const T1& confPairBinning, const T2& confObject1Binning, const T3& confObject2Binning) +{ + return std::map>{ + {kKstar, {confPairBinning.kstar}}, + {kKt, {confPairBinning.kt}}, + {kMt, {confPairBinning.mt}}, + {kPt1VsPt2, {confObject1Binning.pt, confObject2Binning.pt}}, + {kPt1VsKstar, {confObject1Binning.pt, confPairBinning.kstar}}, + {kPt2VsKstar, {confObject2Binning.pt, confPairBinning.kstar}}, + {kPt1VsKt, {confObject1Binning.pt, confPairBinning.kt}}, + {kPt2VsKt, {confObject2Binning.pt, confPairBinning.kt}}, + {kPt1VsMt, {confObject1Binning.pt, confPairBinning.mt}}, + {kPt2VsMt, {confObject2Binning.pt, confPairBinning.mt}}}; +}; + +constexpr char PrefixTrackTrackSe[] = "TrackTrack/SE/"; +constexpr char PrefixTrackTrackMe[] = "TrackTrack/ME/"; + +constexpr char PrefixTrackV0Se[] = "TrackV0/SE/"; +constexpr char PrefixTrackV0Me[] = "TrackV0/ME/"; + +constexpr std::string_view AnalysisDir = "Analysis/"; +constexpr std::string_view QaDir = "QA/"; + +/// \class FemtoDreamEventHisto +/// \brief Class for histogramming event properties +// template +template +class PairHistManager +{ + public: + /// Destructor + virtual ~PairHistManager() = default; + /// Initializes histograms for the task + /// \param registry Histogram registry to be passed + /// + void init(o2::framework::HistogramRegistry* registry, std::map> Specs) + { + mHistogramRegistry = registry; + + if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { + std::string analysisDir = std::string(prefix) + std::string(AnalysisDir); + + mHistogramRegistry->add(analysisDir + GetHistNamev2(kKstar, HistTable), GetHistDesc(kKstar, HistTable), GetHistType(kKstar, HistTable), {Specs[kKstar]}); + mHistogramRegistry->add(analysisDir + GetHistNamev2(kMt, HistTable), GetHistDesc(kMt, HistTable), GetHistType(kMt, HistTable), {Specs[kMt]}); + mHistogramRegistry->add(analysisDir + GetHistNamev2(kPt1VsPt2, HistTable), GetHistDesc(kPt1VsPt2, HistTable), GetHistType(kPt1VsPt2, HistTable), {Specs[kPt1VsPt2]}); + mHistogramRegistry->add(analysisDir + GetHistNamev2(kPt1VsKstar, HistTable), GetHistDesc(kPt1VsKstar, HistTable), GetHistType(kPt1VsKstar, HistTable), {Specs[kPt1VsKstar]}); + mHistogramRegistry->add(analysisDir + GetHistNamev2(kPt2VsKstar, HistTable), GetHistDesc(kPt2VsKstar, HistTable), GetHistType(kPt2VsKstar, HistTable), {Specs[kPt2VsKstar]}); + mHistogramRegistry->add(analysisDir + GetHistNamev2(kPt1VsKt, HistTable), GetHistDesc(kPt1VsKt, HistTable), GetHistType(kPt1VsKt, HistTable), {Specs[kPt1VsKt]}); + mHistogramRegistry->add(analysisDir + GetHistNamev2(kPt2VsKt, HistTable), GetHistDesc(kPt2VsKt, HistTable), GetHistType(kPt2VsKt, HistTable), {Specs[kPt2VsKt]}); + mHistogramRegistry->add(analysisDir + GetHistNamev2(kPt1VsMt, HistTable), GetHistDesc(kPt1VsMt, HistTable), GetHistType(kPt1VsMt, HistTable), {Specs[kPt1VsMt]}); + mHistogramRegistry->add(analysisDir + GetHistNamev2(kPt2VsMt, HistTable), GetHistDesc(kPt2VsMt, HistTable), GetHistType(kPt2VsMt, HistTable), {Specs[kPt2VsMt]}); + } + + // if constexpr (isFlagSet(mode, modes::Mode::kQA)) { + // std::string qaDir = std::string(prefix) + std::string(QaDir); + // } + } + + void setMass(int PdgParticle1, int PdgParticle2) + { + mMass1 = o2::analysis::femto::utils::getMass(PdgParticle1); + mMass2 = o2::analysis::femto::utils::getMass(PdgParticle2); + } + + template + void setPair(const T1& particle1, const T2& particle2) + { + mTrack1 = ROOT::Math::PtEtaPhiMVector{particle1.pt(), particle1.eta(), particle1.phi(), mMass1}; + mTrack2 = ROOT::Math::PtEtaPhiMVector{particle2.pt(), particle2.eta(), particle2.phi(), mMass2}; + auto partSum = mTrack1 + mTrack2; + + // set kT + mKt = partSum.Pt(); + + // set mT + float averageMass = (mMass1 + mMass2) / 2.; + mMt = std::hypot(mKt, averageMass); + + // Boost Track1 to the pair rest frame and calculate k* + auto track1 = ROOT::Math::PxPyPzEVector(mTrack1); + ROOT::Math::Boost boostPrf(partSum.BoostToCM()); + mKstar = boostPrf(track1).P(); + } + + void fill() + { + if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { + mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kKstar, HistTable)), mKstar); + mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kMt, HistTable)), mMt); + mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt1VsPt2, HistTable)), mTrack1.Pt(), mTrack2.Pt()); + mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt1VsKstar, HistTable)), mTrack1.Pt(), mKstar); + mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt1VsMt, HistTable)), mTrack1.Pt(), mMt); + mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt1VsKt, HistTable)), mTrack1.Pt(), mKt); + mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt2VsKstar, HistTable)), mTrack2.Pt(), mKstar); + mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt2VsMt, HistTable)), mTrack2.Pt(), mMt); + mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt2VsKt, HistTable)), mTrack2.Pt(), mKt); + } + + // if constexpr (isFlagSet(mode, modes::Mode::kQA)) { + // mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kPtVsDcaz, HistTable)), track.pt(), track.dcaZ()); + // } + } + + private: + o2::framework::HistogramRegistry* mHistogramRegistry; + float mMass1 = 0.f; + float mMass2 = 0.f; + ROOT::Math::PtEtaPhiMVector mTrack1{}; + ROOT::Math::PtEtaPhiMVector mTrack2{}; + float mKstar = 0.f; + float mKt = 0.f; + float mMt = 0.f; +}; +}; // namespace pairhistmanager +}; // namespace o2::analysis::femto +#endif // PWGCF_FEMTO_CORE_PAIRHISTMANAGER_H_ diff --git a/PWGCF/Femto/Core/pairProcessHelpers.h b/PWGCF/Femto/Core/pairProcessHelpers.h new file mode 100644 index 00000000000..d0519b60d00 --- /dev/null +++ b/PWGCF/Femto/Core/pairProcessHelpers.h @@ -0,0 +1,331 @@ +// 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 pairProcessHelpers.h +/// \brief process functions used in pair tasks +/// \author anton.riedel@tum.de, TU München, anton.riedel@tum.de + +#ifndef PWGCF_FEMTO_CORE_PAIRPROCESSHELPERS_H_ +#define PWGCF_FEMTO_CORE_PAIRPROCESSHELPERS_H_ + +#include "PWGCF/Femto/Core/femtoUtils.h" +#include "PWGCF/Femto/Core/histManager.h" +#include "PWGCF/Femto/Core/modes.h" +#include "PWGCF/Femto/DataModel/FemtoTables.h" + +#include "Framework/ASoAHelpers.h" + +#include + +namespace o2::analysis::femto +{ +namespace pairprocesshelpers +{ + +// process same event for identical tracks +template +void processSameEvent(const T1& SliceParticle, + T2& ParticleHistManager, + T3& PairHistManager, + T4& CprManager, + T5& rng, + bool randomize) +{ + // Fill single particle histograms + for (auto const& part : SliceParticle) { + ParticleHistManager.fill(part); + } + + std::uniform_real_distribution dist(0.f, 1.f); + + for (auto const& [p1, p2] : o2::soa::combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(SliceParticle, SliceParticle))) { + + // Close pair rejection + if (CprManager.isActivated()) { + CprManager.setPair(p1, p2); + if (CprManager.isClosePair()) { + continue; + } + } + CprManager.fill(); + + // Randomize pair order if enabled + float threshold = 0.5f; + bool swapPair = randomize ? (dist(rng) > threshold) : false; + if (swapPair) { + PairHistManager.setPair(p2, p1); + } else { + PairHistManager.setPair(p1, p2); + } + PairHistManager.fill(); + } +} + +// process same event for non-identical tracks +template +void processSameEvent(const T1& SliceParticle1, + const T2& SliceParticle2, + T3& ParticleHistManager1, + T4& ParticleHistManager2, + T5& PairHistManager, + T6& CprManager, + T7& PcManager) +{ + // Fill single particle histograms + for (auto const& part : SliceParticle1) { + ParticleHistManager1.fill(part); + } + + for (auto const& part : SliceParticle2) { + ParticleHistManager2.fill(part); + } + + for (auto const& [p1, p2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(SliceParticle1, SliceParticle2))) { + // pair cleaning + if (!PcManager.isCleanPair(p1, p2)) { + continue; + } + // Close pair rejection + if (CprManager.isActivated()) { + CprManager.setPair(p1, p2); + if (CprManager.isClosePair()) { + continue; + } + } + CprManager.fill(); + PairHistManager.setPair(p1, p2); + PairHistManager.fill(); + } +} + +// process same event for tracks and particles decaying into tracks +template +void processSameEvent(const T1& SliceParticle1, + const T2& SliceParticle2, + const T3& TrackTable, + T4& ParticleHistManager1, + T5& ParticleHistManager2, + T6& PairHistManager, + T7& CprManager, + T8& PcManager) +{ + // Fill single particle histograms + for (auto const& part : SliceParticle1) { + ParticleHistManager1.fill(part); + } + + for (auto const& part : SliceParticle2) { + ParticleHistManager2.fill(part, TrackTable); + } + + for (auto const& [p1, p2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(SliceParticle1, SliceParticle2))) { + // pair cleaning + if (!PcManager.isCleanPair(p1, p2, TrackTable)) { + continue; + } + // Close pair rejection + if (CprManager.isActivated()) { + CprManager.setPair(p1, p2, TrackTable); + if (CprManager.isClosePair()) { + continue; + } + } + CprManager.fill(); + PairHistManager.setPair(p1, p2); + PairHistManager.fill(); + } +} + +// process mixed event identical tracks +template +void processMixedEvent(T1& Collisions, + T2& Partition, + T3& cache, + T4& policy, + T5& depth, + T6& ParticleHistManager1, + T7& ParticleHistManager2, + T8& PairHistManager, + T9& CprManager, + T10& PcManager) +{ + for (auto const& [collision1, collision2] : o2::soa::selfCombinations(policy, depth, -1, Collisions, Collisions)) { + auto sliceParticle1 = Partition->sliceByCached(o2::aod::femtobase::stored::collisionId, collision1.globalIndex(), cache); + auto sliceParticle2 = Partition->sliceByCached(o2::aod::femtobase::stored::collisionId, collision2.globalIndex(), cache); + if (sliceParticle1.size() == 0 || sliceParticle2.size() == 0) { + continue; + } + for (auto const& part : sliceParticle1) { + ParticleHistManager1.fill(part); + } + for (auto const& part : sliceParticle2) { + ParticleHistManager2.fill(part); + } + for (auto const& [p1, p2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(sliceParticle1, sliceParticle2))) { + // pair cleaning + if (!PcManager.isCleanPair(p1, p2)) { + continue; + } + // Close pair rejection + if (CprManager.isActivated()) { + CprManager.setPair(p1, p2); + if (CprManager.isClosePair()) { + continue; + } + } + CprManager.fill(); + PairHistManager.setPair(p1, p2); + PairHistManager.fill(); + } + } +} + +// process mixed event different tracks +template +void processMixedEvent(T1& Collisions, + T2& Partition1, + T3& Partition2, + T4& cache, + T5& policy, + T6& depth, + T7& ParticleHistManager1, + T8& ParticleHistManager2, + T9& PairHistManager, + T10& CprManager, + T11& PcManager) +{ + for (auto const& [collision1, collision2] : o2::soa::selfCombinations(policy, depth, -1, Collisions, Collisions)) { + auto sliceParticle1 = Partition1->sliceByCached(o2::aod::femtobase::stored::collisionId, collision1.globalIndex(), cache); + auto sliceParticle2 = Partition2->sliceByCached(o2::aod::femtobase::stored::collisionId, collision2.globalIndex(), cache); + if (sliceParticle1.size() == 0 || sliceParticle2.size() == 0) { + continue; + } + for (auto const& part : sliceParticle1) { + ParticleHistManager1.fill(part); + } + for (auto const& part : sliceParticle2) { + ParticleHistManager2.fill(part); + } + for (auto const& [p1, p2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(sliceParticle1, sliceParticle2))) { + // pair cleaning + if (!PcManager.isCleanPair(p1, p2)) { + continue; + } + // Close pair rejection + if (CprManager.isActivated()) { + CprManager.setPair(p1, p2); + if (CprManager.isClosePair()) { + continue; + } + } + CprManager.fill(); + PairHistManager.setPair(p1, p2); + PairHistManager.fill(); + } + } +} + +// process mixed event for track and particles decaying into tracks +template +void processMixedEvent(T1& Collisions, + T2& Partition1, + T3& Partition2, + T4& TrackTable, + T5& cache, + T6& policy, + T7& depth, + T8& ParticleHistManager1, + T9& ParticleHistManager2, + T10& PairHistManager, + T11& CprManager, + T12& PcManager) +{ + for (auto const& [collision1, collision2] : o2::soa::selfCombinations(policy, depth, -1, Collisions, Collisions)) { + auto sliceParticle1 = Partition1->sliceByCached(o2::aod::femtobase::stored::collisionId, collision1.globalIndex(), cache); + auto sliceParticle2 = Partition2->sliceByCached(o2::aod::femtobase::stored::collisionId, collision2.globalIndex(), cache); + if (sliceParticle1.size() == 0 || sliceParticle2.size() == 0) { + continue; + } + for (auto const& part : sliceParticle1) { + ParticleHistManager1.fill(part); + } + for (auto const& part : sliceParticle2) { + ParticleHistManager2.fill(part, TrackTable); + } + for (auto const& [p1, p2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(sliceParticle1, sliceParticle2))) { + // pair cleaning + if (!PcManager.isCleanPair(p1, p2, TrackTable)) { + continue; + } + // Close pair rejection + if (CprManager.isActivated()) { + CprManager.setPair(p1, p2, TrackTable); + if (CprManager.isClosePair()) { + continue; + } + } + CprManager.fill(); + PairHistManager.setPair(p1, p2); + PairHistManager.fill(); + } + } +} +} // namespace pairprocesshelpers +} // namespace o2::analysis::femto + +#endif // PWGCF_FEMTOUNITED_CORE_PAIRPROCESSHELPERS_H_ diff --git a/PWGCF/Femto/Core/partitions.h b/PWGCF/Femto/Core/partitions.h index ffbdf6fd214..a4f0d8c197f 100644 --- a/PWGCF/Femto/Core/partitions.h +++ b/PWGCF/Femto/Core/partitions.h @@ -16,13 +16,15 @@ #ifndef PWGCF_FEMTO_CORE_PARTITIONS_H_ #define PWGCF_FEMTO_CORE_PARTITIONS_H_ -// collsion filters -#define MAKE_COLLISION_FILTER(selection) \ - (femtocollisions::posZ >= (selection).vtxZMin && femtocollisions::posZ <= (selection).vtxZMax) && \ - (femtocollisions::mult >= (selection).multMin && femtocollisions::mult <= (selection).multMax) && \ - (femtocollisions::cent >= (selection).centMin && femtocollisions::cent <= (selection).centMax) && \ - (femtocollisions::sphericity >= (selection).spherMin && femtocollisions::sphericity <= (selection).spherMax) && \ - (femtocollisions::magField >= (selection).magFieldMin && femtocollisions::magField <= (selection).magFieldMax) +// collsion selection +#define MAKE_COLLISION_FILTER(selection) \ + (femtocollisions::posZ >= selection.vtxZMin && femtocollisions::posZ <= selection.vtxZMax) && \ + (femtocollisions::mult >= selection.multMin && femtocollisions::mult <= selection.multMax) && \ + (femtocollisions::cent >= selection.centMin && femtocollisions::cent <= selection.centMax) && \ + (femtocollisions::sphericity >= selection.spherMin && femtocollisions::sphericity <= selection.spherMax) && \ + (femtocollisions::magField >= selection.magFieldMin && femtocollisions::magField <= selection.magFieldMax) && \ + (femtocollisions::occupancy >= selection.occupancyMin && femtocollisions::occupancy <= selection.occupancyMax) && \ + ncheckbit(femtocollisions::collisionMask, selection.collisionMask) // standard track partition #define MAKE_TRACK_PARTITION(selection) \ diff --git a/PWGCF/Femto/DataModel/FemtoTables.h b/PWGCF/Femto/DataModel/FemtoTables.h index c7bc8334c52..8c4d2208313 100644 --- a/PWGCF/Femto/DataModel/FemtoTables.h +++ b/PWGCF/Femto/DataModel/FemtoTables.h @@ -34,7 +34,7 @@ namespace o2::aod namespace femtocollisions { -DECLARE_SOA_COLUMN(CollisionMask, collisionMask, femtodatatypes::CollsionsMaskType); //! Bitmask for collision selections +DECLARE_SOA_COLUMN(CollisionMask, collisionMask, femtodatatypes::CollisionMaskType); //! Bitmask for collision selections DECLARE_SOA_COLUMN(PosX, posX, float); //! x coordinate of vertex DECLARE_SOA_COLUMN(PosY, posY, float); //! y coordinate of vertex @@ -274,50 +274,50 @@ DECLARE_SOA_TABLE_STAGED_VERSIONED(FElectronPids_001, "FELECTRONPID", 1, //! ful femtotracks::ItsNSigmaEl, femtotracks::TpcNSigmaEl, femtotracks::TofNSigmaEl, - femtotracks::TpcitsNSigmaEl, - femtotracks::TpctofNSigmaEl); + femtotracks::TpcitsNSigmaEl, + femtotracks::TpctofNSigmaEl); using FElectronPids = FElectronPids_001; DECLARE_SOA_TABLE_STAGED_VERSIONED(FPionPids_001, "FPIONPID", 1, //! full pion pid femtotracks::ItsNSigmaPi, femtotracks::TpcNSigmaPi, femtotracks::TofNSigmaPi, - femtotracks::TpcitsNSigmaPi, - femtotracks::TpctofNSigmaPi); + femtotracks::TpcitsNSigmaPi, + femtotracks::TpctofNSigmaPi); using FPionPids = FPionPids_001; DECLARE_SOA_TABLE_STAGED_VERSIONED(FKaonPids_001, "FKAONPID", 1, //! full kaon pid femtotracks::ItsNSigmaKa, femtotracks::TpcNSigmaKa, femtotracks::TofNSigmaKa, - femtotracks::TpcitsNSigmaKa, - femtotracks::TpctofNSigmaKa); + femtotracks::TpcitsNSigmaKa, + femtotracks::TpctofNSigmaKa); using FKaonPids = FKaonPids_001; DECLARE_SOA_TABLE_STAGED_VERSIONED(FProtonPids_001, "FPROTONPID", 1, //! full proton pid femtotracks::ItsNSigmaPr, femtotracks::TpcNSigmaPr, femtotracks::TofNSigmaPr, - femtotracks::TpcitsNSigmaPr, - femtotracks::TpctofNSigmaPr); + femtotracks::TpcitsNSigmaPr, + femtotracks::TpctofNSigmaPr); using FProtonPids = FProtonPids_001; DECLARE_SOA_TABLE_STAGED_VERSIONED(FDeuteronPids_001, "FDEUTERONPID", 1, //! full deuteron pid femtotracks::ItsNSigmaDe, femtotracks::TpcNSigmaDe, femtotracks::TofNSigmaDe, - femtotracks::TpcitsNSigmaDe, - femtotracks::TpctofNSigmaDe); + femtotracks::TpcitsNSigmaDe, + femtotracks::TpctofNSigmaDe); using FDeuteronPids = FDeuteronPids_001; DECLARE_SOA_TABLE_STAGED_VERSIONED(FTritonPids_001, "FTRITONPID", 1, //! full triton pid femtotracks::ItsNSigmaTr, femtotracks::TpcNSigmaTr, femtotracks::TofNSigmaTr, - femtotracks::TpcitsNSigmaTr, - femtotracks::TpctofNSigmaTr); + femtotracks::TpcitsNSigmaTr, + femtotracks::TpctofNSigmaTr); using FTritonPids = FTritonPids_001; DECLARE_SOA_TABLE_STAGED_VERSIONED(FHeliumPids_001, "FHELIUMPID", 1, //! full helium3 pid femtotracks::ItsNSigmaHe, femtotracks::TpcNSigmaHe, femtotracks::TofNSigmaHe, - femtotracks::TpcitsNSigmaHe, - femtotracks::TpctofNSigmaHe); + femtotracks::TpcitsNSigmaHe, + femtotracks::TpctofNSigmaHe); using FHeliumPids = FHeliumPids_001; using FTrackPids = soa::Join; diff --git a/PWGCF/Femto/Tasks/CMakeLists.txt b/PWGCF/Femto/Tasks/CMakeLists.txt index 7ed493cc309..0eacf23db6b 100644 --- a/PWGCF/Femto/Tasks/CMakeLists.txt +++ b/PWGCF/Femto/Tasks/CMakeLists.txt @@ -34,12 +34,12 @@ o2physics_add_dpl_workflow(femto-cascade-qa PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) -# o2physics_add_dpl_workflow(femtounited-pair-track-track -# SOURCES femtounitedPairTrackTrack.cxx -# PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore -# COMPONENT_NAME Analysis) -# -# o2physics_add_dpl_workflow(femtounited-pair-track-v0 -# SOURCES femtounitedPairTrackV0.cxx -# PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore -# COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(femto-pair-track-track + SOURCES femtoPairTrackTrack.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(femto-pair-track-v0 + SOURCES femtoPairTrackV0.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGCF/Femto/Tasks/femtoCascadeQa.cxx b/PWGCF/Femto/Tasks/femtoCascadeQa.cxx index 1de5aef92ec..97c6bce428b 100644 --- a/PWGCF/Femto/Tasks/femtoCascadeQa.cxx +++ b/PWGCF/Femto/Tasks/femtoCascadeQa.cxx @@ -46,7 +46,7 @@ using namespace o2::analysis::femto; struct FemtoCascadeQa { // setup tables - using Collisions = FCols; + using Collisions = Join; using Collision = Collisions::iterator; using FilteredCollisions = o2::soa::Filtered; @@ -59,10 +59,10 @@ struct FemtoCascadeQa { SliceCache cache; // setup collisions + collisionbuilder::ConfCollisionSelection collisionSelection; + Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); colhistmanager::CollisionHistManager colHistManager; colhistmanager::ConfCollisionBinning confCollisionBinning; - collisionbuilder::ConfCollisionFilters collisionSelection; - Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); // setup for xis cascadebuilder::ConfXiSelection confXiSelection; diff --git a/PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx b/PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx new file mode 100644 index 00000000000..b16c48ff19b --- /dev/null +++ b/PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx @@ -0,0 +1,212 @@ +// 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 femtoPairTrackTrack.cxx +/// \brief Tasks that computes correlation between two tracks +/// \author Anton Riedel, TU München, anton.riedel@cern.ch + +#include "PWGCF/Femto/Core/closePairRejection.h" +#include "PWGCF/Femto/Core/collisionBuilder.h" +#include "PWGCF/Femto/Core/collisionHistManager.h" +#include "PWGCF/Femto/Core/modes.h" +#include "PWGCF/Femto/Core/pairCleaner.h" +#include "PWGCF/Femto/Core/pairHistManager.h" +#include "PWGCF/Femto/Core/pairProcessHelpers.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 +#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 FemtoPairTrackTrack { + + // setup tables + using Collisions = FCols; + using Collision = Collisions::iterator; + + using FilteredCollisions = o2::soa::Filtered; + using FilteredCollision = FilteredCollisions::iterator; + + using Tracks = o2::soa::Join; + + SliceCache cache; + + // setup collisions + collisionbuilder::ConfCollisionSelection collisionSelection; + Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); + colhistmanager::ConfCollisionBinning confCollisionBinning; + colhistmanager::CollisionHistManager colHistManager; + + // setup tracks + trackbuilder::ConfTrackSelection1 trackSelections1; + trackhistmanager::ConfTrackBinning1 confTrackBinning1; + trackhistmanager::TrackHistManager trackHistManager1; + Partition trackPartition1 = MAKE_TRACK_PARTITION(trackSelections1); + + trackbuilder::ConfTrackSelection2 trackSelections2; + trackhistmanager::ConfTrackBinning2 confTrackBinning2; + trackhistmanager::TrackHistManager trackHistManager2; + Partition trackPartition2 = MAKE_TRACK_PARTITION(trackSelections1); + + Preslice perColReco = aod::femtobase::stored::collisionId; + + // setup pairs + pairhistmanager::ConfPairBinning confPairBinning; + pairhistmanager::PairHistManager pairHistManagerSe; + pairhistmanager::PairHistManager pairHistManagerMe; + + // 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{"FemtoTrackTrack", {}, OutputObjHandlingPolicy::AnalysisObject}; + std::mt19937 rng; + bool mixParticles = false; + + // setup cpr + closepairrejection::ConfCpr confCpr; + closepairrejection::ClosePairRejectionTrackTrack cprSe; + closepairrejection::ClosePairRejectionTrackTrack cprMe; + paircleaner::TrackTrackPairCleaner pc; + + 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 for tracks + auto colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); + colHistManager.init(&hRegistry, colHistSpec); + + auto trackHistSpec1 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning1); + trackHistManager1.init(&hRegistry, trackHistSpec1); + + auto trackHistSpec2 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning2); + trackHistManager2.init(&hRegistry, trackHistSpec2); + + // setup histograms for pair + auto pairHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning, confTrackBinning1, confTrackBinning2); + pairHistManagerSe.init(&hRegistry, pairHistSpec); + pairHistManagerSe.setMass(trackSelections1.pdgCode.value, trackSelections2.pdgCode.value); + pairHistManagerMe.init(&hRegistry, pairHistSpec); + pairHistManagerMe.setMass(trackSelections1.pdgCode.value, trackSelections2.pdgCode.value); + + // setup histograms for cpr + auto cprHistSpec = closepairrejection::makeCprHistSpecMap(confCpr); + cprSe.init(&hRegistry, cprHistSpec, confCpr.detaMax.value, confCpr.dphistarMax.value, confCpr.on.value); + cprMe.init(&hRegistry, cprHistSpec, confCpr.detaMax.value, confCpr.dphistarMax.value, confCpr.on.value); + + // setup rng if necessary + if (confMixing.seed.value >= 0) { + uint64_t randomSeed = 0; + mixParticles = 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); + } + rng = std::mt19937(randomSeed); + } + }; + + void processSameEvent(FilteredCollision const& col, Tracks const& /*tracks*/) + { + if (confMixing.sameSpecies) { + auto trackSlice1 = trackPartition1->sliceByCached(femtobase::stored::collisionId, col.globalIndex(), cache); + if (trackSlice1.size() == 0) { + return; + } + colHistManager.fill(col); + cprSe.setMagField(col.magField()); + pairprocesshelpers::processSameEvent(trackSlice1, trackHistManager1, pairHistManagerSe, cprSe, rng, mixParticles); + } else { + auto trackSlice1 = trackPartition1->sliceByCached(femtobase::stored::collisionId, col.globalIndex(), cache); + auto trackSlice2 = trackPartition2->sliceByCached(femtobase::stored::collisionId, col.globalIndex(), cache); + if (trackSlice1.size() == 0 || trackSlice2.size() == 0) { + return; + } + colHistManager.fill(col); + cprSe.setMagField(col.magField()); + pairprocesshelpers::processSameEvent(trackSlice1, trackSlice2, trackHistManager1, trackHistManager2, pairHistManagerSe, cprSe, pc); + } + } + PROCESS_SWITCH(FemtoPairTrackTrack, processSameEvent, "Enable processing same event processing", true); + + void processMixedEvent(FilteredCollisions const& cols, Tracks const& /*tracks*/) + { + if (confMixing.sameSpecies) { + switch (confMixing.policy.value) { + case static_cast(pairhistmanager::kVtxMult): + pairprocesshelpers::processMixedEvent(cols, trackPartition1, cache, mixBinsVtxMult, confMixing.depth.value, trackHistManager1, trackHistManager2, pairHistManagerMe, cprMe, pc); + break; + case static_cast(pairhistmanager::kVtxCent): + pairprocesshelpers::processMixedEvent(cols, trackPartition1, cache, mixBinsVtxCent, confMixing.depth.value, trackHistManager1, trackHistManager2, pairHistManagerMe, cprMe, pc); + break; + case static_cast(pairhistmanager::kVtxMultCent): + pairprocesshelpers::processMixedEvent(cols, trackPartition1, cache, mixBinsVtxMultCent, confMixing.depth.value, trackHistManager1, trackHistManager2, pairHistManagerMe, cprMe, pc); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } else { + switch (confMixing.policy.value) { + case static_cast(pairhistmanager::kVtxMult): + pairprocesshelpers::processMixedEvent(cols, trackPartition1, trackPartition2, cache, mixBinsVtxMult, confMixing.depth.value, trackHistManager1, trackHistManager2, pairHistManagerMe, cprMe, pc); + break; + case static_cast(pairhistmanager::kVtxCent): + pairprocesshelpers::processMixedEvent(cols, trackPartition1, trackPartition2, cache, mixBinsVtxCent, confMixing.depth.value, trackHistManager1, trackHistManager2, pairHistManagerMe, cprMe, pc); + break; + case static_cast(pairhistmanager::kVtxMultCent): + pairprocesshelpers::processMixedEvent(cols, trackPartition1, trackPartition2, cache, mixBinsVtxMultCent, confMixing.depth.value, trackHistManager1, trackHistManager2, pairHistManagerMe, cprMe, pc); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + } + PROCESS_SWITCH(FemtoPairTrackTrack, processMixedEvent, "Enable processing mixed event processing", true); +}; + +WorkflowSpec + defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{ + adaptAnalysisTask(cfgc), + }; + return workflow; +} diff --git a/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx b/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx new file mode 100644 index 00000000000..893d72561a5 --- /dev/null +++ b/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx @@ -0,0 +1,247 @@ +// 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 femtounitedPairTrackV0.cxx +/// \brief Tasks that computes correlation between tracks and lambdas +/// \author Anton Riedel, TU München, anton.riedel@cern.ch + +#include "PWGCF/Femto/Core/closePairRejection.h" +#include "PWGCF/Femto/Core/collisionBuilder.h" +#include "PWGCF/Femto/Core/collisionHistManager.h" +#include "PWGCF/Femto/Core/modes.h" +#include "PWGCF/Femto/Core/pairCleaner.h" +#include "PWGCF/Femto/Core/pairHistManager.h" +#include "PWGCF/Femto/Core/pairProcessHelpers.h" +#include "PWGCF/Femto/Core/partitions.h" +#include "PWGCF/Femto/Core/trackBuilder.h" +#include "PWGCF/Femto/Core/trackHistManager.h" +#include "PWGCF/Femto/Core/v0Builder.h" +#include "PWGCF/Femto/Core/v0HistManager.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 +#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 FemtounitedPairTrackV0 { + + // setup tables + using Collisions = FCols; + using Collision = Collisions::iterator; + + using FilteredCollisions = o2::soa::Filtered; + using FilteredCollision = FilteredCollisions::iterator; + + using Tracks = o2::soa::Join; + using Lambdas = o2::soa::Join; + using K0shorts = o2::soa::Join; + + SliceCache cache; + + // setup collisions + collisionbuilder::ConfCollisionSelection collisionSelection; + Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); + colhistmanager::ConfCollisionBinning confCollisionBinning; + colhistmanager::CollisionHistManager colHistManager; + + // setup tracks + trackbuilder::ConfTrackSelection1 trackSelections; + trackhistmanager::ConfTrackBinning1 confTrackBinning; + trackhistmanager::TrackHistManager trackHistManager; + Partition trackPartition = MAKE_TRACK_PARTITION(trackSelections); + Preslice perColTracks = aod::femtobase::stored::collisionId; + + // setup for daughters + trackhistmanager::ConfV0PosDauBinning confPosDauBinning; + trackhistmanager::ConfV0NegDauBinning confNegDauBinning; + + // setup lambdas + v0builder::ConfLambdaSelection1 lambdaSelection; + v0histmanager::ConfLambdaBinning1 confLambdaBinning; + v0histmanager::V0HistManager< + v0histmanager::PrefixLambda, + trackhistmanager::PrefixV0PosDaughter, + trackhistmanager::PrefixV0NegDaughter, + modes::Mode::kAnalysis, + modes::V0::kLambda> + lambdaHistManager; + Partition lambdaPartition = MAKE_LAMBDA_PARTITION(lambdaSelection); + Preslice perColLambdas = aod::femtobase::stored::collisionId; + + // setup k0shorts + v0builder::ConfK0shortSelection1 k0shortSelection; + v0histmanager::ConfK0shortBinning1 confK0shortBinning; + v0histmanager::V0HistManager< + v0histmanager::PrefixK0short, + trackhistmanager::PrefixV0PosDaughter, + trackhistmanager::PrefixV0NegDaughter, + modes::Mode::kAnalysis, + modes::V0::kK0short> + k0shortHistManager; + Partition k0shortPartition = MAKE_K0SHORT_PARTITION(k0shortSelection); + Preslice perColk0shorts = aod::femtobase::stored::collisionId; + + // setup pairs + pairhistmanager::ConfPairBinning confPairBinning; + pairhistmanager::PairHistManager pairHistManagerSe; + pairhistmanager::PairHistManager pairHistManagerMe; + + // 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{"FemtoTrackTrack", {}, OutputObjHandlingPolicy::AnalysisObject}; + + // setup cpr + closepairrejection::ConfCpr confCpr; + closepairrejection::ClosePairRejectionTrackV0 cprSe; + closepairrejection::ClosePairRejectionTrackV0 cprMe; + paircleaner::TrackV0PairCleaner pc; + + 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 for tracks + auto colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); + colHistManager.init(&hRegistry, colHistSpec); + + auto trackHistSpec1 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning); + trackHistManager.init(&hRegistry, trackHistSpec1); + + // setup for daughters + auto posDauSpec = trackhistmanager::makeTrackHistSpecMap(confPosDauBinning); + auto negDauSpec = trackhistmanager::makeTrackHistSpecMap(confNegDauBinning); + + // setup for lambda + if (doprocessLambdaSameEvent || doprocessLambdaMixedEvent) { + auto lambdaHistSpec = v0histmanager::makeV0HistSpecMap(confLambdaBinning); + lambdaHistManager.init(&hRegistry, lambdaHistSpec, posDauSpec, negDauSpec); + } + + if (((doprocessLambdaSameEvent || doprocessLambdaMixedEvent) + (doprocessK0shortSameEvent || doprocessK0shortMixedEvent)) > 1) { + LOG(fatal) << "Can only process lambda-tracks Or k0short-tracks"; + } + + // setup for k0short + if (doprocessK0shortSameEvent || doprocessK0shortMixedEvent) { + auto k0shortHistSpec = v0histmanager::makeV0HistSpecMap(confK0shortBinning); + k0shortHistManager.init(&hRegistry, k0shortHistSpec, posDauSpec, negDauSpec); + } + + // setup histograms for pair + auto pairHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning, confTrackBinning, confLambdaBinning); + pairHistManagerSe.init(&hRegistry, pairHistSpec); + pairHistManagerSe.setMass(trackSelections.pdgCode.value, lambdaSelection.pdgCode.value); + pairHistManagerMe.init(&hRegistry, pairHistSpec); + pairHistManagerMe.setMass(trackSelections.pdgCode.value, lambdaSelection.pdgCode.value); + + // setup histograms for cpr + auto cprHistSpec = closepairrejection::makeCprHistSpecMap(confCpr); + cprSe.init(&hRegistry, cprHistSpec, confCpr.detaMax.value, confCpr.dphistarMax.value, confCpr.on.value); + cprMe.init(&hRegistry, cprHistSpec, confCpr.detaMax.value, confCpr.dphistarMax.value, confCpr.on.value); + }; + + void processLambdaSameEvent(FilteredCollision const& col, Tracks const& tracks, Lambdas const& /*lambdas*/) + { + auto trackSlice = trackPartition->sliceByCached(femtobase::stored::collisionId, col.globalIndex(), cache); + auto lambdaSlice = lambdaPartition->sliceByCached(femtobase::stored::collisionId, col.globalIndex(), cache); + if (trackSlice.size() == 0 || lambdaSlice.size() == 0) { + return; + } + colHistManager.fill(col); + cprSe.setMagField(col.magField()); + pairprocesshelpers::processSameEvent(trackSlice, lambdaSlice, tracks, trackHistManager, lambdaHistManager, pairHistManagerSe, cprSe, pc); + } + PROCESS_SWITCH(FemtounitedPairTrackV0, processLambdaSameEvent, "Enable processing same event processing for tracks and lambdas", true); + + void processLambdaMixedEvent(FilteredCollisions const& cols, Tracks const& tracks) + { + switch (confMixing.policy.value) { + case static_cast(pairhistmanager::kVtxMult): + pairprocesshelpers::processMixedEvent(cols, trackPartition, lambdaPartition, tracks, cache, mixBinsVtxMult, confMixing.depth.value, trackHistManager, lambdaHistManager, pairHistManagerMe, cprMe, pc); + break; + case static_cast(pairhistmanager::kVtxCent): + pairprocesshelpers::processMixedEvent(cols, trackPartition, lambdaPartition, tracks, cache, mixBinsVtxCent, confMixing.depth.value, trackHistManager, lambdaHistManager, pairHistManagerMe, cprMe, pc); + break; + case static_cast(pairhistmanager::kVtxMultCent): + pairprocesshelpers::processMixedEvent(cols, trackPartition, lambdaPartition, tracks, cache, mixBinsVtxMultCent, confMixing.depth.value, trackHistManager, lambdaHistManager, pairHistManagerMe, cprMe, pc); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + PROCESS_SWITCH(FemtounitedPairTrackV0, processLambdaMixedEvent, "Enable processing mixed event processing for tracks and lambdas", true); + + void processK0shortSameEvent(FilteredCollision const& col, Tracks const& tracks, K0shorts const& /*k0shorts*/) + { + auto trackSlice = trackPartition->sliceByCached(femtobase::stored::collisionId, col.globalIndex(), cache); + auto k0shortSlice = k0shortPartition->sliceByCached(femtobase::stored::collisionId, col.globalIndex(), cache); + if (trackSlice.size() == 0 || k0shortSlice.size() == 0) { + return; + } + colHistManager.fill(col); + cprSe.setMagField(col.magField()); + pairprocesshelpers::processSameEvent(trackSlice, k0shortSlice, tracks, trackHistManager, k0shortHistManager, pairHistManagerSe, cprSe, pc); + } + PROCESS_SWITCH(FemtounitedPairTrackV0, processK0shortSameEvent, "Enable processing same event processing for tracks and k0shorts", false); + + void processK0shortMixedEvent(FilteredCollisions const& cols, Tracks const& tracks) + { + switch (confMixing.policy.value) { + case static_cast(pairhistmanager::kVtxMult): + pairprocesshelpers::processMixedEvent(cols, trackPartition, k0shortPartition, tracks, cache, mixBinsVtxMult, confMixing.depth.value, trackHistManager, k0shortHistManager, pairHistManagerMe, cprMe, pc); + break; + case static_cast(pairhistmanager::kVtxCent): + pairprocesshelpers::processMixedEvent(cols, trackPartition, k0shortPartition, tracks, cache, mixBinsVtxCent, confMixing.depth.value, trackHistManager, k0shortHistManager, pairHistManagerMe, cprMe, pc); + break; + case static_cast(pairhistmanager::kVtxMultCent): + pairprocesshelpers::processMixedEvent(cols, trackPartition, k0shortPartition, tracks, cache, mixBinsVtxMultCent, confMixing.depth.value, trackHistManager, k0shortHistManager, pairHistManagerMe, cprMe, pc); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + PROCESS_SWITCH(FemtounitedPairTrackV0, processK0shortMixedEvent, "Enable processing mixed event processing for tracks and k0shorts", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{ + adaptAnalysisTask(cfgc), + }; + return workflow; +} diff --git a/PWGCF/Femto/Tasks/femtoTrackQa.cxx b/PWGCF/Femto/Tasks/femtoTrackQa.cxx index a111111f6b0..de1c8bd1181 100644 --- a/PWGCF/Femto/Tasks/femtoTrackQa.cxx +++ b/PWGCF/Femto/Tasks/femtoTrackQa.cxx @@ -43,7 +43,7 @@ using namespace o2::analysis::femto; struct FemtoTrackQa { // setup tables - using Collisions = FCols; + using Collisions = o2::soa::Join; using Collision = Collisions::iterator; using FilteredCollisions = o2::soa::Filtered; @@ -54,7 +54,7 @@ struct FemtoTrackQa { SliceCache cache; // setup collisions - collisionbuilder::ConfCollisionFilters collisionSelection; + collisionbuilder::ConfCollisionSelection collisionSelection; Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); colhistmanager::ConfCollisionBinning confCollisionBinning; colhistmanager::CollisionHistManager colHistManager; @@ -85,7 +85,6 @@ struct FemtoTrackQa { auto trackSlice = trackPartition->sliceByCached(femtobase::stored::collisionId, col.globalIndex(), cache); for (auto const& track : trackSlice) { trackHistManager.fill(track); - // asdf } } }; diff --git a/PWGCF/Femto/Tasks/femtoTwotrackresonanceQa.cxx b/PWGCF/Femto/Tasks/femtoTwotrackresonanceQa.cxx index 83b28842469..7ecdd2c4102 100644 --- a/PWGCF/Femto/Tasks/femtoTwotrackresonanceQa.cxx +++ b/PWGCF/Femto/Tasks/femtoTwotrackresonanceQa.cxx @@ -44,7 +44,7 @@ using namespace o2::analysis::femto; struct FemtoTwotrackresonanceQa { // setup tables - using Collisions = FCols; + using Collisions = Join; using Collision = Collisions::iterator; using FilteredCollisions = o2::soa::Filtered; @@ -58,10 +58,10 @@ struct FemtoTwotrackresonanceQa { SliceCache cache; // setup for collisions + collisionbuilder::ConfCollisionSelection collisionSelection; + Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); colhistmanager::CollisionHistManager colHistManager; colhistmanager::ConfCollisionBinning confCollisionBinning; - collisionbuilder::ConfCollisionFilters collisionSelection; - Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); // setup for phis twotrackresonancebuilder::ConfPhiSelection confPhiSelection; diff --git a/PWGCF/Femto/Tasks/femtoV0Qa.cxx b/PWGCF/Femto/Tasks/femtoV0Qa.cxx index 1b75bcd24ea..56e3f7a6869 100644 --- a/PWGCF/Femto/Tasks/femtoV0Qa.cxx +++ b/PWGCF/Femto/Tasks/femtoV0Qa.cxx @@ -46,14 +46,14 @@ using namespace o2::analysis::femto; struct FemtoV0Qa { // setup for collisions - collisionbuilder::ConfCollisionFilters collisionSelection; + collisionbuilder::ConfCollisionSelection collisionSelection; Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); colhistmanager::CollisionHistManager colHistManager; colhistmanager::ConfCollisionBinning confCollisionBinning; // using Collisions = o2::soa::Join; - using Collisions = FCols; + using Collisions = o2::soa::Join; using Collision = Collisions::iterator; using FilteredCollisions = o2::soa::Filtered; From 90cc9051323c70f48c74062fd69b50becb3450b5 Mon Sep 17 00:00:00 2001 From: Anton Riedel Date: Mon, 22 Sep 2025 09:01:42 +0200 Subject: [PATCH 2/4] Feat: add track-track and track-v0 pairing task --- PWGCF/Femto/Core/baseSelection.h | 5 +- PWGCF/Femto/Core/closePairRejection.h | 149 +++++---- PWGCF/Femto/Core/collisionBuilder.h | 33 +- PWGCF/Femto/Core/dataTypes.h | 10 +- PWGCF/Femto/Core/femtoUtils.h | 6 + PWGCF/Femto/Core/modes.h | 21 +- PWGCF/Femto/Core/pairBuilder.h | 296 ++++++++++++++++++ PWGCF/Femto/Core/pairCleaner.h | 49 +-- PWGCF/Femto/Core/pairHistManager.h | 35 ++- PWGCF/Femto/Core/pairProcessHelpers.h | 81 ++--- PWGCF/Femto/Core/partitions.h | 33 +- PWGCF/Femto/Core/trackBuilder.h | 3 +- PWGCF/Femto/Core/trackHistManager.h | 103 +++--- PWGCF/Femto/Core/v0HistManager.h | 6 +- PWGCF/Femto/DataModel/FemtoTables.h | 6 - PWGCF/Femto/Tasks/femtoCascadeQa.cxx | 2 +- PWGCF/Femto/Tasks/femtoKinkQa.cxx | 4 +- PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx | 127 ++------ PWGCF/Femto/Tasks/femtoPairTrackV0.cxx | 169 ++++------ PWGCF/Femto/Tasks/femtoTrackQa.cxx | 4 +- .../Femto/Tasks/femtoTwotrackresonanceQa.cxx | 2 +- PWGCF/Femto/Tasks/femtoV0Qa.cxx | 2 +- 22 files changed, 632 insertions(+), 514 deletions(-) create mode 100644 PWGCF/Femto/Core/pairBuilder.h diff --git a/PWGCF/Femto/Core/baseSelection.h b/PWGCF/Femto/Core/baseSelection.h index e64f5d05665..2be9737422d 100644 --- a/PWGCF/Femto/Core/baseSelection.h +++ b/PWGCF/Femto/Core/baseSelection.h @@ -63,7 +63,7 @@ class BaseSelection if (static_cast(observableIndex) >= NumObservables) { LOG(fatal) << "Observable is not valid. Observable (index) has to be smaller than " << NumObservables; } - if (skipMostPermissiveBit) { + if (!selectionValues.empty() && skipMostPermissiveBit) { mNSelections += selectionValues.size() - 1; } else { mNSelections += selectionValues.size(); @@ -115,9 +115,6 @@ class BaseSelection /// \param observableIndex Index of the observable. void addSelection(int mode, int observableIndex) { - if (static_cast(observableIndex) >= NumObservables) { - LOG(fatal) << "Observable is not valid. Observable (index) has to be smaller than " << NumObservables; - } switch (mode) { case -1: // cut is optional and we store bit for the cut mNSelections += 1; diff --git a/PWGCF/Femto/Core/closePairRejection.h b/PWGCF/Femto/Core/closePairRejection.h index b1bb7656b3a..4a693b89267 100644 --- a/PWGCF/Femto/Core/closePairRejection.h +++ b/PWGCF/Femto/Core/closePairRejection.h @@ -16,21 +16,15 @@ #ifndef PWGCF_FEMTO_CORE_CLOSEPAIRREJECTION_H_ #define PWGCF_FEMTO_CORE_CLOSEPAIRREJECTION_H_ -#include "PWGCF/Femto/Core/dataTypes.h" #include "PWGCF/Femto/Core/femtoUtils.h" #include "PWGCF/Femto/Core/histManager.h" -#include "PWGCF/Femto/Core/modes.h" -#include "PWGCF/Femto/DataModel/FemtoTables.h" #include "Framework/HistogramRegistry.h" #include #include -#include #include #include -#include -#include #include namespace o2::analysis::femto @@ -58,8 +52,8 @@ struct ConfCpr : o2::framework::ConfigurableGroup { o2::framework::Configurable on{"on", true, "Turn on CPR"}; o2::framework::Configurable detaMax{"detaMax", 0.01f, "Maximium deta"}; o2::framework::Configurable dphistarMax{"dphistarMax", 0.01f, "Maximum dphistar"}; - o2::framework::ConfigurableAxis binningDeta{"binningDeta", {{200, -0.2, 0.2}}, "deta"}; - o2::framework::ConfigurableAxis binningDphistar{"binningDphistar", {{200, -0.2, 0.2}}, "dphi"}; + o2::framework::ConfigurableAxis binningDeta{"binningDeta", {{500, -0.5, 0.5}}, "deta"}; + o2::framework::ConfigurableAxis binningDphistar{"binningDphistar", {{500, -0.5, 0.5}}, "dphi"}; }; // tpc radii for computing phistar @@ -69,10 +63,8 @@ constexpr std::array kTpcRadius = {85., 105., 125., 145., 165., // directory names constexpr char PrefixTrackTrackSe[] = "CPR_TrackTrack/SE/"; constexpr char PrefixTrackTrackMe[] = "CPR_TrackTrack/ME/"; -constexpr char PrefixTrackPosDauSe[] = "CPR_TrackPosDau/SE/"; -constexpr char PrefixTrackNegDauSe[] = "CPR_TrackNegDau/SE/"; -constexpr char PrefixTrackPosDauMe[] = "CPR_TrackPosDau/ME/"; -constexpr char PrefixTrackNegDauMe[] = "CPR_TrackNegDau/ME/"; +constexpr char PrefixTrackV0Se[] = "CPR_TrackV0/SE/"; +constexpr char PrefixTrackV0Me[] = "CPR_TrackV0/ME/"; // must be in sync with enum TrackVariables // the enum gives the correct index in the array @@ -91,58 +83,73 @@ constexpr std::array, kCprHistogramLast> HistTabl template auto makeCprHistSpecMap(const T& confCpr) { - std::map> specs; - for (int i = 0; i < kCprHistogramLast; ++i) { - specs[static_cast(i)] = {confCpr.binningDeta, confCpr.binningDphistar}; - } - return specs; + return std::map>{ + {kAverage, {confCpr.binningDeta, confCpr.binningDphistar}}, + {kRadius0, {confCpr.binningDeta, confCpr.binningDphistar}}, + {kRadius1, {confCpr.binningDeta, confCpr.binningDphistar}}, + {kRadius2, {confCpr.binningDeta, confCpr.binningDphistar}}, + {kRadius3, {confCpr.binningDeta, confCpr.binningDphistar}}, + {kRadius4, {confCpr.binningDeta, confCpr.binningDphistar}}, + {kRadius5, {confCpr.binningDeta, confCpr.binningDphistar}}, + {kRadius6, {confCpr.binningDeta, confCpr.binningDphistar}}, + {kRadius7, {confCpr.binningDeta, confCpr.binningDphistar}}, + {kRadius8, {confCpr.binningDeta, confCpr.binningDphistar}}}; }; template class CloseTrackRejection { public: - CloseTrackRejection() {} + CloseTrackRejection() = default; + virtual ~CloseTrackRejection() = default; - void init(o2::framework::HistogramRegistry* registry, std::map>& specs, float detaMax, float dphistarMax) + void init(o2::framework::HistogramRegistry* registry, std::map>& specs, float detaMax, float dphistarMax, int chargeTrack1, int chargeTrack2) { - mHistogramRegistry = registry; mDetaMax = detaMax; mDphistarMax = dphistarMax; - for (int i = 0; i < kCprHistogramLast; ++i) { - auto hist = static_cast(i); - mHistogramRegistry->add(std::string(prefix) + GetHistNamev2(hist, HistTable), GetHistDesc(hist, HistTable), GetHistType(hist, HistTable), {specs.at(hist)}); + if (mDetaMax < o2::constants::math::Epsilon || mDphistarMax < o2::constants::math::Epsilon) { + LOG(fatal) << "Either DetaMax or DphistarMax are 0 or negative. Either turn off CPR or specify reasonable values. Breaking ..."; + } + mChargeTrack1 = chargeTrack1; + mChargeTrack2 = chargeTrack2; + + if (utils::sign(mChargeTrack1) != utils::sign(mChargeTrack2)) { + LOG(warn) << "CPR is truned on for tracks with opposite charge. Is this intended?"; } + + mHistogramRegistry = registry; + + mHistogramRegistry->add(std::string(prefix) + GetHistNamev2(kAverage, HistTable), GetHistDesc(kAverage, HistTable), GetHistType(kAverage, HistTable), {specs.at(kAverage)}); + mHistogramRegistry->add(std::string(prefix) + GetHistNamev2(kRadius0, HistTable), GetHistDesc(kRadius0, HistTable), GetHistType(kRadius0, HistTable), {specs.at(kRadius0)}); + mHistogramRegistry->add(std::string(prefix) + GetHistNamev2(kRadius1, HistTable), GetHistDesc(kRadius1, HistTable), GetHistType(kRadius1, HistTable), {specs.at(kRadius1)}); + mHistogramRegistry->add(std::string(prefix) + GetHistNamev2(kRadius2, HistTable), GetHistDesc(kRadius2, HistTable), GetHistType(kRadius2, HistTable), {specs.at(kRadius2)}); + mHistogramRegistry->add(std::string(prefix) + GetHistNamev2(kRadius3, HistTable), GetHistDesc(kRadius3, HistTable), GetHistType(kRadius3, HistTable), {specs.at(kRadius3)}); + mHistogramRegistry->add(std::string(prefix) + GetHistNamev2(kRadius4, HistTable), GetHistDesc(kRadius4, HistTable), GetHistType(kRadius4, HistTable), {specs.at(kRadius4)}); + mHistogramRegistry->add(std::string(prefix) + GetHistNamev2(kRadius5, HistTable), GetHistDesc(kRadius5, HistTable), GetHistType(kRadius5, HistTable), {specs.at(kRadius5)}); + mHistogramRegistry->add(std::string(prefix) + GetHistNamev2(kRadius6, HistTable), GetHistDesc(kRadius6, HistTable), GetHistType(kRadius6, HistTable), {specs.at(kRadius6)}); + mHistogramRegistry->add(std::string(prefix) + GetHistNamev2(kRadius7, HistTable), GetHistDesc(kRadius7, HistTable), GetHistType(kRadius7, HistTable), {specs.at(kRadius7)}); + mHistogramRegistry->add(std::string(prefix) + GetHistNamev2(kRadius8, HistTable), GetHistDesc(kRadius8, HistTable), GetHistType(kRadius8, HistTable), {specs.at(kRadius8)}); } void setMagField(float magField) { mMagField = magField; } - void reset() + template + void compute(const T1& track1, const T2& track2) { - mSameCharge = false; + // reset values mAverageDphistar = 0.f; mDeta = 0.f; mDphistar.fill(0.f); - } - template - void compute(const T1& track1, const T2& track2) - { - reset(); - if (track1.sign() != track2.sign()) { - return; - } - mSameCharge = true; mDeta = track1.eta() - track2.eta(); - for (size_t i = 0; i < kTpcRadius.size(); ++i) { - auto phistar1 = utils::dphistar(mMagField, kTpcRadius[i], track1.sign(), track1.pt(), track1.phi()); - auto phistar2 = utils::dphistar(mMagField, kTpcRadius[i], track2.sign(), track2.pt(), track2.phi()); - + for (size_t i = 0; i < kTpcRadius.size(); i++) { + auto phistar1 = utils::dphistar(mMagField, kTpcRadius[i], mChargeTrack1, track1.pt(), track1.phi()); + auto phistar2 = utils::dphistar(mMagField, kTpcRadius[i], mChargeTrack2, track2.pt(), track2.phi()); if (phistar1 && phistar2) { // if the calculation for one phistar fails, keep the default value, which is 0 // this makes it more likelier for the pair to be rejected sind the averave will be biased towards lower values - mDphistar[i] = phistar1.value() - phistar2.value(); + mDphistar.at(i) = phistar1.value() - phistar2.value(); } } mAverageDphistar = std::accumulate(mDphistar.begin(), mDphistar.end(), 0.f) / mDphistar.size(); @@ -154,28 +161,31 @@ class CloseTrackRejection mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(kAverage, HistTable)), mDeta, mAverageDphistar); // fill radii hists - for (int i = 0; i < kNradii; ++i) { - mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(static_cast(kRadius0 + 1), HistTable)), mDeta, mDphistar.at(i)); - } + mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(kRadius0, HistTable)), mDeta, mDphistar.at(0)); + mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(kRadius1, HistTable)), mDeta, mDphistar.at(1)); + mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(kRadius2, HistTable)), mDeta, mDphistar.at(2)); + mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(kRadius3, HistTable)), mDeta, mDphistar.at(3)); + mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(kRadius4, HistTable)), mDeta, mDphistar.at(4)); + mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(kRadius5, HistTable)), mDeta, mDphistar.at(5)); + mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(kRadius6, HistTable)), mDeta, mDphistar.at(6)); + mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(kRadius7, HistTable)), mDeta, mDphistar.at(7)); + mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(kRadius8, HistTable)), mDeta, mDphistar.at(8)); } bool isClosePair() const { - if (!mSameCharge) { - return false; - } else { - return ((mAverageDphistar * mAverageDphistar) / (mDphistarMax * mDphistarMax) + (mDeta * mDeta) / (mDetaMax * mDetaMax)) < 1.f; - } + return std::hypot(mAverageDphistar / mDphistarMax, mDeta / mDetaMax) < 1.f; } private: + int mChargeTrack1 = 0; + int mChargeTrack2 = 0; float mMagField = 0.f; float mAverageDphistar = 0.f; - bool mSameCharge = false; float mDeta = 0.f; float mDetaMax = 0.f; float mDphistarMax = 0.f; - std::array mDphistar = {}; + std::array mDphistar = {0.f}; o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; }; @@ -184,10 +194,10 @@ template class ClosePairRejectionTrackTrack { public: - void init(o2::framework::HistogramRegistry* registry, std::map>& specs, float detaMax, float dphistarMax, bool isActivated) + void init(o2::framework::HistogramRegistry* registry, std::map>& specs, float detaMax, float dphistarMax, int signTrack1, int absChargeTrack1, int signTrack2, int AbsChargeTrack2, bool isActivated) { mIsActivated = isActivated; - mCtr.init(registry, specs, detaMax, dphistarMax); + mCtr.init(registry, specs, detaMax, dphistarMax, signTrack1 * absChargeTrack1, signTrack2 * AbsChargeTrack2); } void setMagField(float magField) { mCtr.setMagField(magField); } @@ -205,41 +215,48 @@ class ClosePairRejectionTrackTrack bool mIsActivated = true; }; -template +template class ClosePairRejectionTrackV0 // can also be used for any particle type that has pos/neg daughters, like resonances { public: - void init(o2::framework::HistogramRegistry* registry, std::map>& specs, float detaMax, float dphistarMax, bool isActivated) + void init(o2::framework::HistogramRegistry* registry, std::map>& specs, float detaMax, float dphistarMax, int signTrack, int absChargeTrack, bool isActivated) { mIsActivated = isActivated; - mCtrPosDau.init(registry, specs, detaMax, dphistarMax); - mCtrNegDau.init(registry, specs, detaMax, dphistarMax); + mSignTrack = signTrack; + + // initialize CPR with charge of the track and the same charge for the daughter particle + // absolute charge of the daughter track will be 1, so we can pass the sign directly + mCtr.init(registry, specs, detaMax, dphistarMax, signTrack * absChargeTrack, signTrack); } void setMagField(float magField) { - mCtrPosDau.setMagField(magField); - mCtrNegDau.setMagField(magField); + mCtr.setMagField(magField); } template void setPair(const T1& track, const T2& v0, const T3 /*trackTable*/) { - auto posDaughter = v0.template posDau_as(); - auto negDaughter = v0.template negDau_as(); - mCtrPosDau.compute(track, posDaughter); - mCtrNegDau.compute(track, negDaughter); + if (mSignTrack == 1) { + auto daughter = v0.template posDau_as(); + mCtr.compute(track, daughter); + } else if (mSignTrack == -1) { + auto daughter = v0.template negDau_as(); + mCtr.compute(track, daughter); + } else { + LOG(fatal) << "CPR Track-V0: Wrong track sign"; + } } - bool isClosePair() const { return mCtrPosDau.isClosePair() || mCtrNegDau.isClosePair(); } + + bool isClosePair() const { return mCtr.isClosePair(); } void fill() { - mCtrPosDau.fill(); - mCtrNegDau.fill(); + mCtr.fill(); } bool isActivated() const { return mIsActivated; } private: - CloseTrackRejection mCtrPosDau; - CloseTrackRejection mCtrNegDau; + CloseTrackRejection mCtr; + int mSignTrack = 0; bool mIsActivated = true; }; diff --git a/PWGCF/Femto/Core/collisionBuilder.h b/PWGCF/Femto/Core/collisionBuilder.h index b7ebf38824b..96c64645c7a 100644 --- a/PWGCF/Femto/Core/collisionBuilder.h +++ b/PWGCF/Femto/Core/collisionBuilder.h @@ -50,8 +50,6 @@ struct ConfCollisionFilters : o2::framework::ConfigurableGroup { o2::framework::Configurable centMax{"centMax", 999.f, "Maximum centrality (multiplicity percentile)"}; o2::framework::Configurable spherMin{"spherMin", 0.f, "Minimum centrality (multiplicity percentile)"}; o2::framework::Configurable spherMax{"spherMax", 2.f, "Maximum centrality (multiplicity percentile)"}; - o2::framework::Configurable occupancyMin{"occupancyMin", 0.f, "Minimum occupancy (Cut works at producer level and if occupancy is stored also at consumer level)"}; - o2::framework::Configurable occupancyMax{"occupancyMax", 1e6f, "Maximum occupancy (Cut works at producer level and if occupancy is stored also at consumer level)"}; o2::framework::Configurable magFieldMin{"magFieldMin", -1.f, "Minimum magnetic field strength (T)"}; o2::framework::Configurable magFieldMax{"magFieldMax", 1.f, "Maximum magnetic field strength (T)"}; }; @@ -71,6 +69,8 @@ struct ConfCollisionBits : o2::framework::ConfigurableGroup { o2::framework::Configurable isGoodItsLayer3{"isGoodItsLayer3", 0, "number of inactive chips on ITS layer 3 is below maximum allowed value (-1: stored in bitmaks; 0 off; 1 on)"}; o2::framework::Configurable isGoodItsLayer0123{"isGoodItsLayer0123", 0, "numbers of inactive chips on ITS layers 0-3 are below maximum allowed values (-1: stored in bitmaks; 0 off; 1 on)"}; o2::framework::Configurable isGoodItsLayersAll{"isGoodItsLayersAll", 0, "numbers of inactive chips on all ITS layers are below maximum allowed values (-1: stored in bitmaks; 0 off; 1 on)"}; + o2::framework::Configurable> occupancyMin{"occupancyMin", {}, "Minimum occpancy"}; + o2::framework::Configurable> occupancyMax{"occupancyMax", {}, "Maximum occpancy"}; }; struct ConfCollisionTriggers : o2::framework::ConfigurableGroup { @@ -93,9 +93,7 @@ struct ConfCollisionSelection : o2::framework::ConfigurableGroup { o2::framework::Configurable spherMax{"spherMax", 2.f, "Maximum centrality (multiplicity percentile)"}; o2::framework::Configurable magFieldMin{"magFieldMin", -1.f, "Minimum magnetic field strength (T)"}; o2::framework::Configurable magFieldMax{"magFieldMax", 1.f, "Maximum magnetic field strength (T)"}; - o2::framework::Configurable occupancyMin{"occupancyMin", 0.f, "Minimum occupancy (Optional)"}; - o2::framework::Configurable occupancyMax{"occupancyMax", 1e6f, "Maximum occupancy (Optional)"}; - o2::framework::Configurable collisionMask{"collisionMask", 0, "Bitmask for collision (Optional)"}; + o2::framework::Configurable collisionMask{"collisionMask", 0, "Bitmask for collision"}; }; /// enum for all collision selections @@ -114,6 +112,8 @@ enum CollisionSels { kIsGoodItsLayer3, ///< number of inactive chips on ITS layer 3 is below maximum allowed value kIsGoodItsLayer0123, ///< numbers of inactive chips on ITS layers 0-3 are below maximum allowed values kIsGoodItsLayersAll, ///< numbers of inactive chips on all ITS layers are below maximum allowed values + kOccupancyMin, ///< Min. occupancy + kOccupancyMax, ///< Max. occupancy kCollisionSelsMax }; @@ -132,7 +132,9 @@ const std::unordered_map colSelsToString = { {kNoHighMultCollInPrevRof, "No high mult collsions in previous ROF"}, {kIsGoodItsLayer3, "Is good ITS layer 3"}, {kIsGoodItsLayer0123, "Is good ITS layer 0-3"}, - {kIsGoodItsLayersAll, "Is good ITS layer all"}}; + {kIsGoodItsLayersAll, "Is good ITS layer all"}, + {kOccupancyMin, "Minimum Occupancy"}, + {kOccupancyMax, "Maximum Occupancy"}}; class CollisionSelection : public BaseSelection { @@ -154,8 +156,6 @@ class CollisionSelection : public BaseSelectionaddSelection(config.sel8.value, kSel8); @@ -170,6 +170,8 @@ class CollisionSelection : public BaseSelectionaddSelection(config.isGoodItsLayer3.value, kIsGoodItsLayer3); this->addSelection(config.isGoodItsLayer0123.value, kIsGoodItsLayer0123); this->addSelection(config.isGoodItsLayersAll.value, kIsGoodItsLayersAll); + this->addSelection(config.occupancyMin.value, kOccupancyMin, limits::kLowerLimit, true, true); + this->addSelection(config.occupancyMax.value, kOccupancyMax, limits::kUpperLimit, true, true); }; void setMagneticField(float MagField) @@ -233,9 +235,6 @@ class CollisionSelection : public BaseSelection mSphericityMax) { return false; } - if (col.trackOccupancyInTimeRange() < mOccupancyMin || col.trackOccupancyInTimeRange() > mOccupancyMax) { - return false; - } return true; } @@ -260,6 +259,9 @@ class CollisionSelection : public BaseSelectionevaluateObservable(kIsGoodItsLayer0123, static_cast(col.selection_bit(o2::aod::evsel::kIsGoodITSLayer0123))); this->evaluateObservable(kIsGoodItsLayersAll, static_cast(col.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll))); + this->evaluateObservable(kOccupancyMin, col.trackOccupancyInTimeRange()); + this->evaluateObservable(kOccupancyMax, col.trackOccupancyInTimeRange()); + this->assembleBitmask(); }; @@ -275,8 +277,6 @@ class CollisionSelection : public BaseSelection producedCollision; o2::framework::Produces producedCollisionMask; - o2::framework::Produces producedOccupancy; o2::framework::Produces producedQns; o2::framework::Produces producedPositions; o2::framework::Produces producedMultiplicityEstimators; @@ -298,7 +297,6 @@ struct ConfCollisionTables : o2::framework::ConfigurableGroup { std::string prefix = std::string("CollisionTables"); o2::framework::Configurable produceCollisions{"produceCollisions", -1, "Produce Collisions (-1: auto; 0 off; 1 on)"}; o2::framework::Configurable produceCollisionMasks{"produceCollisionMasks", -1, "Produce Collision Masks (-1: auto; 0 off; 1 on)"}; - o2::framework::Configurable produceOccupancy{"produceOccupancy", -1, "Produce Occupancy (-1: auto; 0 off; 1 on)"}; o2::framework::Configurable produceQns{"produceQns", -1, "Produce Qn (-1: auto; 0 off; 1 on)"}; o2::framework::Configurable producePositions{"producePositions", -1, "Produce Positions (-1: auto; 0 off; 1 on)"}; o2::framework::Configurable produceMults{"produceMults", -1, "Produce Multiplicities (-1: auto; 0 off; 1 on)"}; @@ -323,7 +321,6 @@ class CollisionBuilder LOG(info) << "Initialize femto collision builder..."; mProducedCollisions = utils::enableTable("FCols_001", table.produceCollisions.value, initContext); mProducedCollisionMasks = utils::enableTable("FColMasks_001", table.produceCollisionMasks.value, initContext); - mProduceOccupancy = utils::enableTable("FColOccs_001", table.produceOccupancy.value, initContext); mProduceQns = utils::enableTable("FColQnBins_001", table.produceQns.value, initContext); mProducedPositions = utils::enableTable("FColPos_001", table.producePositions.value, initContext); mProducedMultiplicities = utils::enableTable("FColMults_001", table.produceMults.value, initContext); @@ -378,9 +375,6 @@ class CollisionBuilder if (mProducedCollisionMasks) { collisionProducts.producedCollisionMask(mCollisionSelection.getBitmask()); } - if (mProduceOccupancy) { - collisionProducts.producedOccupancy(col.trackOccupancyInTimeRange()); - } if (mProducedPositions) { collisionProducts.producedPositions(col.posX(), col.posY()); @@ -416,7 +410,6 @@ class CollisionBuilder bool mFillAnyTable = false; bool mProducedCollisions = false; bool mProducedCollisionMasks = false; - bool mProduceOccupancy = false; bool mProduceQns = false; bool mProducedPositions = false; bool mProducedMultiplicities = false; diff --git a/PWGCF/Femto/Core/dataTypes.h b/PWGCF/Femto/Core/dataTypes.h index f1c317fae73..54cef607b7b 100644 --- a/PWGCF/Femto/Core/dataTypes.h +++ b/PWGCF/Femto/Core/dataTypes.h @@ -28,12 +28,13 @@ namespace femtodatatypes using CollisionMaskType = uint16_t; // datatypes for tracks +using MomentumType = uint16_t; using TrackMaskType = uint64_t; using TrackType = uint16_t; // datatypes for v0s using V0MaskType = uint16_t; -using V0Type = uint8_t; +using V0Type = uint16_t; // datatypes for kinks using KinkMaskType = uint32_t; @@ -42,14 +43,11 @@ using KinkType = uint8_t; // datatypes for two track resonances using TwoTrackResonanceMaskType = uint32_t; // two track resonance types -using TwoTrackResonanceType = uint8_t; +using TwoTrackResonanceType = uint16_t; // datatypes for cascades using CascadeMaskType = uint16_t; -using CascadeType = uint8_t; - -// datatypes for pairs -using PairType = uint8_t; +using CascadeType = uint16_t; } // namespace femtodatatypes diff --git a/PWGCF/Femto/Core/femtoUtils.h b/PWGCF/Femto/Core/femtoUtils.h index 10f81cf3669..13a8bfb981f 100644 --- a/PWGCF/Femto/Core/femtoUtils.h +++ b/PWGCF/Femto/Core/femtoUtils.h @@ -184,6 +184,12 @@ inline bool enableTable(const char* tableName, int userSetting, o2::framework::I return required; } +template +inline int sign(T value) +{ + return (value > 0) - (value < 0); // Returns 1 for positive, -1 for negative, 0 for zero +} + }; // namespace utils }; // namespace o2::analysis::femto #endif // PWGCF_FEMTO_CORE_FEMTOUTILS_H_ diff --git a/PWGCF/Femto/Core/modes.h b/PWGCF/Femto/Core/modes.h index 012442bb3f1..752df384b7a 100644 --- a/PWGCF/Femto/Core/modes.h +++ b/PWGCF/Femto/Core/modes.h @@ -65,6 +65,11 @@ enum class System : uint32_t { kPbPb_Run2 = kPbPb | kRun2, }; +enum class MomentumType : o2::aod::femtodatatypes::MomentumType { + kPAtPv, // momentum at primary vertex + kPt, // transverse momentum +}; + enum class Track : o2::aod::femtodatatypes::TrackType { kPrimaryTrack, kV0Daughter, @@ -96,22 +101,6 @@ enum class TwoTrackResonance : o2::aod::femtodatatypes::TwoTrackResonanceType { kKstar0Bar }; -enum class Pairs : o2::aod::femtodatatypes::PairType { - kTrackTrack, - kTrackV0, - kTrackResonance, - kTrackCascade, - kTrackKink -}; - -enum class TrackPairs : o2::aod::femtodatatypes::PairType { - kTrackTrack, - kTrackPosDaughter, - kTrackNegDaughter, - kTrackBachelor, - kTrackChaDaughter -}; - }; // namespace modes }; // namespace o2::analysis::femto #endif // PWGCF_FEMTO_CORE_MODES_H_ diff --git a/PWGCF/Femto/Core/pairBuilder.h b/PWGCF/Femto/Core/pairBuilder.h new file mode 100644 index 00000000000..e1d7ff5091a --- /dev/null +++ b/PWGCF/Femto/Core/pairBuilder.h @@ -0,0 +1,296 @@ +// 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 pairBuilder.h +/// \brief histogram manager for pair tasks +/// \author anton.riedel@tum.de, TU München, anton.riedel@tum.de + +#ifndef PWGCF_FEMTO_CORE_PAIRBUILDER_H_ +#define PWGCF_FEMTO_CORE_PAIRBUILDER_H_ + +#include "PWGCF/Femto/Core/closePairRejection.h" +#include "PWGCF/Femto/Core/collisionHistManager.h" +#include "PWGCF/Femto/Core/modes.h" +#include "PWGCF/Femto/Core/pairCleaner.h" +#include "PWGCF/Femto/Core/pairHistManager.h" +#include "PWGCF/Femto/Core/pairProcessHelpers.h" +#include "PWGCF/Femto/Core/trackHistManager.h" +#include "PWGCF/Femto/Core/v0HistManager.h" +#include "PWGCF/Femto/DataModel/FemtoTables.h" + +#include "Framework/HistogramRegistry.h" + +#include +#include +#include + +namespace o2::analysis::femto +{ +namespace pairbuilder +{ + +template < + const char* prefixTrack1, + const char* prefixTrack2, + const char* prefixSe, + const char* prefixMe, + const char* prefixCprSe, + const char* prefixCprMe, + modes::Mode mode> +class PairTrackTrackBuilder +{ + public: + PairTrackTrackBuilder() = default; + + template + void init(o2::framework::HistogramRegistry* registry, + T1& confTrackSelection1, + T2& confTrackSelection2, + T3& confCpr, + T4& confMixing, + std::map>& colHistSpec, + std::map>& trackHistSpec1, + std::map>& trackHistSpec2, + std::map>& pairHistSpec, + std::map>& cprHistSpec) + { + + // check if correlate the same tracks or not + mSameSpecies = confMixing.sameSpecies.value; + + mColHistManager.init(registry, colHistSpec); + mPairHistManagerSe.init(registry, pairHistSpec); + mPairHistManagerMe.init(registry, pairHistSpec); + + if (mSameSpecies) { + mTrackHistManager1.init(registry, trackHistSpec1); + + mPairHistManagerSe.setMass(confTrackSelection1.pdgCode.value, confTrackSelection1.pdgCode.value); + mCprSe.init(registry, cprHistSpec, confCpr.detaMax.value, confCpr.dphistarMax.value, confTrackSelection1.sign.value, confTrackSelection1.absCharge.value, confTrackSelection1.sign.value, confTrackSelection1.absCharge.value, confCpr.on.value); + + mPairHistManagerMe.setMass(confTrackSelection1.pdgCode.value, confTrackSelection2.pdgCode.value); + mCprMe.init(registry, cprHistSpec, confCpr.detaMax.value, confCpr.dphistarMax.value, confTrackSelection1.sign.value, confTrackSelection1.absCharge.value, confTrackSelection1.sign.value, confTrackSelection1.absCharge.value, confCpr.on.value); + } else { + mTrackHistManager1.init(registry, trackHistSpec1); + mTrackHistManager2.init(registry, trackHistSpec2); + + mPairHistManagerSe.setMass(confTrackSelection1.pdgCode.value, confTrackSelection2.pdgCode.value); + mCprSe.init(registry, cprHistSpec, confCpr.detaMax.value, confCpr.dphistarMax.value, confTrackSelection1.sign.value, confTrackSelection1.absCharge.value, confTrackSelection2.sign.value, confTrackSelection2.absCharge.value, confCpr.on.value); + + mPairHistManagerMe.setMass(confTrackSelection1.pdgCode.value, confTrackSelection2.pdgCode.value); + mCprMe.init(registry, cprHistSpec, confCpr.detaMax.value, confCpr.dphistarMax.value, confTrackSelection1.sign.value, confTrackSelection1.absCharge.value, confTrackSelection2.sign.value, confTrackSelection2.absCharge.value, confCpr.on.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); + } + } + + template + void processSameEvent(T1 const& col, T2& /*trackTable*/, T3& partition1, T4& partition2, T5& cache) + { + if (mSameSpecies) { + auto trackSlice1 = partition1->sliceByCached(o2::aod::femtobase::stored::collisionId, col.globalIndex(), cache); + if (trackSlice1.size() == 0) { + return; + } + mColHistManager.fill(col); + mCprSe.setMagField(col.magField()); + pairprocesshelpers::processSameEvent(trackSlice1, mTrackHistManager1, mPairHistManagerSe, mCprSe, mRng, mMixIdenticalParticles); + } else { + auto trackSlice1 = partition1->sliceByCached(o2::aod::femtobase::stored::collisionId, col.globalIndex(), cache); + auto trackSlice2 = partition2->sliceByCached(o2::aod::femtobase::stored::collisionId, col.globalIndex(), cache); + if (trackSlice1.size() == 0 || trackSlice2.size() == 0) { + return; + } + mColHistManager.fill(col); + mCprSe.setMagField(col.magField()); + pairprocesshelpers::processSameEvent(trackSlice1, trackSlice2, mTrackHistManager1, mTrackHistManager2, mPairHistManagerSe, mCprSe, mPc); + } + } + + template + void processMixedEvent(T1 const& cols, T2& /*trackTable*/, T3& partition1, T4& partition2, T5& cache, T6& binsVtxMult, T7& binsVtxCent, T8& binsVtxMultCent) + { + + if (mSameSpecies) { + switch (mMixingPolicy) { + case static_cast(pairhistmanager::kVtxMult): + pairprocesshelpers::processMixedEvent(cols, partition1, cache, binsVtxMult, mMixingDepth, mPairHistManagerMe, mCprMe, mPc); + break; + case static_cast(pairhistmanager::kVtxCent): + pairprocesshelpers::processMixedEvent(cols, partition1, cache, binsVtxCent, mMixingDepth, mPairHistManagerMe, mCprMe, mPc); + break; + case static_cast(pairhistmanager::kVtxMultCent): + pairprocesshelpers::processMixedEvent(cols, partition1, cache, binsVtxMultCent, mMixingDepth, mPairHistManagerMe, mCprMe, mPc); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } else { + switch (mMixingPolicy) { + case static_cast(pairhistmanager::kVtxMult): + pairprocesshelpers::processMixedEvent(cols, partition1, partition2, cache, binsVtxMult, mMixingDepth, mPairHistManagerMe, mCprMe, mPc); + break; + case static_cast(pairhistmanager::kVtxCent): + pairprocesshelpers::processMixedEvent(cols, partition1, partition2, cache, binsVtxCent, mMixingDepth, mPairHistManagerMe, mCprMe, mPc); + break; + case static_cast(pairhistmanager::kVtxMultCent): + pairprocesshelpers::processMixedEvent(cols, partition1, partition2, cache, binsVtxMultCent, mMixingDepth, mPairHistManagerMe, mCprMe, mPc); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + } + + private: + colhistmanager::CollisionHistManager mColHistManager; + trackhistmanager::TrackHistManager mTrackHistManager1; + trackhistmanager::TrackHistManager mTrackHistManager2; + pairhistmanager::PairHistManager mPairHistManagerSe; + pairhistmanager::PairHistManager mPairHistManagerMe; + closepairrejection::ClosePairRejectionTrackTrack mCprSe; + closepairrejection::ClosePairRejectionTrackTrack mCprMe; + paircleaner::TrackTrackPairCleaner mPc; + std::mt19937 mRng; + pairhistmanager::MixingPoliciy mMixingPolicy = pairhistmanager::MixingPoliciy::kVtxMult; + bool mSameSpecies = false; + int mMixingDepth = 5; + bool mMixIdenticalParticles = false; +}; + +template < + const char* prefixTrack, + const char* prefixV0, + const char* prefixPosDau, + const char* prefixNegDau, + const char* prefixSe, + const char* prefixMe, + const char* prefixCprSe, + const char* prefixCprMe, + modes::Mode mode, + modes::V0 v0Type> +class PairTrackV0Builder +{ + public: + PairTrackV0Builder() = default; + + template + void init(o2::framework::HistogramRegistry* registry, + T1& confTrackSelection, + T2& confV0Selection, + T3& confCpr, + T4& confMixing, + std::map>& colHistSpec, + std::map>& trackHistSpec, + std::map>& v0HistSpec, + std::map>& posDauHistSpec, + std::map>& negDauHistSpec, + std::map>& pairHistSpec, + std::map>& cprHistSpec) + { + mColHistManager.init(registry, colHistSpec); + + mTrackHistManager.init(registry, trackHistSpec); + mV0HistManager.init(registry, v0HistSpec, posDauHistSpec, negDauHistSpec); + + mPairHistManagerSe.init(registry, pairHistSpec); + mPairHistManagerSe.setMass(confTrackSelection.pdgCode.value, confV0Selection.pdgCode.value); + 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, confV0Selection.pdgCode.value); + 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& /*v0table*/, T5& v0Partition, T6& cache) + { + auto trackSlice = trackPartition->sliceByCached(o2::aod::femtobase::stored::collisionId, col.globalIndex(), cache); + auto v0Slice = v0Partition->sliceByCached(o2::aod::femtobase::stored::collisionId, col.globalIndex(), cache); + if (trackSlice.size() == 0 || v0Slice.size() == 0) { + return; + } + mColHistManager.fill(col); + mCprSe.setMagField(col.magField()); + pairprocesshelpers::processSameEvent(trackSlice, v0Slice, trackTable, mTrackHistManager, mV0HistManager, mPairHistManagerSe, mCprSe, mPc); + } + + template + void processMixedEvent(T1 const& cols, T2& trackTable, T3& trackPartition, T4& v0Partition, T5& cache, T6& binsVtxMult, T7& binsVtxCent, T8& binsVtxMultCent) + { + switch (mMixingPolicy) { + case static_cast(pairhistmanager::kVtxMult): + pairprocesshelpers::processMixedEvent(cols, trackPartition, v0Partition, trackTable, cache, binsVtxMult, mMixingDepth, mPairHistManagerMe, mCprMe, mPc); + break; + case static_cast(pairhistmanager::kVtxCent): + pairprocesshelpers::processMixedEvent(cols, trackPartition, v0Partition, trackTable, cache, binsVtxCent, mMixingDepth, mPairHistManagerMe, mCprMe, mPc); + break; + case static_cast(pairhistmanager::kVtxMultCent): + pairprocesshelpers::processMixedEvent(cols, trackPartition, v0Partition, trackTable, cache, binsVtxMultCent, mMixingDepth, mPairHistManagerMe, mCprMe, mPc); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + + private: + colhistmanager::CollisionHistManager mColHistManager; + trackhistmanager::TrackHistManager mTrackHistManager; + v0histmanager::V0HistManager mV0HistManager; + pairhistmanager::PairHistManager mPairHistManagerSe; + pairhistmanager::PairHistManager mPairHistManagerMe; + closepairrejection::ClosePairRejectionTrackV0 mCprSe; + closepairrejection::ClosePairRejectionTrackV0 mCprMe; + paircleaner::TrackV0PairCleaner mPc; + pairhistmanager::MixingPoliciy mMixingPolicy = pairhistmanager::MixingPoliciy::kVtxMult; + int mMixingDepth = 5; +}; + +} // namespace pairbuilder +} // namespace o2::analysis::femto + +#endif // PWGCF_FEMTO_CORE_PAIRBUILDER_H_ diff --git a/PWGCF/Femto/Core/pairCleaner.h b/PWGCF/Femto/Core/pairCleaner.h index d613db5971a..47608056acf 100644 --- a/PWGCF/Femto/Core/pairCleaner.h +++ b/PWGCF/Femto/Core/pairCleaner.h @@ -16,11 +16,6 @@ #ifndef PWGCF_FEMTO_CORE_PAIRCLEANER_H_ #define PWGCF_FEMTO_CORE_PAIRCLEANER_H_ -#include "PWGCF/Femto/Core/dataTypes.h" -#include "PWGCF/Femto/Core/histManager.h" -#include "PWGCF/Femto/Core/modes.h" -#include "PWGCF/Femto/DataModel/FemtoTables.h" - namespace o2::analysis::femto { namespace paircleaner @@ -63,45 +58,7 @@ class TrackV0PairCleaner : public BasePairCleaner return this->isCleanTrackPair(posDaughter, track) && this->isCleanTrackPair(negDaughter, track); } }; +} // namespace paircleaner +} // namespace o2::analysis::femto -// template -// template -// class PairCleaner -// { -// public: -// /// Destructor -// virtual ~PairCleaner() = default; -// -// template -// bool isCleanPair(const T1& particle1, const T2& particle2) -// { -// if constexpr (modes::isEqual(pair, modes::Pairs::kTrackTrack)) { -// return particle1.globalIndex() != particle2.globalIndex(); -// } -// return true; -// }; -// -// template -// bool isCleanPair(const T1& particle1, const T2& particle2, const T3& /*trackTable*/) -// { -// if constexpr (modes::isEqual(pair, modes::Pairs::kTrackV0) || modes::isEqual(pair, modes::Pairs::kTrackResonance)) { -// auto posDaughter = particle2.template posDau_as(); -// auto negDaughter = particle2.template negDau_as(); -// return (particle1.globalIndex() != posDaughter.globalIndex() && particle1.globalIndex() != negDaughter.globalIndex()); -// } -// if constexpr (modes::isEqual(pair, modes::Pairs::kTrackCascade)) { -// auto posDaughter = particle2.template posDau_as(); -// auto negDaughter = particle2.template negDau_as(); -// auto bachelor = particle2.template bachelor_as(); -// return (particle1.globalIndex() != posDaughter.globalIndex() && -// particle1.globalIndex() != negDaughter.globalIndex() && -// particle1.globalIndex() != bachelor.globalIndex()); -// } -// return true; -// }; -// -// private: -// }; -}; // namespace paircleaner -}; // namespace o2::analysis::femto -#endif // PWGCF_FEMTOUNITED_CORE_PAIRCLEANER_H_ +#endif // PWGCF_FEMTO_CORE_PAIRCLEANER_H_ diff --git a/PWGCF/Femto/Core/pairHistManager.h b/PWGCF/Femto/Core/pairHistManager.h index 7c4546adbb9..e9587180a71 100644 --- a/PWGCF/Femto/Core/pairHistManager.h +++ b/PWGCF/Femto/Core/pairHistManager.h @@ -16,9 +16,13 @@ #ifndef PWGCF_FEMTO_CORE_PAIRHISTMANAGER_H_ #define PWGCF_FEMTO_CORE_PAIRHISTMANAGER_H_ +#include "PWGCF/Femto/Core/closePairRejection.h" +#include "PWGCF/Femto/Core/collisionHistManager.h" #include "PWGCF/Femto/Core/femtoUtils.h" #include "PWGCF/Femto/Core/histManager.h" #include "PWGCF/Femto/Core/modes.h" +#include "PWGCF/Femto/Core/pairCleaner.h" +#include "PWGCF/Femto/Core/trackHistManager.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" #include "Framework/Configurable.h" @@ -164,19 +168,19 @@ class PairHistManager template void setPair(const T1& particle1, const T2& particle2) { - mTrack1 = ROOT::Math::PtEtaPhiMVector{particle1.pt(), particle1.eta(), particle1.phi(), mMass1}; - mTrack2 = ROOT::Math::PtEtaPhiMVector{particle2.pt(), particle2.eta(), particle2.phi(), mMass2}; - auto partSum = mTrack1 + mTrack2; + mParticle1 = ROOT::Math::PtEtaPhiMVector{particle1.pt(), particle1.eta(), particle1.phi(), mMass1}; + mParticle2 = ROOT::Math::PtEtaPhiMVector{particle2.pt(), particle2.eta(), particle2.phi(), mMass2}; + auto partSum = mParticle1 + mParticle2; // set kT - mKt = partSum.Pt(); + mKt = partSum.Pt() / 2.f; // set mT - float averageMass = (mMass1 + mMass2) / 2.; + float averageMass = (mMass1 + mMass2) / 2.f; mMt = std::hypot(mKt, averageMass); // Boost Track1 to the pair rest frame and calculate k* - auto track1 = ROOT::Math::PxPyPzEVector(mTrack1); + auto track1 = ROOT::Math::PxPyPzEVector(mParticle1); ROOT::Math::Boost boostPrf(partSum.BoostToCM()); mKstar = boostPrf(track1).P(); } @@ -186,13 +190,13 @@ class PairHistManager if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kKstar, HistTable)), mKstar); mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kMt, HistTable)), mMt); - mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt1VsPt2, HistTable)), mTrack1.Pt(), mTrack2.Pt()); - mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt1VsKstar, HistTable)), mTrack1.Pt(), mKstar); - mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt1VsMt, HistTable)), mTrack1.Pt(), mMt); - mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt1VsKt, HistTable)), mTrack1.Pt(), mKt); - mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt2VsKstar, HistTable)), mTrack2.Pt(), mKstar); - mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt2VsMt, HistTable)), mTrack2.Pt(), mMt); - mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt2VsKt, HistTable)), mTrack2.Pt(), mKt); + mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt1VsPt2, HistTable)), mParticle1.Pt(), mParticle2.Pt()); + mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt1VsKstar, HistTable)), mParticle1.Pt(), mKstar); + mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt1VsMt, HistTable)), mParticle1.Pt(), mMt); + mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt1VsKt, HistTable)), mParticle1.Pt(), mKt); + mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt2VsKstar, HistTable)), mParticle2.Pt(), mKstar); + mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt2VsMt, HistTable)), mParticle2.Pt(), mMt); + mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt2VsKt, HistTable)), mParticle2.Pt(), mKt); } // if constexpr (isFlagSet(mode, modes::Mode::kQA)) { @@ -204,12 +208,13 @@ class PairHistManager o2::framework::HistogramRegistry* mHistogramRegistry; float mMass1 = 0.f; float mMass2 = 0.f; - ROOT::Math::PtEtaPhiMVector mTrack1{}; - ROOT::Math::PtEtaPhiMVector mTrack2{}; + ROOT::Math::PtEtaPhiMVector mParticle1{}; + ROOT::Math::PtEtaPhiMVector mParticle2{}; float mKstar = 0.f; float mKt = 0.f; float mMt = 0.f; }; + }; // namespace pairhistmanager }; // namespace o2::analysis::femto #endif // PWGCF_FEMTO_CORE_PAIRHISTMANAGER_H_ diff --git a/PWGCF/Femto/Core/pairProcessHelpers.h b/PWGCF/Femto/Core/pairProcessHelpers.h index d0519b60d00..df96b056c16 100644 --- a/PWGCF/Femto/Core/pairProcessHelpers.h +++ b/PWGCF/Femto/Core/pairProcessHelpers.h @@ -16,9 +16,6 @@ #ifndef PWGCF_FEMTO_CORE_PAIRPROCESSHELPERS_H_ #define PWGCF_FEMTO_CORE_PAIRPROCESSHELPERS_H_ -#include "PWGCF/Femto/Core/femtoUtils.h" -#include "PWGCF/Femto/Core/histManager.h" -#include "PWGCF/Femto/Core/modes.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" #include "Framework/ASoAHelpers.h" @@ -81,8 +78,8 @@ template -void processSameEvent(const T1& SliceParticle1, - const T2& SliceParticle2, +void processSameEvent(T1& SliceParticle1, + T2& SliceParticle2, T3& ParticleHistManager1, T4& ParticleHistManager2, T5& PairHistManager, @@ -125,9 +122,9 @@ template -void processSameEvent(const T1& SliceParticle1, - const T2& SliceParticle2, - const T3& TrackTable, +void processSameEvent(T1& SliceParticle1, + T2& SliceParticle2, + T3& TrackTable, T4& ParticleHistManager1, T5& ParticleHistManager2, T6& PairHistManager, @@ -169,32 +166,26 @@ template + typename T8> void processMixedEvent(T1& Collisions, T2& Partition, T3& cache, T4& policy, T5& depth, - T6& ParticleHistManager1, - T7& ParticleHistManager2, - T8& PairHistManager, - T9& CprManager, - T10& PcManager) + T6& PairHistManager, + T7& CprManager, + T8& PcManager) { for (auto const& [collision1, collision2] : o2::soa::selfCombinations(policy, depth, -1, Collisions, Collisions)) { + if (!(std::fabs(collision1.magField() - collision2.magField()) < o2::constants::math::Epsilon)) { + continue; + } + CprManager.setMagField(collision1.magField()); auto sliceParticle1 = Partition->sliceByCached(o2::aod::femtobase::stored::collisionId, collision1.globalIndex(), cache); auto sliceParticle2 = Partition->sliceByCached(o2::aod::femtobase::stored::collisionId, collision2.globalIndex(), cache); if (sliceParticle1.size() == 0 || sliceParticle2.size() == 0) { continue; } - for (auto const& part : sliceParticle1) { - ParticleHistManager1.fill(part); - } - for (auto const& part : sliceParticle2) { - ParticleHistManager2.fill(part); - } for (auto const& [p1, p2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(sliceParticle1, sliceParticle2))) { // pair cleaning if (!PcManager.isCleanPair(p1, p2)) { @@ -223,33 +214,27 @@ template + typename T9> void processMixedEvent(T1& Collisions, T2& Partition1, T3& Partition2, T4& cache, T5& policy, T6& depth, - T7& ParticleHistManager1, - T8& ParticleHistManager2, - T9& PairHistManager, - T10& CprManager, - T11& PcManager) + T7& PairHistManager, + T8& CprManager, + T9& PcManager) { for (auto const& [collision1, collision2] : o2::soa::selfCombinations(policy, depth, -1, Collisions, Collisions)) { + if (!(std::fabs(collision1.magField() - collision2.magField()) < o2::constants::math::Epsilon)) { + continue; + } + CprManager.setMagField(collision1.magField()); auto sliceParticle1 = Partition1->sliceByCached(o2::aod::femtobase::stored::collisionId, collision1.globalIndex(), cache); auto sliceParticle2 = Partition2->sliceByCached(o2::aod::femtobase::stored::collisionId, collision2.globalIndex(), cache); if (sliceParticle1.size() == 0 || sliceParticle2.size() == 0) { continue; } - for (auto const& part : sliceParticle1) { - ParticleHistManager1.fill(part); - } - for (auto const& part : sliceParticle2) { - ParticleHistManager2.fill(part); - } for (auto const& [p1, p2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(sliceParticle1, sliceParticle2))) { // pair cleaning if (!PcManager.isCleanPair(p1, p2)) { @@ -279,9 +264,7 @@ template + typename T10> void processMixedEvent(T1& Collisions, T2& Partition1, T3& Partition2, @@ -289,24 +272,20 @@ void processMixedEvent(T1& Collisions, T5& cache, T6& policy, T7& depth, - T8& ParticleHistManager1, - T9& ParticleHistManager2, - T10& PairHistManager, - T11& CprManager, - T12& PcManager) + T8& PairHistManager, + T9& CprManager, + T10& PcManager) { for (auto const& [collision1, collision2] : o2::soa::selfCombinations(policy, depth, -1, Collisions, Collisions)) { + if (!(std::fabs(collision1.magField() - collision2.magField()) < o2::constants::math::Epsilon)) { + continue; + } + CprManager.setMagField(collision1.magField()); auto sliceParticle1 = Partition1->sliceByCached(o2::aod::femtobase::stored::collisionId, collision1.globalIndex(), cache); auto sliceParticle2 = Partition2->sliceByCached(o2::aod::femtobase::stored::collisionId, collision2.globalIndex(), cache); if (sliceParticle1.size() == 0 || sliceParticle2.size() == 0) { continue; } - for (auto const& part : sliceParticle1) { - ParticleHistManager1.fill(part); - } - for (auto const& part : sliceParticle2) { - ParticleHistManager2.fill(part, TrackTable); - } for (auto const& [p1, p2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(sliceParticle1, sliceParticle2))) { // pair cleaning if (!PcManager.isCleanPair(p1, p2, TrackTable)) { @@ -328,4 +307,4 @@ void processMixedEvent(T1& Collisions, } // namespace pairprocesshelpers } // namespace o2::analysis::femto -#endif // PWGCF_FEMTOUNITED_CORE_PAIRPROCESSHELPERS_H_ +#endif // PWGCF_FEMTO_CORE_PAIRPROCESSHELPERS_H_ diff --git a/PWGCF/Femto/Core/partitions.h b/PWGCF/Femto/Core/partitions.h index a4f0d8c197f..4b4943bed44 100644 --- a/PWGCF/Femto/Core/partitions.h +++ b/PWGCF/Femto/Core/partitions.h @@ -17,26 +17,25 @@ #define PWGCF_FEMTO_CORE_PARTITIONS_H_ // collsion selection -#define MAKE_COLLISION_FILTER(selection) \ - (femtocollisions::posZ >= selection.vtxZMin && femtocollisions::posZ <= selection.vtxZMax) && \ - (femtocollisions::mult >= selection.multMin && femtocollisions::mult <= selection.multMax) && \ - (femtocollisions::cent >= selection.centMin && femtocollisions::cent <= selection.centMax) && \ - (femtocollisions::sphericity >= selection.spherMin && femtocollisions::sphericity <= selection.spherMax) && \ - (femtocollisions::magField >= selection.magFieldMin && femtocollisions::magField <= selection.magFieldMax) && \ - (femtocollisions::occupancy >= selection.occupancyMin && femtocollisions::occupancy <= selection.occupancyMax) && \ +#define MAKE_COLLISION_FILTER(selection) \ + (femtocollisions::posZ >= selection.vtxZMin && femtocollisions::posZ <= selection.vtxZMax) && \ + (femtocollisions::mult >= selection.multMin && femtocollisions::mult <= selection.multMax) && \ + (femtocollisions::cent >= selection.centMin && femtocollisions::cent <= selection.centMax) && \ + (femtocollisions::sphericity >= selection.spherMin && femtocollisions::sphericity <= selection.spherMax) && \ + (femtocollisions::magField >= selection.magFieldMin && femtocollisions::magField <= selection.magFieldMax) && \ ncheckbit(femtocollisions::collisionMask, selection.collisionMask) // standard track partition -#define MAKE_TRACK_PARTITION(selection) \ - ifnode(selection.sign.node() > 0, femtobase::stored::signedPt > 0.f, femtobase::stored::signedPt < 0.f) && \ - (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) && \ - ifnode(nabs(femtobase::stored::signedPt) * (nexp(femtobase::stored::eta) + nexp(-1.f * femtobase::stored::eta)) / 2.f <= selection.pidThres, \ - ncheckbit(femtotracks::trackMask, selection.maskLowMomentum), \ +#define MAKE_TRACK_PARTITION(selection) \ + ifnode(selection.sign.node() > 0, femtobase::stored::signedPt > 0.f, femtobase::stored::signedPt < 0.f) && \ + (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) && \ + ifnode(nabs(femtobase::stored::signedPt) * (nexp(femtobase::stored::eta) + nexp(-1.f * femtobase::stored::eta)) / 2.f <= selection.pidThres, /* o2-linter: disable=magic-number (formula for cosh) */ \ + ncheckbit(femtotracks::trackMask, selection.maskLowMomentum), \ ncheckbit(femtotracks::trackMask, selection.maskHighMomentum)) // partition for phis and rhos, i.e. resonance that are their own antiparticle diff --git a/PWGCF/Femto/Core/trackBuilder.h b/PWGCF/Femto/Core/trackBuilder.h index 9a784acee35..d8e1f3251dd 100644 --- a/PWGCF/Femto/Core/trackBuilder.h +++ b/PWGCF/Femto/Core/trackBuilder.h @@ -118,6 +118,7 @@ struct ConfTrackSelection : public o2::framework::ConfigurableGroup { // configuration parameters o2::framework::Configurable pdgCode{"pdgCode", 2212, "Track PDG code"}; o2::framework::Configurable sign{"sign", 1, "Sign of the track (1 for positive tracks and -1 for negative tracks)"}; + o2::framework::Configurable absCharge{"absCharge", 1, "Absolute charge of the track (keep 1 for all tracks, except for He, it should be 2)"}; // filters for kinematics o2::framework::Configurable ptMin{"ptMin", 0.2f, "Minimum pT (GeV/c)"}; o2::framework::Configurable ptMax{"ptMax", 6.f, "Maximum pT (GeV/c)"}; @@ -443,7 +444,7 @@ struct ConfTrackTables : o2::framework::ConfigurableGroup { class TrackBuilder { public: - TrackBuilder() {} + TrackBuilder() = default; virtual ~TrackBuilder() = default; template diff --git a/PWGCF/Femto/Core/trackHistManager.h b/PWGCF/Femto/Core/trackHistManager.h index 677e88e5487..fa80af22106 100644 --- a/PWGCF/Femto/Core/trackHistManager.h +++ b/PWGCF/Femto/Core/trackHistManager.h @@ -146,6 +146,7 @@ using ConfKinkChaDauBinning = ConfTrackBinning; template struct ConfTrackQaBinning : o2::framework::ConfigurableGroup { std::string prefix = Prefix; + o2::framework::Configurable momentumType{"momentumType", 0, "Momentum on x-axis (0->Pt, 1->P at PV"}; o2::framework::ConfigurableAxis itsCluster{"itsCluster", {{8, -0.5, 7.5}}, "ITS cluster"}; o2::framework::ConfigurableAxis itsClusterIb{"itsClusterIb", {{4, -0.5, 3.5}}, "ITS cluster in inner barrel"}; o2::framework::ConfigurableAxis tpcCrossedRows{"tpcCrossedRows", {{161, -0.5, 160.5}}, "TPC cluster"}; @@ -396,7 +397,7 @@ class TrackHistManager /// Destructor virtual ~TrackHistManager() = default; - void init(o2::framework::HistogramRegistry* registry, std::map> Specs) + void init(o2::framework::HistogramRegistry* registry, std::map> Specs, int momentumTypeForPid = 0) { mHistogramRegistry = registry; @@ -410,6 +411,7 @@ class TrackHistManager } if constexpr (isFlagSet(mode, modes::Mode::kQa)) { + std::string qaDir = std::string(prefix) + std::string(QaDir); mHistogramRegistry->add(qaDir + GetHistNamev2(kItsCluster, HistTable), GetHistDesc(kItsCluster, HistTable), GetHistType(kItsCluster, HistTable), {Specs[kItsCluster]}); @@ -435,6 +437,8 @@ class TrackHistManager std::string pidDir = std::string(prefix) + std::string(PidDir); + mMomentumType = static_cast(momentumTypeForPid); + mHistogramRegistry->add(pidDir + GetHistNamev2(kItsSignal, HistTable), GetHistDesc(kItsSignal, HistTable), GetHistType(kItsSignal, HistTable), {Specs[kItsSignal]}); mHistogramRegistry->add(pidDir + GetHistNamev2(kItsElectron, HistTable), GetHistDesc(kItsElectron, HistTable), GetHistType(kItsElectron, HistTable), {Specs[kItsElectron]}); mHistogramRegistry->add(pidDir + GetHistNamev2(kItsPion, HistTable), GetHistDesc(kItsPion, HistTable), GetHistType(kItsPion, HistTable), {Specs[kItsPion]}); @@ -511,55 +515,64 @@ class TrackHistManager mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kPtVsDcaz, HistTable)), track.pt(), track.dcaZ()); mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kPtVsDca, HistTable)), track.pt(), track.dca()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kItsSignal, HistTable)), track.p(), o2::analysis::femto::utils::itsSignal(track)); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kItsElectron, HistTable)), track.p(), track.itsNSigmaEl()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kItsPion, HistTable)), track.p(), track.itsNSigmaPi()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kItsKaon, HistTable)), track.p(), track.itsNSigmaKa()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kItsProton, HistTable)), track.p(), track.itsNSigmaPr()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kItsDeuteron, HistTable)), track.p(), track.itsNSigmaDe()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kItsTriton, HistTable)), track.p(), track.itsNSigmaTr()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kItsHelium, HistTable)), track.p(), track.itsNSigmaHe()); - - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcSignal, HistTable)), track.p(), track.tpcSignal()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcElectron, HistTable)), track.p(), track.tpcNSigmaEl()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcPion, HistTable)), track.p(), track.tpcNSigmaPi()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcKaon, HistTable)), track.p(), track.tpcNSigmaKa()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcProton, HistTable)), track.p(), track.tpcNSigmaPr()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcDeuteron, HistTable)), track.p(), track.tpcNSigmaDe()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcTriton, HistTable)), track.p(), track.tpcNSigmaTr()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcHelium, HistTable)), track.p(), track.tpcNSigmaHe()); - - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTofBeta, HistTable)), track.p(), track.tofBeta()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTofMass, HistTable)), track.p(), track.tofMass()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTofElectron, HistTable)), track.p(), track.tofNSigmaEl()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTofPion, HistTable)), track.p(), track.tofNSigmaPi()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTofKaon, HistTable)), track.p(), track.tofNSigmaKa()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTofProton, HistTable)), track.p(), track.tofNSigmaPr()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTofDeuteron, HistTable)), track.p(), track.tofNSigmaDe()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTofTriton, HistTable)), track.p(), track.tofNSigmaTr()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTofHelium, HistTable)), track.p(), track.tofNSigmaHe()); - - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcitsElectron, HistTable)), track.p(), track.tpcitsNSigmaEl()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcitsPion, HistTable)), track.p(), track.tpcitsNSigmaPi()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcitsKaon, HistTable)), track.p(), track.tpcitsNSigmaKa()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcitsProton, HistTable)), track.p(), track.tpcitsNSigmaPr()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcitsDeuteron, HistTable)), track.p(), track.tpcitsNSigmaDe()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcitsTriton, HistTable)), track.p(), track.tpcitsNSigmaTr()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcitsHelium, HistTable)), track.p(), track.tpcitsNSigmaHe()); - - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpctofElectron, HistTable)), track.p(), track.tpctofNSigmaEl()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpctofPion, HistTable)), track.p(), track.tpctofNSigmaPi()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpctofKaon, HistTable)), track.p(), track.tpctofNSigmaKa()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpctofProton, HistTable)), track.p(), track.tpctofNSigmaPr()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpctofDeuteron, HistTable)), track.p(), track.tpctofNSigmaDe()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpctofTriton, HistTable)), track.p(), track.tpctofNSigmaTr()); - mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpctofHelium, HistTable)), track.p(), track.tpctofNSigmaHe()); + float momentum = 0.f; + if (mMomentumType == modes::MomentumType::kPAtPv) { + momentum = track.p(); + } else if (mMomentumType == modes::MomentumType::kPt) { + momentum = track.pt(); + } + + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kItsSignal, HistTable)), momentum, o2::analysis::femto::utils::itsSignal(track)); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kItsElectron, HistTable)), momentum, track.itsNSigmaEl()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kItsPion, HistTable)), momentum, track.itsNSigmaPi()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kItsKaon, HistTable)), momentum, track.itsNSigmaKa()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kItsProton, HistTable)), momentum, track.itsNSigmaPr()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kItsDeuteron, HistTable)), momentum, track.itsNSigmaDe()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kItsTriton, HistTable)), momentum, track.itsNSigmaTr()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kItsHelium, HistTable)), momentum, track.itsNSigmaHe()); + + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcSignal, HistTable)), momentum, track.tpcSignal()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcElectron, HistTable)), momentum, track.tpcNSigmaEl()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcPion, HistTable)), momentum, track.tpcNSigmaPi()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcKaon, HistTable)), momentum, track.tpcNSigmaKa()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcProton, HistTable)), momentum, track.tpcNSigmaPr()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcDeuteron, HistTable)), momentum, track.tpcNSigmaDe()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcTriton, HistTable)), momentum, track.tpcNSigmaTr()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcHelium, HistTable)), momentum, track.tpcNSigmaHe()); + + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTofBeta, HistTable)), momentum, track.tofBeta()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTofMass, HistTable)), momentum, track.tofMass()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTofElectron, HistTable)), momentum, track.tofNSigmaEl()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTofPion, HistTable)), momentum, track.tofNSigmaPi()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTofKaon, HistTable)), momentum, track.tofNSigmaKa()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTofProton, HistTable)), momentum, track.tofNSigmaPr()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTofDeuteron, HistTable)), momentum, track.tofNSigmaDe()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTofTriton, HistTable)), momentum, track.tofNSigmaTr()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTofHelium, HistTable)), momentum, track.tofNSigmaHe()); + + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcitsElectron, HistTable)), momentum, track.tpcitsNSigmaEl()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcitsPion, HistTable)), momentum, track.tpcitsNSigmaPi()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcitsKaon, HistTable)), momentum, track.tpcitsNSigmaKa()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcitsProton, HistTable)), momentum, track.tpcitsNSigmaPr()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcitsDeuteron, HistTable)), momentum, track.tpcitsNSigmaDe()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcitsTriton, HistTable)), momentum, track.tpcitsNSigmaTr()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpcitsHelium, HistTable)), momentum, track.tpcitsNSigmaHe()); + + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpctofElectron, HistTable)), momentum, track.tpctofNSigmaEl()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpctofPion, HistTable)), momentum, track.tpctofNSigmaPi()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpctofKaon, HistTable)), momentum, track.tpctofNSigmaKa()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpctofProton, HistTable)), momentum, track.tpctofNSigmaPr()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpctofDeuteron, HistTable)), momentum, track.tpctofNSigmaDe()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpctofTriton, HistTable)), momentum, track.tpctofNSigmaTr()); + mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kTpctofHelium, HistTable)), momentum, track.tpctofNSigmaHe()); } } private: - o2::framework::HistogramRegistry* mHistogramRegistry; + o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; + modes::MomentumType mMomentumType = modes::MomentumType::kPAtPv; }; }; // namespace trackhistmanager +// aespace trackhistmanager }; // namespace o2::analysis::femto #endif // PWGCF_FEMTO_CORE_TRACKHISTMANAGER_H_ diff --git a/PWGCF/Femto/Core/v0HistManager.h b/PWGCF/Femto/Core/v0HistManager.h index 7dc732b84b1..d767791d558 100644 --- a/PWGCF/Femto/Core/v0HistManager.h +++ b/PWGCF/Femto/Core/v0HistManager.h @@ -182,9 +182,11 @@ std::map> makeV0QaHistSpecMap(T1 const& }; constexpr char PrefixLambdaQa[] = "LambdaQA/"; -constexpr char PrefixLambda[] = "Lambda/"; +constexpr char PrefixLambda1[] = "Lambda1/"; +constexpr char PrefixLambda2[] = "Lambda2/"; constexpr char PrefixK0shortQa[] = "K0shortQa/"; -constexpr char PrefixK0short[] = "K0short/"; +constexpr char PrefixK0short1[] = "K0short1/"; +constexpr char PrefixK0short2[] = "K0short2/"; constexpr char PrefixLambdaCascade[] = "LambdaCascadeQa/"; diff --git a/PWGCF/Femto/DataModel/FemtoTables.h b/PWGCF/Femto/DataModel/FemtoTables.h index 8c4d2208313..9f87b6a6d24 100644 --- a/PWGCF/Femto/DataModel/FemtoTables.h +++ b/PWGCF/Femto/DataModel/FemtoTables.h @@ -43,7 +43,6 @@ DECLARE_SOA_COLUMN(Mult, mult, float); //! Multiplicity estimator se DECLARE_SOA_COLUMN(Cent, cent, float); //! Centrality (~= multiplicity percentile) estimator set by producer DECLARE_SOA_COLUMN(MagField, magField, float); //! Magnetic field of the event DECLARE_SOA_COLUMN(Sphericity, sphericity, float); //! Sphericity of the event -DECLARE_SOA_COLUMN(Occupancy, occupancy, float); //! occupancy of the event DECLARE_SOA_COLUMN(Qn, qn, float); //! qn bins for dividing events } // namespace femtocollisions @@ -62,11 +61,6 @@ DECLARE_SOA_TABLE_STAGED_VERSIONED(FColMasks_001, "FCOLMASK", 1, //! track masks femtocollisions::CollisionMask); using FColMasks = FColMasks_001; -// table for occupancy -DECLARE_SOA_TABLE_STAGED_VERSIONED(FColOccs_001, "FCOLOCC", 1, //! occupancy - femtocollisions::Occupancy); -using FColOccs = FColOccs_001; - // table for qn values DECLARE_SOA_TABLE_STAGED_VERSIONED(FColQns_001, "FCOLQN", 1, //! qn vector femtocollisions::Qn); diff --git a/PWGCF/Femto/Tasks/femtoCascadeQa.cxx b/PWGCF/Femto/Tasks/femtoCascadeQa.cxx index 97c6bce428b..4d1bd1953d7 100644 --- a/PWGCF/Femto/Tasks/femtoCascadeQa.cxx +++ b/PWGCF/Femto/Tasks/femtoCascadeQa.cxx @@ -46,7 +46,7 @@ using namespace o2::analysis::femto; struct FemtoCascadeQa { // setup tables - using Collisions = Join; + using Collisions = Join; using Collision = Collisions::iterator; using FilteredCollisions = o2::soa::Filtered; diff --git a/PWGCF/Femto/Tasks/femtoKinkQa.cxx b/PWGCF/Femto/Tasks/femtoKinkQa.cxx index 1fdb4e58693..a416ba5993f 100644 --- a/PWGCF/Femto/Tasks/femtoKinkQa.cxx +++ b/PWGCF/Femto/Tasks/femtoKinkQa.cxx @@ -48,14 +48,14 @@ using namespace o2::analysis::femto; struct FemtoKinkQa { // setup for collisions - collisionbuilder::ConfCollisionFilters collisionSelection; + collisionbuilder::ConfCollisionSelection collisionSelection; Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); colhistmanager::CollisionHistManager colHistManager; colhistmanager::ConfCollisionBinning confCollisionBinning; // using Collisions = o2::soa::Join; - using Collisions = FCols; + using Collisions = Join; using Collision = Collisions::iterator; using FilteredCollisions = o2::soa::Filtered; diff --git a/PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx b/PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx index b16c48ff19b..b0d7f54baa3 100644 --- a/PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx +++ b/PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx @@ -16,10 +16,7 @@ #include "PWGCF/Femto/Core/closePairRejection.h" #include "PWGCF/Femto/Core/collisionBuilder.h" #include "PWGCF/Femto/Core/collisionHistManager.h" -#include "PWGCF/Femto/Core/modes.h" -#include "PWGCF/Femto/Core/pairCleaner.h" -#include "PWGCF/Femto/Core/pairHistManager.h" -#include "PWGCF/Femto/Core/pairProcessHelpers.h" +#include "PWGCF/Femto/Core/pairBuilder.h" #include "PWGCF/Femto/Core/partitions.h" #include "PWGCF/Femto/Core/trackBuilder.h" #include "PWGCF/Femto/Core/trackHistManager.h" @@ -32,8 +29,6 @@ #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" -#include -#include #include #include @@ -47,7 +42,7 @@ using namespace o2::analysis::femto; struct FemtoPairTrackTrack { // setup tables - using Collisions = FCols; + using Collisions = Join; using Collision = Collisions::iterator; using FilteredCollisions = o2::soa::Filtered; @@ -61,25 +56,31 @@ struct FemtoPairTrackTrack { collisionbuilder::ConfCollisionSelection collisionSelection; Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); colhistmanager::ConfCollisionBinning confCollisionBinning; - colhistmanager::CollisionHistManager colHistManager; // setup tracks trackbuilder::ConfTrackSelection1 trackSelections1; trackhistmanager::ConfTrackBinning1 confTrackBinning1; - trackhistmanager::TrackHistManager trackHistManager1; - Partition trackPartition1 = MAKE_TRACK_PARTITION(trackSelections1); - trackbuilder::ConfTrackSelection2 trackSelections2; trackhistmanager::ConfTrackBinning2 confTrackBinning2; - trackhistmanager::TrackHistManager trackHistManager2; - Partition trackPartition2 = MAKE_TRACK_PARTITION(trackSelections1); + + Partition trackPartition1 = MAKE_TRACK_PARTITION(trackSelections1); + Partition trackPartition2 = MAKE_TRACK_PARTITION(trackSelections2); Preslice perColReco = aod::femtobase::stored::collisionId; // setup pairs pairhistmanager::ConfPairBinning confPairBinning; - pairhistmanager::PairHistManager pairHistManagerSe; - pairhistmanager::PairHistManager pairHistManagerMe; + closepairrejection::ConfCpr confCpr; + + pairbuilder::PairTrackTrackBuilder< + trackhistmanager::PrefixTrack1, + trackhistmanager::PrefixTrack2, + pairhistmanager::PrefixTrackTrackSe, + pairhistmanager::PrefixTrackTrackMe, + closepairrejection::PrefixTrackTrackSe, + closepairrejection::PrefixTrackTrackMe, + modes::Mode::kAnalysis> + pairTrackTrackBuilder; // setup mixing std::vector defaultVtxBins{10, -10, 10}; @@ -91,119 +92,39 @@ struct FemtoPairTrackTrack { pairhistmanager::ConfMixing confMixing; HistogramRegistry hRegistry{"FemtoTrackTrack", {}, OutputObjHandlingPolicy::AnalysisObject}; - std::mt19937 rng; - bool mixParticles = false; - - // setup cpr - closepairrejection::ConfCpr confCpr; - closepairrejection::ClosePairRejectionTrackTrack cprSe; - closepairrejection::ClosePairRejectionTrackTrack cprMe; - paircleaner::TrackTrackPairCleaner pc; 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 for tracks + // setup histogram specs auto colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); - colHistManager.init(&hRegistry, colHistSpec); - auto trackHistSpec1 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning1); - trackHistManager1.init(&hRegistry, trackHistSpec1); - auto trackHistSpec2 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning2); - trackHistManager2.init(&hRegistry, trackHistSpec2); - - // setup histograms for pair auto pairHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning, confTrackBinning1, confTrackBinning2); - pairHistManagerSe.init(&hRegistry, pairHistSpec); - pairHistManagerSe.setMass(trackSelections1.pdgCode.value, trackSelections2.pdgCode.value); - pairHistManagerMe.init(&hRegistry, pairHistSpec); - pairHistManagerMe.setMass(trackSelections1.pdgCode.value, trackSelections2.pdgCode.value); - - // setup histograms for cpr auto cprHistSpec = closepairrejection::makeCprHistSpecMap(confCpr); - cprSe.init(&hRegistry, cprHistSpec, confCpr.detaMax.value, confCpr.dphistarMax.value, confCpr.on.value); - cprMe.init(&hRegistry, cprHistSpec, confCpr.detaMax.value, confCpr.dphistarMax.value, confCpr.on.value); - - // setup rng if necessary - if (confMixing.seed.value >= 0) { - uint64_t randomSeed = 0; - mixParticles = 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); - } - rng = std::mt19937(randomSeed); - } + + pairTrackTrackBuilder.init(&hRegistry, trackSelections1, trackSelections2, confCpr, confMixing, colHistSpec, trackHistSpec1, trackHistSpec2, pairHistSpec, cprHistSpec); }; - void processSameEvent(FilteredCollision const& col, Tracks const& /*tracks*/) + void processSameEvent(FilteredCollision const& col, Tracks const& tracks) { - if (confMixing.sameSpecies) { - auto trackSlice1 = trackPartition1->sliceByCached(femtobase::stored::collisionId, col.globalIndex(), cache); - if (trackSlice1.size() == 0) { - return; - } - colHistManager.fill(col); - cprSe.setMagField(col.magField()); - pairprocesshelpers::processSameEvent(trackSlice1, trackHistManager1, pairHistManagerSe, cprSe, rng, mixParticles); - } else { - auto trackSlice1 = trackPartition1->sliceByCached(femtobase::stored::collisionId, col.globalIndex(), cache); - auto trackSlice2 = trackPartition2->sliceByCached(femtobase::stored::collisionId, col.globalIndex(), cache); - if (trackSlice1.size() == 0 || trackSlice2.size() == 0) { - return; - } - colHistManager.fill(col); - cprSe.setMagField(col.magField()); - pairprocesshelpers::processSameEvent(trackSlice1, trackSlice2, trackHistManager1, trackHistManager2, pairHistManagerSe, cprSe, pc); - } + pairTrackTrackBuilder.processSameEvent(col, tracks, trackPartition1, trackPartition2, cache); } PROCESS_SWITCH(FemtoPairTrackTrack, processSameEvent, "Enable processing same event processing", true); - void processMixedEvent(FilteredCollisions const& cols, Tracks const& /*tracks*/) + void processMixedEvent(FilteredCollisions const& cols, Tracks const& tracks) { - if (confMixing.sameSpecies) { - switch (confMixing.policy.value) { - case static_cast(pairhistmanager::kVtxMult): - pairprocesshelpers::processMixedEvent(cols, trackPartition1, cache, mixBinsVtxMult, confMixing.depth.value, trackHistManager1, trackHistManager2, pairHistManagerMe, cprMe, pc); - break; - case static_cast(pairhistmanager::kVtxCent): - pairprocesshelpers::processMixedEvent(cols, trackPartition1, cache, mixBinsVtxCent, confMixing.depth.value, trackHistManager1, trackHistManager2, pairHistManagerMe, cprMe, pc); - break; - case static_cast(pairhistmanager::kVtxMultCent): - pairprocesshelpers::processMixedEvent(cols, trackPartition1, cache, mixBinsVtxMultCent, confMixing.depth.value, trackHistManager1, trackHistManager2, pairHistManagerMe, cprMe, pc); - break; - default: - LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; - } - } else { - switch (confMixing.policy.value) { - case static_cast(pairhistmanager::kVtxMult): - pairprocesshelpers::processMixedEvent(cols, trackPartition1, trackPartition2, cache, mixBinsVtxMult, confMixing.depth.value, trackHistManager1, trackHistManager2, pairHistManagerMe, cprMe, pc); - break; - case static_cast(pairhistmanager::kVtxCent): - pairprocesshelpers::processMixedEvent(cols, trackPartition1, trackPartition2, cache, mixBinsVtxCent, confMixing.depth.value, trackHistManager1, trackHistManager2, pairHistManagerMe, cprMe, pc); - break; - case static_cast(pairhistmanager::kVtxMultCent): - pairprocesshelpers::processMixedEvent(cols, trackPartition1, trackPartition2, cache, mixBinsVtxMultCent, confMixing.depth.value, trackHistManager1, trackHistManager2, pairHistManagerMe, cprMe, pc); - break; - default: - LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; - } - } + pairTrackTrackBuilder.processMixedEvent(cols, tracks, trackPartition1, trackPartition2, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackTrack, processMixedEvent, "Enable processing mixed event processing", true); }; -WorkflowSpec - defineDataProcessing(ConfigContext const& cfgc) +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { WorkflowSpec workflow{ adaptAnalysisTask(cfgc), diff --git a/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx b/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx index 893d72561a5..0433d9fbae7 100644 --- a/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx +++ b/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx @@ -9,17 +9,16 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file femtounitedPairTrackV0.cxx -/// \brief Tasks that computes correlation between tracks and lambdas +/// \file femtoPairTrackV0.cxx +/// \brief Tasks that computes correlation between tracks and v0s /// \author Anton Riedel, TU München, anton.riedel@cern.ch #include "PWGCF/Femto/Core/closePairRejection.h" #include "PWGCF/Femto/Core/collisionBuilder.h" #include "PWGCF/Femto/Core/collisionHistManager.h" #include "PWGCF/Femto/Core/modes.h" -#include "PWGCF/Femto/Core/pairCleaner.h" +#include "PWGCF/Femto/Core/pairBuilder.h" #include "PWGCF/Femto/Core/pairHistManager.h" -#include "PWGCF/Femto/Core/pairProcessHelpers.h" #include "PWGCF/Femto/Core/partitions.h" #include "PWGCF/Femto/Core/trackBuilder.h" #include "PWGCF/Femto/Core/trackHistManager.h" @@ -34,8 +33,6 @@ #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" -#include -#include #include #include @@ -46,10 +43,10 @@ using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::analysis::femto; -struct FemtounitedPairTrackV0 { +struct FemtoPairTrackV0 { // setup tables - using Collisions = FCols; + using Collisions = Join; using Collision = Collisions::iterator; using FilteredCollisions = o2::soa::Filtered; @@ -65,13 +62,11 @@ struct FemtounitedPairTrackV0 { collisionbuilder::ConfCollisionSelection collisionSelection; Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); colhistmanager::ConfCollisionBinning confCollisionBinning; - colhistmanager::CollisionHistManager colHistManager; // setup tracks - trackbuilder::ConfTrackSelection1 trackSelections; + trackbuilder::ConfTrackSelection1 trackSelection; trackhistmanager::ConfTrackBinning1 confTrackBinning; - trackhistmanager::TrackHistManager trackHistManager; - Partition trackPartition = MAKE_TRACK_PARTITION(trackSelections); + Partition trackPartition = MAKE_TRACK_PARTITION(trackSelection); Preslice perColTracks = aod::femtobase::stored::collisionId; // setup for daughters @@ -81,33 +76,43 @@ struct FemtounitedPairTrackV0 { // setup lambdas v0builder::ConfLambdaSelection1 lambdaSelection; v0histmanager::ConfLambdaBinning1 confLambdaBinning; - v0histmanager::V0HistManager< - v0histmanager::PrefixLambda, - trackhistmanager::PrefixV0PosDaughter, - trackhistmanager::PrefixV0NegDaughter, - modes::Mode::kAnalysis, - modes::V0::kLambda> - lambdaHistManager; Partition lambdaPartition = MAKE_LAMBDA_PARTITION(lambdaSelection); Preslice perColLambdas = aod::femtobase::stored::collisionId; // setup k0shorts v0builder::ConfK0shortSelection1 k0shortSelection; v0histmanager::ConfK0shortBinning1 confK0shortBinning; - v0histmanager::V0HistManager< - v0histmanager::PrefixK0short, - trackhistmanager::PrefixV0PosDaughter, - trackhistmanager::PrefixV0NegDaughter, - modes::Mode::kAnalysis, - modes::V0::kK0short> - k0shortHistManager; Partition k0shortPartition = MAKE_K0SHORT_PARTITION(k0shortSelection); Preslice perColk0shorts = aod::femtobase::stored::collisionId; // setup pairs pairhistmanager::ConfPairBinning confPairBinning; - pairhistmanager::PairHistManager pairHistManagerSe; - pairhistmanager::PairHistManager pairHistManagerMe; + + pairbuilder::PairTrackV0Builder< + trackhistmanager::PrefixTrack1, + v0histmanager::PrefixLambda1, + trackhistmanager::PrefixV0PosDaughter, + trackhistmanager::PrefixV0NegDaughter, + pairhistmanager::PrefixTrackV0Se, + pairhistmanager::PrefixTrackV0Me, + closepairrejection::PrefixTrackV0Se, + closepairrejection::PrefixTrackV0Me, + modes::Mode::kAnalysis, + modes::V0::kLambda> + pairTrackLambdaBuilder; + + pairbuilder::PairTrackV0Builder< + trackhistmanager::PrefixTrack1, + v0histmanager::PrefixK0short1, + trackhistmanager::PrefixV0PosDaughter, + trackhistmanager::PrefixV0NegDaughter, + pairhistmanager::PrefixTrackV0Se, + pairhistmanager::PrefixTrackV0Me, + closepairrejection::PrefixTrackV0Se, + closepairrejection::PrefixTrackV0Me, + modes::Mode::kAnalysis, + modes::V0::kK0short> + pairTrackK0shortBuilder; // setup mixing std::vector defaultVtxBins{10, -10, 10}; @@ -122,9 +127,6 @@ struct FemtounitedPairTrackV0 { // setup cpr closepairrejection::ConfCpr confCpr; - closepairrejection::ClosePairRejectionTrackV0 cprSe; - closepairrejection::ClosePairRejectionTrackV0 cprMe; - paircleaner::TrackV0PairCleaner pc; void init(InitContext&) { @@ -135,113 +137,62 @@ struct FemtounitedPairTrackV0 { mixBinsVtxCent = {{confMixing.vtxBins.value, confMixing.centBins.value}, true}; mixBinsVtxMultCent = {{confMixing.vtxBins.value, confMixing.multBins.value, confMixing.centBins.value}, true}; - // setup histograms for tracks + // setup histograms auto colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); - colHistManager.init(&hRegistry, colHistSpec); - - auto trackHistSpec1 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning); - trackHistManager.init(&hRegistry, trackHistSpec1); - - // setup for daughters + auto trackHistSpec = trackhistmanager::makeTrackHistSpecMap(confTrackBinning); auto posDauSpec = trackhistmanager::makeTrackHistSpecMap(confPosDauBinning); auto negDauSpec = trackhistmanager::makeTrackHistSpecMap(confNegDauBinning); + auto pairHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning, confTrackBinning, confLambdaBinning); + auto cprHistSpec = closepairrejection::makeCprHistSpecMap(confCpr); // setup for lambda - if (doprocessLambdaSameEvent || doprocessLambdaMixedEvent) { + // if (doprocessLambdaSameEvent || doprocessLambdaMixedEvent) { + if (doprocessLambdaSameEvent) { auto lambdaHistSpec = v0histmanager::makeV0HistSpecMap(confLambdaBinning); - lambdaHistManager.init(&hRegistry, lambdaHistSpec, posDauSpec, negDauSpec); + pairTrackLambdaBuilder.init(&hRegistry, trackSelection, lambdaSelection, confCpr, confMixing, colHistSpec, trackHistSpec, lambdaHistSpec, posDauSpec, negDauSpec, pairHistSpec, cprHistSpec); } - if (((doprocessLambdaSameEvent || doprocessLambdaMixedEvent) + (doprocessK0shortSameEvent || doprocessK0shortMixedEvent)) > 1) { - LOG(fatal) << "Can only process lambda-tracks Or k0short-tracks"; - } + // if (((doprocessLambdaSameEvent || doprocessLambdaMixedEvent) + (doprocessK0shortSameEvent || doprocessK0shortMixedEvent)) > 1) { + // LOG(fatal) << "Can only process lambda-tracks Or k0short-tracks"; + // } // setup for k0short - if (doprocessK0shortSameEvent || doprocessK0shortMixedEvent) { + // if (doprocessK0shortSameEvent || doprocessK0shortMixedEvent) { + if (doprocessK0shortSameEvent) { auto k0shortHistSpec = v0histmanager::makeV0HistSpecMap(confK0shortBinning); - k0shortHistManager.init(&hRegistry, k0shortHistSpec, posDauSpec, negDauSpec); + pairTrackK0shortBuilder.init(&hRegistry, trackSelection, lambdaSelection, confCpr, confMixing, colHistSpec, trackHistSpec, k0shortHistSpec, posDauSpec, negDauSpec, pairHistSpec, cprHistSpec); } - - // setup histograms for pair - auto pairHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning, confTrackBinning, confLambdaBinning); - pairHistManagerSe.init(&hRegistry, pairHistSpec); - pairHistManagerSe.setMass(trackSelections.pdgCode.value, lambdaSelection.pdgCode.value); - pairHistManagerMe.init(&hRegistry, pairHistSpec); - pairHistManagerMe.setMass(trackSelections.pdgCode.value, lambdaSelection.pdgCode.value); - - // setup histograms for cpr - auto cprHistSpec = closepairrejection::makeCprHistSpecMap(confCpr); - cprSe.init(&hRegistry, cprHistSpec, confCpr.detaMax.value, confCpr.dphistarMax.value, confCpr.on.value); - cprMe.init(&hRegistry, cprHistSpec, confCpr.detaMax.value, confCpr.dphistarMax.value, confCpr.on.value); }; - void processLambdaSameEvent(FilteredCollision const& col, Tracks const& tracks, Lambdas const& /*lambdas*/) + void processLambdaSameEvent(FilteredCollision const& col, Tracks const& tracks, Lambdas const& lambdas) { - auto trackSlice = trackPartition->sliceByCached(femtobase::stored::collisionId, col.globalIndex(), cache); - auto lambdaSlice = lambdaPartition->sliceByCached(femtobase::stored::collisionId, col.globalIndex(), cache); - if (trackSlice.size() == 0 || lambdaSlice.size() == 0) { - return; - } - colHistManager.fill(col); - cprSe.setMagField(col.magField()); - pairprocesshelpers::processSameEvent(trackSlice, lambdaSlice, tracks, trackHistManager, lambdaHistManager, pairHistManagerSe, cprSe, pc); + pairTrackLambdaBuilder.processSameEvent(col, tracks, trackPartition, lambdas, lambdaPartition, cache); } - PROCESS_SWITCH(FemtounitedPairTrackV0, processLambdaSameEvent, "Enable processing same event processing for tracks and lambdas", true); + PROCESS_SWITCH(FemtoPairTrackV0, processLambdaSameEvent, "Enable processing same event processing for tracks and lambdas", true); - void processLambdaMixedEvent(FilteredCollisions const& cols, Tracks const& tracks) + void processLambdaMixedEvent(FilteredCollisions const& cols, Tracks const& tracks, Lambdas const& /*lambas*/) { - switch (confMixing.policy.value) { - case static_cast(pairhistmanager::kVtxMult): - pairprocesshelpers::processMixedEvent(cols, trackPartition, lambdaPartition, tracks, cache, mixBinsVtxMult, confMixing.depth.value, trackHistManager, lambdaHistManager, pairHistManagerMe, cprMe, pc); - break; - case static_cast(pairhistmanager::kVtxCent): - pairprocesshelpers::processMixedEvent(cols, trackPartition, lambdaPartition, tracks, cache, mixBinsVtxCent, confMixing.depth.value, trackHistManager, lambdaHistManager, pairHistManagerMe, cprMe, pc); - break; - case static_cast(pairhistmanager::kVtxMultCent): - pairprocesshelpers::processMixedEvent(cols, trackPartition, lambdaPartition, tracks, cache, mixBinsVtxMultCent, confMixing.depth.value, trackHistManager, lambdaHistManager, pairHistManagerMe, cprMe, pc); - break; - default: - LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; - } + pairTrackLambdaBuilder.processMixedEvent(cols, tracks, trackPartition, lambdaPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } - PROCESS_SWITCH(FemtounitedPairTrackV0, processLambdaMixedEvent, "Enable processing mixed event processing for tracks and lambdas", true); - - void processK0shortSameEvent(FilteredCollision const& col, Tracks const& tracks, K0shorts const& /*k0shorts*/) + PROCESS_SWITCH(FemtoPairTrackV0, processLambdaMixedEvent, "Enable processing mixed event processing for tracks and lambdas", true); + // + void processK0shortSameEvent(FilteredCollision const& col, Tracks const& tracks, K0shorts const& k0shorts) { - auto trackSlice = trackPartition->sliceByCached(femtobase::stored::collisionId, col.globalIndex(), cache); - auto k0shortSlice = k0shortPartition->sliceByCached(femtobase::stored::collisionId, col.globalIndex(), cache); - if (trackSlice.size() == 0 || k0shortSlice.size() == 0) { - return; - } - colHistManager.fill(col); - cprSe.setMagField(col.magField()); - pairprocesshelpers::processSameEvent(trackSlice, k0shortSlice, tracks, trackHistManager, k0shortHistManager, pairHistManagerSe, cprSe, pc); + pairTrackK0shortBuilder.processSameEvent(col, tracks, trackPartition, k0shorts, k0shortPartition, cache); } - PROCESS_SWITCH(FemtounitedPairTrackV0, processK0shortSameEvent, "Enable processing same event processing for tracks and k0shorts", false); + PROCESS_SWITCH(FemtoPairTrackV0, processK0shortSameEvent, "Enable processing same event processing for tracks and k0shorts", false); - void processK0shortMixedEvent(FilteredCollisions const& cols, Tracks const& tracks) + void processK0shortMixedEvent(FilteredCollisions const& cols, Tracks const& tracks, K0shorts const& /*k0shorts*/) { - switch (confMixing.policy.value) { - case static_cast(pairhistmanager::kVtxMult): - pairprocesshelpers::processMixedEvent(cols, trackPartition, k0shortPartition, tracks, cache, mixBinsVtxMult, confMixing.depth.value, trackHistManager, k0shortHistManager, pairHistManagerMe, cprMe, pc); - break; - case static_cast(pairhistmanager::kVtxCent): - pairprocesshelpers::processMixedEvent(cols, trackPartition, k0shortPartition, tracks, cache, mixBinsVtxCent, confMixing.depth.value, trackHistManager, k0shortHistManager, pairHistManagerMe, cprMe, pc); - break; - case static_cast(pairhistmanager::kVtxMultCent): - pairprocesshelpers::processMixedEvent(cols, trackPartition, k0shortPartition, tracks, cache, mixBinsVtxMultCent, confMixing.depth.value, trackHistManager, k0shortHistManager, pairHistManagerMe, cprMe, pc); - break; - default: - LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; - } + pairTrackK0shortBuilder.processMixedEvent(cols, tracks, trackPartition, k0shortPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } - PROCESS_SWITCH(FemtounitedPairTrackV0, processK0shortMixedEvent, "Enable processing mixed event processing for tracks and k0shorts", false); + PROCESS_SWITCH(FemtoPairTrackV0, processK0shortMixedEvent, "Enable processing mixed event processing for tracks and k0shorts", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), }; return workflow; } diff --git a/PWGCF/Femto/Tasks/femtoTrackQa.cxx b/PWGCF/Femto/Tasks/femtoTrackQa.cxx index de1c8bd1181..57fd9d3862e 100644 --- a/PWGCF/Femto/Tasks/femtoTrackQa.cxx +++ b/PWGCF/Femto/Tasks/femtoTrackQa.cxx @@ -43,7 +43,7 @@ using namespace o2::analysis::femto; struct FemtoTrackQa { // setup tables - using Collisions = o2::soa::Join; + using Collisions = o2::soa::Join; using Collision = Collisions::iterator; using FilteredCollisions = o2::soa::Filtered; @@ -76,7 +76,7 @@ struct FemtoTrackQa { auto colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); colHistManager.init(&hRegistry, colHistSpec); auto trackHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confTrackBinning, confTrackQaBinning); - trackHistManager.init(&hRegistry, trackHistSpec); + trackHistManager.init(&hRegistry, trackHistSpec, confTrackQaBinning.momentumType.value); }; void process(FilteredCollision const& col, Tracks const& /*tracks*/) diff --git a/PWGCF/Femto/Tasks/femtoTwotrackresonanceQa.cxx b/PWGCF/Femto/Tasks/femtoTwotrackresonanceQa.cxx index 7ecdd2c4102..5e7b6192ae7 100644 --- a/PWGCF/Femto/Tasks/femtoTwotrackresonanceQa.cxx +++ b/PWGCF/Femto/Tasks/femtoTwotrackresonanceQa.cxx @@ -44,7 +44,7 @@ using namespace o2::analysis::femto; struct FemtoTwotrackresonanceQa { // setup tables - using Collisions = Join; + using Collisions = Join; using Collision = Collisions::iterator; using FilteredCollisions = o2::soa::Filtered; diff --git a/PWGCF/Femto/Tasks/femtoV0Qa.cxx b/PWGCF/Femto/Tasks/femtoV0Qa.cxx index 56e3f7a6869..089d2975e1d 100644 --- a/PWGCF/Femto/Tasks/femtoV0Qa.cxx +++ b/PWGCF/Femto/Tasks/femtoV0Qa.cxx @@ -53,7 +53,7 @@ struct FemtoV0Qa { colhistmanager::ConfCollisionBinning confCollisionBinning; // using Collisions = o2::soa::Join; - using Collisions = o2::soa::Join; + using Collisions = o2::soa::Join; using Collision = Collisions::iterator; using FilteredCollisions = o2::soa::Filtered; From 2d3ac1e0ce20ce9c76705be3750237fbc6ac014f Mon Sep 17 00:00:00 2001 From: Anton Riedel Date: Tue, 23 Sep 2025 10:58:36 +0200 Subject: [PATCH 3/4] Feat: add absolute charge as configurable --- PWGCF/Femto/Core/pairBuilder.h | 8 +++++++- PWGCF/Femto/Core/pairHistManager.h | 16 +++++++++++----- PWGCF/Femto/Core/trackHistManager.h | 26 ++++++++++++++------------ PWGCF/Femto/Tasks/femtoTrackQa.cxx | 2 +- 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/PWGCF/Femto/Core/pairBuilder.h b/PWGCF/Femto/Core/pairBuilder.h index e1d7ff5091a..2d82529ca87 100644 --- a/PWGCF/Femto/Core/pairBuilder.h +++ b/PWGCF/Femto/Core/pairBuilder.h @@ -82,18 +82,22 @@ class PairTrackTrackBuilder mTrackHistManager1.init(registry, trackHistSpec1); mPairHistManagerSe.setMass(confTrackSelection1.pdgCode.value, confTrackSelection1.pdgCode.value); + mPairHistManagerSe.setCharge(confTrackSelection1.absCharge.value, confTrackSelection1.absCharge.value); mCprSe.init(registry, cprHistSpec, confCpr.detaMax.value, confCpr.dphistarMax.value, confTrackSelection1.sign.value, confTrackSelection1.absCharge.value, confTrackSelection1.sign.value, confTrackSelection1.absCharge.value, confCpr.on.value); - mPairHistManagerMe.setMass(confTrackSelection1.pdgCode.value, confTrackSelection2.pdgCode.value); + mPairHistManagerMe.setMass(confTrackSelection1.pdgCode.value, confTrackSelection1.pdgCode.value); + mPairHistManagerMe.setCharge(confTrackSelection1.absCharge.value, confTrackSelection1.absCharge.value); mCprMe.init(registry, cprHistSpec, confCpr.detaMax.value, confCpr.dphistarMax.value, confTrackSelection1.sign.value, confTrackSelection1.absCharge.value, confTrackSelection1.sign.value, confTrackSelection1.absCharge.value, confCpr.on.value); } else { mTrackHistManager1.init(registry, trackHistSpec1); mTrackHistManager2.init(registry, trackHistSpec2); mPairHistManagerSe.setMass(confTrackSelection1.pdgCode.value, confTrackSelection2.pdgCode.value); + mPairHistManagerSe.setCharge(confTrackSelection1.absCharge.value, confTrackSelection2.absCharge.value); mCprSe.init(registry, cprHistSpec, confCpr.detaMax.value, confCpr.dphistarMax.value, confTrackSelection1.sign.value, confTrackSelection1.absCharge.value, confTrackSelection2.sign.value, confTrackSelection2.absCharge.value, confCpr.on.value); mPairHistManagerMe.setMass(confTrackSelection1.pdgCode.value, confTrackSelection2.pdgCode.value); + mPairHistManagerMe.setCharge(confTrackSelection1.absCharge.value, confTrackSelection2.absCharge.value); mCprMe.init(registry, cprHistSpec, confCpr.detaMax.value, confCpr.dphistarMax.value, confTrackSelection1.sign.value, confTrackSelection1.absCharge.value, confTrackSelection2.sign.value, confTrackSelection2.absCharge.value, confCpr.on.value); } @@ -235,10 +239,12 @@ class PairTrackV0Builder mPairHistManagerSe.init(registry, pairHistSpec); mPairHistManagerSe.setMass(confTrackSelection.pdgCode.value, confV0Selection.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, confV0Selection.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 diff --git a/PWGCF/Femto/Core/pairHistManager.h b/PWGCF/Femto/Core/pairHistManager.h index e9587180a71..c256c09b9af 100644 --- a/PWGCF/Femto/Core/pairHistManager.h +++ b/PWGCF/Femto/Core/pairHistManager.h @@ -133,9 +133,6 @@ class PairHistManager public: /// Destructor virtual ~PairHistManager() = default; - /// Initializes histograms for the task - /// \param registry Histogram registry to be passed - /// void init(o2::framework::HistogramRegistry* registry, std::map> Specs) { mHistogramRegistry = registry; @@ -164,12 +161,19 @@ class PairHistManager mMass1 = o2::analysis::femto::utils::getMass(PdgParticle1); mMass2 = o2::analysis::femto::utils::getMass(PdgParticle2); } + void setCharge(int chargeParticle1, int chargeParticle2) + { + mAbsCharge1 = std::fabs(chargeParticle1); + mAbsCharge1 = std::fabs(chargeParticle2); + } template void setPair(const T1& particle1, const T2& particle2) { - mParticle1 = ROOT::Math::PtEtaPhiMVector{particle1.pt(), particle1.eta(), particle1.phi(), mMass1}; - mParticle2 = ROOT::Math::PtEtaPhiMVector{particle2.pt(), particle2.eta(), particle2.phi(), mMass2}; + // pt in track stable is stored from 1/signedPt from the original track table + // in case of He with Z=2, we have to rescale the pt with the absolute charge + mParticle1 = ROOT::Math::PtEtaPhiMVector{mAbsCharge1 * particle1.pt(), particle1.eta(), particle1.phi(), mMass1}; + mParticle2 = ROOT::Math::PtEtaPhiMVector{mAbsCharge2 * particle2.pt(), particle2.eta(), particle2.phi(), mMass2}; auto partSum = mParticle1 + mParticle2; // set kT @@ -208,6 +212,8 @@ class PairHistManager o2::framework::HistogramRegistry* mHistogramRegistry; float mMass1 = 0.f; float mMass2 = 0.f; + float mAbsCharge1 = 1.f; + float mAbsCharge2 = 1.f; ROOT::Math::PtEtaPhiMVector mParticle1{}; ROOT::Math::PtEtaPhiMVector mParticle2{}; float mKstar = 0.f; diff --git a/PWGCF/Femto/Core/trackHistManager.h b/PWGCF/Femto/Core/trackHistManager.h index fa80af22106..197c47983cc 100644 --- a/PWGCF/Femto/Core/trackHistManager.h +++ b/PWGCF/Femto/Core/trackHistManager.h @@ -397,9 +397,10 @@ class TrackHistManager /// Destructor virtual ~TrackHistManager() = default; - void init(o2::framework::HistogramRegistry* registry, std::map> Specs, int momentumTypeForPid = 0) + void init(o2::framework::HistogramRegistry* registry, std::map> Specs, float charge = 1, int momentumTypeForPid = 0) { mHistogramRegistry = registry; + mAbsCharge = std::fabs(charge); if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { std::string analysisDir = std::string(prefix) + std::string(AnalysisDir); @@ -489,7 +490,7 @@ class TrackHistManager void fill(T const& track) { if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { - mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt, HistTable)), track.pt()); + mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPt, HistTable)), mAbsCharge * track.pt()); mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kEta, HistTable)), track.eta()); mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kPhi, HistTable)), track.phi()); mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(GetHistName(kSign, HistTable)), track.sign()); @@ -503,23 +504,23 @@ class TrackHistManager mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kTpcClusterShared, HistTable)), static_cast(track.tpcNClsShared())); mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kTpcClusterFractionShared, HistTable)), track.tpcSharedOverFound()); - mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kPtVsEta, HistTable)), track.pt(), track.eta()); - mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kPtVsPhi, HistTable)), track.pt(), track.phi()); + mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kPtVsEta, HistTable)), mAbsCharge * track.pt(), track.eta()); + mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kPtVsPhi, HistTable)), mAbsCharge * track.pt(), track.phi()); mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kPhiVsEta, HistTable)), track.phi(), track.eta()); - mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kPtVsItsCluster, HistTable)), track.pt(), static_cast(track.itsNCls())); - mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kPtVsTpcCluster, HistTable)), track.pt(), static_cast(track.tpcNClsFound())); - mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kPtVsTpcClusterShared, HistTable)), track.pt(), static_cast(track.tpcNClsShared())); + mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kPtVsItsCluster, HistTable)), mAbsCharge * track.pt(), static_cast(track.itsNCls())); + mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kPtVsTpcCluster, HistTable)), mAbsCharge * track.pt(), static_cast(track.tpcNClsFound())); + mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kPtVsTpcClusterShared, HistTable)), mAbsCharge * track.pt(), static_cast(track.tpcNClsShared())); mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kTpcClusterVsTpcClusterShared, HistTable)), static_cast(track.tpcNClsFound()), static_cast(track.tpcNClsShared())); - mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kPtVsDcaxy, HistTable)), track.pt(), track.dcaXY()); - mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kPtVsDcaz, HistTable)), track.pt(), track.dcaZ()); - mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kPtVsDca, HistTable)), track.pt(), track.dca()); + mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kPtVsDcaxy, HistTable)), mAbsCharge * track.pt(), track.dcaXY()); + mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kPtVsDcaz, HistTable)), mAbsCharge * track.pt(), track.dcaZ()); + mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(GetHistName(kPtVsDca, HistTable)), mAbsCharge * track.pt(), track.dca()); float momentum = 0.f; if (mMomentumType == modes::MomentumType::kPAtPv) { - momentum = track.p(); + momentum = mAbsCharge * track.p(); } else if (mMomentumType == modes::MomentumType::kPt) { - momentum = track.pt(); + momentum = mAbsCharge * track.pt(); } mHistogramRegistry->fill(HIST(prefix) + HIST(PidDir) + HIST(GetHistName(kItsSignal, HistTable)), momentum, o2::analysis::femto::utils::itsSignal(track)); @@ -570,6 +571,7 @@ class TrackHistManager private: o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; + float mAbsCharge = 1; modes::MomentumType mMomentumType = modes::MomentumType::kPAtPv; }; }; // namespace trackhistmanager diff --git a/PWGCF/Femto/Tasks/femtoTrackQa.cxx b/PWGCF/Femto/Tasks/femtoTrackQa.cxx index 57fd9d3862e..53338a1852d 100644 --- a/PWGCF/Femto/Tasks/femtoTrackQa.cxx +++ b/PWGCF/Femto/Tasks/femtoTrackQa.cxx @@ -76,7 +76,7 @@ struct FemtoTrackQa { auto colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); colHistManager.init(&hRegistry, colHistSpec); auto trackHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confTrackBinning, confTrackQaBinning); - trackHistManager.init(&hRegistry, trackHistSpec, confTrackQaBinning.momentumType.value); + trackHistManager.init(&hRegistry, trackHistSpec, trackSelections.absCharge.value, confTrackQaBinning.momentumType.value); }; void process(FilteredCollision const& col, Tracks const& /*tracks*/) From ac2381c0eca880f2d7c20aaf63aa176de9b17f35 Mon Sep 17 00:00:00 2001 From: Anton Riedel Date: Tue, 23 Sep 2025 12:41:53 +0200 Subject: [PATCH 4/4] Fix: fix histogram naming --- PWGCF/Femto/Tasks/femtoPairTrackV0.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx b/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx index 0433d9fbae7..4ff228948f6 100644 --- a/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx +++ b/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx @@ -123,7 +123,7 @@ struct FemtoPairTrackV0 { ColumnBinningPolicy mixBinsVtxMultCent{{defaultVtxBins, defaultMultBins, defaultCentBins}, true}; pairhistmanager::ConfMixing confMixing; - HistogramRegistry hRegistry{"FemtoTrackTrack", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry hRegistry{"FemtoTrackV0", {}, OutputObjHandlingPolicy::AnalysisObject}; // setup cpr closepairrejection::ConfCpr confCpr;