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 new file mode 100644 index 00000000000..4a693b89267 --- /dev/null +++ b/PWGCF/Femto/Core/closePairRejection.h @@ -0,0 +1,265 @@ +// 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/femtoUtils.h" +#include "PWGCF/Femto/Core/histManager.h" + +#include "Framework/HistogramRegistry.h" + +#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", {{500, -0.5, 0.5}}, "deta"}; + o2::framework::ConfigurableAxis binningDphistar{"binningDphistar", {{500, -0.5, 0.5}}, "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 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 +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) +{ + 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() = default; + virtual ~CloseTrackRejection() = default; + + void init(o2::framework::HistogramRegistry* registry, std::map>& specs, float detaMax, float dphistarMax, int chargeTrack1, int chargeTrack2) + { + mDetaMax = detaMax; + mDphistarMax = dphistarMax; + + 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; } + + template + void compute(const T1& track1, const T2& track2) + { + // reset values + mAverageDphistar = 0.f; + mDeta = 0.f; + mDphistar.fill(0.f); + + mDeta = track1.eta() - track2.eta(); + 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.at(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 + 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 + { + return std::hypot(mAverageDphistar / mDphistarMax, mDeta / mDetaMax) < 1.f; + } + + private: + int mChargeTrack1 = 0; + int mChargeTrack2 = 0; + float mMagField = 0.f; + float mAverageDphistar = 0.f; + float mDeta = 0.f; + float mDetaMax = 0.f; + float mDphistarMax = 0.f; + std::array mDphistar = {0.f}; + + o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; +}; + +template +class ClosePairRejectionTrackTrack +{ + public: + 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, signTrack1 * absChargeTrack1, signTrack2 * AbsChargeTrack2); + } + + 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, int signTrack, int absChargeTrack, bool isActivated) + { + mIsActivated = isActivated; + 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) + { + mCtr.setMagField(magField); + } + template + void setPair(const T1& track, const T2& v0, const T3 /*trackTable*/) + { + 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 mCtr.isClosePair(); } + void fill() + { + mCtr.fill(); + } + bool isActivated() const { return mIsActivated; } + + private: + CloseTrackRejection mCtr; + int mSignTrack = 0; + bool mIsActivated = true; +}; + +}; // namespace closepairrejection +}; // namespace o2::analysis::femto +#endif // PWGCF_FEMTO_CORE_CLOSEPAIRREJECTION_H_ diff --git a/PWGCF/Femto/Core/collisionBuilder.h b/PWGCF/Femto/Core/collisionBuilder.h index b33619dcf6f..96c64645c7a 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" @@ -49,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)"}; }; @@ -70,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 { @@ -79,6 +80,22 @@ 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 collisionMask{"collisionMask", 0, "Bitmask for collision"}; +}; + /// enum for all collision selections enum CollisionSels { // collsion selection flags @@ -95,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 }; @@ -113,9 +132,11 @@ 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 +class CollisionSelection : public BaseSelection { public: CollisionSelection() {} @@ -135,8 +156,6 @@ class CollisionSelection : public BaseSelectionaddSelection(config.sel8.value, kSel8); @@ -151,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) @@ -214,9 +235,6 @@ class CollisionSelection : public BaseSelection mSphericityMax) { return false; } - if (col.trackOccupancyInTimeRange() < mOccupancyMin || col.trackOccupancyInTimeRange() > mOccupancyMax) { - return false; - } return true; } @@ -241,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(); }; @@ -256,8 +277,6 @@ class CollisionSelection : public BaseSelection producedCollision; - o2::framework::Produces produceCollisionMask; - o2::framework::Produces producedOccupancy; + o2::framework::Produces producedCollisionMask; o2::framework::Produces producedQns; o2::framework::Produces producedPositions; o2::framework::Produces producedMultiplicityEstimators; @@ -279,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)"}; @@ -304,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); @@ -356,11 +372,9 @@ class CollisionBuilder mCollisionSelection.getSphericity(), mCollisionSelection.getMagneticField()); } - - if (mProduceOccupancy) { - collisionProducts.producedOccupancy(col.trackOccupancyInTimeRange()); + if (mProducedCollisionMasks) { + collisionProducts.producedCollisionMask(mCollisionSelection.getBitmask()); } - if (mProducedPositions) { collisionProducts.producedPositions(col.posX(), col.posY()); @@ -396,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/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..54cef607b7b 100644 --- a/PWGCF/Femto/Core/dataTypes.h +++ b/PWGCF/Femto/Core/dataTypes.h @@ -25,15 +25,16 @@ 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 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..2d82529ca87 --- /dev/null +++ b/PWGCF/Femto/Core/pairBuilder.h @@ -0,0 +1,302 @@ +// 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); + 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, 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); + } + + // 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); + 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 + 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 new file mode 100644 index 00000000000..47608056acf --- /dev/null +++ b/PWGCF/Femto/Core/pairCleaner.h @@ -0,0 +1,64 @@ +// 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_ + +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); + } +}; +} // namespace paircleaner +} // namespace o2::analysis::femto + +#endif // PWGCF_FEMTO_CORE_PAIRCLEANER_H_ diff --git a/PWGCF/Femto/Core/pairHistManager.h b/PWGCF/Femto/Core/pairHistManager.h new file mode 100644 index 00000000000..c256c09b9af --- /dev/null +++ b/PWGCF/Femto/Core/pairHistManager.h @@ -0,0 +1,226 @@ +// 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/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" +#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; + 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); + } + void setCharge(int chargeParticle1, int chargeParticle2) + { + mAbsCharge1 = std::fabs(chargeParticle1); + mAbsCharge1 = std::fabs(chargeParticle2); + } + + template + void setPair(const T1& particle1, const T2& particle2) + { + // 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 + mKt = partSum.Pt() / 2.f; + + // set mT + 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(mParticle1); + 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)), 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)) { + // 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; + float mAbsCharge1 = 1.f; + float mAbsCharge2 = 1.f; + 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 new file mode 100644 index 00000000000..df96b056c16 --- /dev/null +++ b/PWGCF/Femto/Core/pairProcessHelpers.h @@ -0,0 +1,310 @@ +// 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/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(T1& SliceParticle1, + 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(T1& SliceParticle1, + T2& SliceParticle2, + 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& 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& [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& 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& [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& 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& [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_FEMTO_CORE_PAIRPROCESSHELPERS_H_ diff --git a/PWGCF/Femto/Core/partitions.h b/PWGCF/Femto/Core/partitions.h index ffbdf6fd214..4b4943bed44 100644 --- a/PWGCF/Femto/Core/partitions.h +++ b/PWGCF/Femto/Core/partitions.h @@ -16,25 +16,26 @@ #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) && \ + 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..197c47983cc 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,9 +397,10 @@ class TrackHistManager /// Destructor virtual ~TrackHistManager() = default; - void init(o2::framework::HistogramRegistry* registry, std::map> Specs) + 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); @@ -410,6 +412,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 +438,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]}); @@ -485,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()); @@ -499,67 +504,77 @@ 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(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()); + 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 = mAbsCharge * track.p(); + } else if (mMomentumType == modes::MomentumType::kPt) { + momentum = mAbsCharge * 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; + float mAbsCharge = 1; + 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 c7bc8334c52..9f87b6a6d24 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 @@ -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); @@ -274,50 +268,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..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 = 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/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 new file mode 100644 index 00000000000..b0d7f54baa3 --- /dev/null +++ b/PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx @@ -0,0 +1,133 @@ +// 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/pairBuilder.h" +#include "PWGCF/Femto/Core/partitions.h" +#include "PWGCF/Femto/Core/trackBuilder.h" +#include "PWGCF/Femto/Core/trackHistManager.h" +#include "PWGCF/Femto/DataModel/FemtoTables.h" + +#include "Framework/ASoA.h" +#include "Framework/AnalysisTask.h" +#include "Framework/Configurable.h" +#include "Framework/Expressions.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + +#include +#include + +using namespace o2; +using namespace o2::aod; +using namespace o2::soa; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::analysis::femto; + +struct FemtoPairTrackTrack { + + // setup tables + using Collisions = Join; + 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; + + // setup tracks + trackbuilder::ConfTrackSelection1 trackSelections1; + trackhistmanager::ConfTrackBinning1 confTrackBinning1; + trackbuilder::ConfTrackSelection2 trackSelections2; + trackhistmanager::ConfTrackBinning2 confTrackBinning2; + + Partition trackPartition1 = MAKE_TRACK_PARTITION(trackSelections1); + Partition trackPartition2 = MAKE_TRACK_PARTITION(trackSelections2); + + Preslice perColReco = aod::femtobase::stored::collisionId; + + // setup pairs + pairhistmanager::ConfPairBinning confPairBinning; + 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}; + 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}; + + 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 histogram specs + auto colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); + auto trackHistSpec1 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning1); + auto trackHistSpec2 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning2); + auto pairHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning, confTrackBinning1, confTrackBinning2); + auto cprHistSpec = closepairrejection::makeCprHistSpecMap(confCpr); + + pairTrackTrackBuilder.init(&hRegistry, trackSelections1, trackSelections2, confCpr, confMixing, colHistSpec, trackHistSpec1, trackHistSpec2, pairHistSpec, cprHistSpec); + }; + + void processSameEvent(FilteredCollision const& col, Tracks const& tracks) + { + 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) + { + 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 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..4ff228948f6 --- /dev/null +++ b/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx @@ -0,0 +1,198 @@ +// 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 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/pairBuilder.h" +#include "PWGCF/Femto/Core/pairHistManager.h" +#include "PWGCF/Femto/Core/partitions.h" +#include "PWGCF/Femto/Core/trackBuilder.h" +#include "PWGCF/Femto/Core/trackHistManager.h" +#include "PWGCF/Femto/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 + +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 FemtoPairTrackV0 { + + // setup tables + using Collisions = Join; + 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; + + // setup tracks + trackbuilder::ConfTrackSelection1 trackSelection; + trackhistmanager::ConfTrackBinning1 confTrackBinning; + Partition trackPartition = MAKE_TRACK_PARTITION(trackSelection); + Preslice perColTracks = aod::femtobase::stored::collisionId; + + // setup for daughters + trackhistmanager::ConfV0PosDauBinning confPosDauBinning; + trackhistmanager::ConfV0NegDauBinning confNegDauBinning; + + // setup lambdas + v0builder::ConfLambdaSelection1 lambdaSelection; + v0histmanager::ConfLambdaBinning1 confLambdaBinning; + Partition lambdaPartition = MAKE_LAMBDA_PARTITION(lambdaSelection); + Preslice perColLambdas = aod::femtobase::stored::collisionId; + + // setup k0shorts + v0builder::ConfK0shortSelection1 k0shortSelection; + v0histmanager::ConfK0shortBinning1 confK0shortBinning; + Partition k0shortPartition = MAKE_K0SHORT_PARTITION(k0shortSelection); + Preslice perColk0shorts = aod::femtobase::stored::collisionId; + + // setup pairs + pairhistmanager::ConfPairBinning confPairBinning; + + 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}; + 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{"FemtoTrackV0", {}, OutputObjHandlingPolicy::AnalysisObject}; + + // setup cpr + closepairrejection::ConfCpr confCpr; + + void init(InitContext&) + { + + // setup columnpolicy for binning + // default values are used during instantiation, so we need to explicity update them here + mixBinsVtxMult = {{confMixing.vtxBins, confMixing.multBins.value}, true}; + mixBinsVtxCent = {{confMixing.vtxBins.value, confMixing.centBins.value}, true}; + mixBinsVtxMultCent = {{confMixing.vtxBins.value, confMixing.multBins.value, confMixing.centBins.value}, true}; + + // setup histograms + auto colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); + auto trackHistSpec = trackhistmanager::makeTrackHistSpecMap(confTrackBinning); + auto 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) { + auto lambdaHistSpec = v0histmanager::makeV0HistSpecMap(confLambdaBinning); + 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"; + // } + + // setup for k0short + // if (doprocessK0shortSameEvent || doprocessK0shortMixedEvent) { + if (doprocessK0shortSameEvent) { + auto k0shortHistSpec = v0histmanager::makeV0HistSpecMap(confK0shortBinning); + pairTrackK0shortBuilder.init(&hRegistry, trackSelection, lambdaSelection, confCpr, confMixing, colHistSpec, trackHistSpec, k0shortHistSpec, posDauSpec, negDauSpec, pairHistSpec, cprHistSpec); + } + }; + + void processLambdaSameEvent(FilteredCollision const& col, Tracks const& tracks, Lambdas const& lambdas) + { + pairTrackLambdaBuilder.processSameEvent(col, tracks, trackPartition, lambdas, lambdaPartition, cache); + } + PROCESS_SWITCH(FemtoPairTrackV0, processLambdaSameEvent, "Enable processing same event processing for tracks and lambdas", true); + + void processLambdaMixedEvent(FilteredCollisions const& cols, Tracks const& tracks, Lambdas const& /*lambas*/) + { + pairTrackLambdaBuilder.processMixedEvent(cols, tracks, trackPartition, lambdaPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + } + 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) + { + pairTrackK0shortBuilder.processSameEvent(col, tracks, trackPartition, k0shorts, k0shortPartition, cache); + } + PROCESS_SWITCH(FemtoPairTrackV0, processK0shortSameEvent, "Enable processing same event processing for tracks and k0shorts", false); + + void processK0shortMixedEvent(FilteredCollisions const& cols, Tracks const& tracks, K0shorts const& /*k0shorts*/) + { + pairTrackK0shortBuilder.processMixedEvent(cols, tracks, trackPartition, k0shortPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + } + PROCESS_SWITCH(FemtoPairTrackV0, 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..53338a1852d 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; @@ -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, trackSelections.absCharge.value, confTrackQaBinning.momentumType.value); }; void process(FilteredCollision const& col, Tracks const& /*tracks*/) @@ -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..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 = 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..089d2975e1d 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;