From 4318160b53ef842fd2b57f3580ac20e2023c7ef7 Mon Sep 17 00:00:00 2001 From: yakparo Date: Tue, 10 Nov 2026 08:02:51 +0100 Subject: [PATCH 1/4] Created sigma0 builder and table producer and wrote a ppSigma0 task --- PWGCF/Femto/Core/closePairRejection.h | 38 ++ PWGCF/Femto/Core/closeTripletRejection.h | 50 ++ PWGCF/Femto/Core/dataTypes.h | 4 + PWGCF/Femto/Core/femtoUtils.h | 3 + PWGCF/Femto/Core/modes.h | 1 + PWGCF/Femto/Core/particleCleaner.h | 3 + PWGCF/Femto/Core/partitions.h | 14 + PWGCF/Femto/Core/sigma0Builder.h | 466 ++++++++++++++++ PWGCF/Femto/Core/sigma0HistManager.h | 523 ++++++++++++++++++ PWGCF/Femto/Core/tripletBuilder.h | 277 ++++++++++ PWGCF/Femto/Core/tripletCleaner.h | 55 ++ PWGCF/Femto/Core/tripletHistManager.h | 3 + PWGCF/Femto/DataModel/FemtoTables.h | 80 +++ PWGCF/Femto/TableProducer/CMakeLists.txt | 5 + .../TableProducer/femtoSigma0Producer.cxx | 60 ++ PWGCF/Femto/Tasks/CMakeLists.txt | 5 + .../Tasks/femtoTripletTrackTrackSigma0.cxx | 225 ++++++++ 17 files changed, 1812 insertions(+) create mode 100644 PWGCF/Femto/Core/sigma0Builder.h create mode 100644 PWGCF/Femto/Core/sigma0HistManager.h create mode 100644 PWGCF/Femto/TableProducer/femtoSigma0Producer.cxx create mode 100644 PWGCF/Femto/Tasks/femtoTripletTrackTrackSigma0.cxx diff --git a/PWGCF/Femto/Core/closePairRejection.h b/PWGCF/Femto/Core/closePairRejection.h index d7d8b320171..2748f4e4c81 100644 --- a/PWGCF/Femto/Core/closePairRejection.h +++ b/PWGCF/Femto/Core/closePairRejection.h @@ -750,6 +750,44 @@ class ClosePairRejectionTrackKink CloseTrackRejection mCtr; }; +// photon legs are not in the Track table so Sigma0 pairs only need to cross-check aganist dau lambda +template +class ClosePairRejectionTrackSigma0 +{ + public: + template + void init(o2::framework::HistogramRegistry* registry, + std::map> const& specsV0Daughter, + T1 const& confCprV0Daughter, + int absChargeTrack) + { + mCtrV0Daughter.init(registry, specsV0Daughter, confCprV0Daughter, absChargeTrack, 1); + } + + void setMagField(float magField) + { + mCtrV0Daughter.setMagField(magField); + } + + template + [[nodiscard]] bool isClosePair(T1 const& track, T2 const& sigma0, T3 const& trackTable, T4 const& pairHistManager) + { + bool isCloseV0Daughter = false; + if (track.sign() > 0) { + auto posDau = trackTable.rawIteratorAt(sigma0.posDauId() - trackTable.offset()); + isCloseV0Daughter = mCtrV0Daughter.isClosePair(track, posDau, pairHistManager); + } else { + auto negDau = trackTable.rawIteratorAt(sigma0.negDauId() - trackTable.offset()); + isCloseV0Daughter = mCtrV0Daughter.isClosePair(track, negDau, pairHistManager); + } + + return isCloseV0Daughter; + } + + private: + CloseTrackRejection mCtrV0Daughter; +}; + // PCM photon daughters are, for now, not indexed into the track table (see photonBuilder.h): // they are TPC-only tracks, so they cannot be confused for a global track the way two V0 // daughters or a track and a V0 daughter can -- there is no detector-overlap effect to correct diff --git a/PWGCF/Femto/Core/closeTripletRejection.h b/PWGCF/Femto/Core/closeTripletRejection.h index a3e2f1b8cc7..2b6025c4db5 100644 --- a/PWGCF/Femto/Core/closeTripletRejection.h +++ b/PWGCF/Femto/Core/closeTripletRejection.h @@ -30,12 +30,14 @@ namespace o2::analysis::femto::closetripletrejection constexpr const char PrefixCtrTrackTrackTrack[] = "CtrTrackTrackTrack"; constexpr const char PrefixCtrTrackTrackV0[] = "CtrTrackTrackV0"; constexpr const char PrefixCtrTrackTrackCascade[] = "CtrTrackTrackCascade"; +constexpr const char PrefixCtrTrackTrackSigma0[] = "CtrTrackTrackSigma0"; constexpr const char PrefixCtrMcParticleMcParticleMcParticle[] = "CtrMcParticleMcParticleMcParticle"; // Q3 (not kstar) is the natural kinematic variable for triplets, so it is the default here using ConfCtrTrackTrackTrack = closepairrejection::ConfCpr; using ConfCtrTrackTrackV0 = closepairrejection::ConfCpr; using ConfCtrTrackTrackCascade = closepairrejection::ConfCpr; +using ConfCtrTrackTrackSigma0 = closepairrejection::ConfCpr; // generated particles, no cut by default (close triplet rejection corrects a detector effect) using ConfCtrMcParticleMcParticleMcParticle = closepairrejection::ConfCpr; @@ -74,6 +76,11 @@ constexpr char PrefixTrack2CascadeBachelorSe[] = "CPR_Track2CascadeBachelor/SE/" constexpr char PrefixTrack1CascadeBachelorMe[] = "CPR_Track1CascadeBachelor/ME/"; constexpr char PrefixTrack2CascadeBachelorMe[] = "CPR_Track2CascadeBachelor/ME/"; +constexpr char PrefixTrack1Sigma0Se[] = "CPR_Track1Sigma0/SE/"; +constexpr char PrefixTrack2Sigma0Se[] = "CPR_Track2Sigma0/SE/"; +constexpr char PrefixTrack1Sigma0Me[] = "CPR_Track1Sigma0/ME/"; +constexpr char PrefixTrack2Sigma0Me[] = "CPR_Track2Sigma0/ME/"; + template @@ -217,6 +224,49 @@ class CloseTripletRejectionTrackTrackCascade closepairrejection::ClosePairRejectionTrackCascade mCtrTrack2Cascade; }; +template +class CloseTripletRejectionTrackTrackSigma0 +{ + public: + CloseTripletRejectionTrackTrackSigma0() = default; + ~CloseTripletRejectionTrackTrackSigma0() = default; + + template + void init(o2::framework::HistogramRegistry* registry, + std::map> const& specs, + T1 const& confCpr, + int absChargeTrack1, + int absChargeTrack2) + { + mCtrTrack12.init(registry, specs, confCpr, absChargeTrack1, absChargeTrack2); + mCtrTrack1Sigma0.init(registry, specs, confCpr, absChargeTrack1); + mCtrTrack2Sigma0.init(registry, specs, confCpr, absChargeTrack2); + } + + void setMagField(float magField) + { + mCtrTrack12.setMagField(magField); + mCtrTrack1Sigma0.setMagField(magField); + mCtrTrack2Sigma0.setMagField(magField); + } + + // checks track1-track2, track1-v0 and track2-v0 (from sigma0); fills the deta-dphi/kinematic + // histograms of each pair internally and returns whether the triplet is rejected. + template + [[nodiscard]] bool isCloseTriplet(T1 const& track1, T2 const& track2, T3 const& sigma0, T4 const& trackTable, T5 const& tripletHistManager) + { + bool isClose12 = mCtrTrack12.isClosePair(track1, track2, trackTable, tripletHistManager); + bool isClose1Sigma0 = mCtrTrack1Sigma0.isClosePair(track1, sigma0, trackTable, tripletHistManager); + bool isClose2Sigma0 = mCtrTrack2Sigma0.isClosePair(track2, sigma0, trackTable, tripletHistManager); + return isClose12 || isClose1Sigma0|| isClose2Sigma0; + } + + private: + closepairrejection::ClosePairRejectionTrackTrack mCtrTrack12; + closepairrejection::ClosePairRejectionTrackSigma0 mCtrTrack1Sigma0; + closepairrejection::ClosePairRejectionTrackSigma0 mCtrTrack2Sigma0; +}; + // close triplet rejection for triplets of generated particles; checks all three constituent pairs template ; using ConfSigmaPlusPcmCleaner2 = ConfParticleCleaner; +constexpr const char PrefixSigma0Cleaner[] = "Sigma0Cleaner"; +using ConfSigma0Cleaner = ConfParticleCleaner; + constexpr const char PrefixXiCleaner1[] = "XiCleaner1"; constexpr const char PrefixXiCleaner2[] = "XiCleaner2"; using ConfXiCleaner1 = ConfParticleCleaner; diff --git a/PWGCF/Femto/Core/partitions.h b/PWGCF/Femto/Core/partitions.h index 6a3a473ecf9..9aef883303d 100644 --- a/PWGCF/Femto/Core/partitions.h +++ b/PWGCF/Femto/Core/partitions.h @@ -259,6 +259,20 @@ (o2::aod::femtokinks::mlScore >= (selection).mlScoreMin) && \ ncheckbit(o2::aod::femtokinks::mask, (selection).mask) +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define MAKE_SIGMA0_PARTITION(selection) \ + ifnode((selection).sign.node() != 0, \ + ifnode((selection).sign.node() > 0, o2::aod::femtobase::stored::signedPt > 0.f, o2::aod::femtobase::stored::signedPt < 0.f), true) && \ + (nabs(o2::aod::femtobase::stored::signedPt) > (selection).ptMin) && \ + (nabs(o2::aod::femtobase::stored::signedPt) < (selection).ptMax) && \ + (o2::aod::femtobase::stored::eta > (selection).etaMin) && \ + (o2::aod::femtobase::stored::eta < (selection).etaMax) && \ + (o2::aod::femtobase::stored::phi > (selection).phiMin) && \ + (o2::aod::femtobase::stored::phi < (selection).phiMax) && \ + (o2::aod::femtobase::stored::mass > (selection).massMin) && \ + (o2::aod::femtobase::stored::mass < (selection).massMax) && \ + ncheckbit(o2::aod::femtosigma0s::mask, (selection).mask) + // partition for D0 // sign of signedPt encodes the hypothesis: D0 (+) / D0bar (-) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) diff --git a/PWGCF/Femto/Core/sigma0Builder.h b/PWGCF/Femto/Core/sigma0Builder.h new file mode 100644 index 00000000000..ac6817539a5 --- /dev/null +++ b/PWGCF/Femto/Core/sigma0Builder.h @@ -0,0 +1,466 @@ +// 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 sigma0Builder.h +/// \brief Sigma0 <- Lambda + gamma builder for femto +/// \author Yakiv Paroviak, CTU in Prague, yakiv.paroviak@cern.ch + +#ifndef PWGCF_FEMTO_CORE_SIGMA0BUILDER_H_ +#define PWGCF_FEMTO_CORE_SIGMA0BUILDER_H_ + +#include "PWGCF/Femto/Core/baseSelection.h" +#include "PWGCF/Femto/Core/dataTypes.h" +#include "PWGCF/Femto/Core/femtoUtils.h" +#include "PWGCF/Femto/Core/selectionContainer.h" +#include "PWGCF/Femto/DataModel/FemtoTables.h" + +#include "Common/Core/RecoDecay.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace o2::analysis::femto::sigma0builder +{ +// Filters applied before the Sigma0 selection bits are evaluated. +struct ConfSigma0Filters : o2::framework::ConfigurableGroup { + std::string prefix = std::string("Sigma0Filters"); + + // Photon preselection. + o2::framework::Configurable photonMask{"photonMask", 0, "Photon selection bits that must all be set. 0: no requirement"}; + o2::framework::Configurable photonPtMin{"photonPtMin", 0.f, "Minimum photon pT"}; + o2::framework::Configurable photonRapMax{"photonRapMax", 0.5f, "Maximum photon |y| (equal to |eta| for a massless photon)"}; + + // Lambda preselection. + o2::framework::Configurable lambdaMask{"lambdaMask", 0, "Lambda selection bits that must all be set. 0: no requirement"}; + o2::framework::Configurable lambdaSign{"lambdaSign", 0, "Lambda sign (+1: Lambda; -1: AntiLambda; 0: both)"}; + o2::framework::Configurable lambdaPtMin{"lambdaPtMin", 0.f, "Minimum Lambda pT"}; + o2::framework::Configurable lambdaRapMax{"lambdaRapMax", 0.5f, "Maximum Lambda |y|, computed with the PDG Lambda mass"}; + o2::framework::Configurable lambdaMassWindow{"lambdaMassWindow", 0.015f, "Maximum |m - m_Lambda(PDG)| in GeV/c^2. Set <= 0 to disable"}; + + // Loose filters on the Lambda-photon pair. + o2::framework::Configurable ptMin{"ptMin", 0.f, "Minimum Sigma0 pT"}; + o2::framework::Configurable rapMax{"rapMax", 1.f, "Maximum Sigma0 |y|"}; + o2::framework::Configurable massMin{"massMin", 1.1f, "Minimum Sigma0 invariant mass"}; + o2::framework::Configurable massMax{"massMax", 1.3f, "Maximum Sigma0 invariant mass"}; +}; + +// Working points stored in the Sigma0 selection mask. +struct ConfSigma0Bits : o2::framework::ConfigurableGroup { + std::string prefix = std::string("Sigma0Bits"); + o2::framework::Configurable passThrough{"passThrough", false, "If true, store all Sigma0 candidates passing the loose filters and record every selection bit"}; + o2::framework::Configurable> massWindow{"massWindow", {0.1f}, "Maximum |m(Lambda gamma) - m_Sigma0(PDG)| (GeV/c^2)"}; + o2::framework::Configurable> absRapMax{"absRapMax", {0.8f}, "Maximum Sigma0 |y|"}; + o2::framework::Configurable> ptMin{"ptMin", {0.f}, "Minimum Sigma0 pT (GeV/c)"}; +}; + +// Base selection configuration for downstream analysis tasks. +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define SIGMA0_DEFAULT_SELECTIONS(defaultMassMin, defaultMassMax, defaultPdgCode) \ + o2::framework::Configurable pdgCodeAbs{"pdgCodeAbs", (defaultPdgCode), "PDG code. Set sign to -1 for antiparticle"}; \ + o2::framework::Configurable ptMin{"ptMin", 0.f, "Minimum pT"}; \ + o2::framework::Configurable ptMax{"ptMax", 999.f, "Maximum pT"}; \ + o2::framework::Configurable etaMin{"etaMin", -10.f, "Minimum eta"}; \ + o2::framework::Configurable etaMax{"etaMax", 10.f, "Maximum eta"}; \ + o2::framework::Configurable phiMin{"phiMin", 0.f, "Minimum phi"}; \ + o2::framework::Configurable phiMax{"phiMax", 1.f * o2::constants::math::TwoPI, "Maximum phi"}; \ + o2::framework::Configurable massMin{"massMin", (defaultMassMin), "Minimum invariant mass"}; \ + o2::framework::Configurable massMax{"massMax", (defaultMassMax), "Maximum invariant mass"}; \ + o2::framework::Configurable mask{"mask", 0, "Bitmask for Sigma0 selection"}; + +template +struct ConfSigma0Selection : o2::framework::ConfigurableGroup { + std::string prefix = Prefix; + SIGMA0_DEFAULT_SELECTIONS(1.1, 1.3, 3212) + o2::framework::Configurable sign{"sign", DefaultSign, "Sign of the Sigma0 (+1: Sigma0; -1: AntiSigma0; 0: both)"}; +}; + +#undef SIGMA0_DEFAULT_SELECTIONS + +constexpr const char PrefixSigma0Selection[] = "Sigma0Selection"; +using ConfSigma0SelectionDefault = ConfSigma0Selection; +constexpr const char PrefixSigma0SelectionStrangeness[] = "Sigma0SelectionStrangeness"; +using ConfSigma0SelectionStrangeness = ConfSigma0Selection; + +/// The selection bits stored for Sigma0 candidates. +enum Sigma0Sels { + kSigmaMassWindow, ///< Maximum |m(Lambda gamma) - m_Sigma0(PDG)| + kSigmaAbsRapMax, ///< Maximum absolute Sigma0 rapidity + kSigmaPtMin, ///< Minimum Sigma0 pT + kSigma0SelsMax +}; + +constexpr char Sigma0SelHistName[] = "hSigma0Selection"; +constexpr char Sigma0SelsName[] = "Sigma0 selection object"; +const std::unordered_map sigma0SelectionNames = { + {kSigmaMassWindow, "Maximum Sigma0 mass deviation"}, + {kSigmaAbsRapMax, "Maximum absolute Sigma0 rapidity"}, + {kSigmaPtMin, "Minimum Sigma0 pT"}}; + +// Loose preselection of each Lambda-photon pair. +enum Sigma0Filters { + kPtMin, + kRapMax, + kMassMin, + kMassMax, + kSigma0FiltersMax +}; + +constexpr char Sigma0FilterHistName[] = "hSigma0Filters"; +const std::unordered_map sigma0FilterNames = { + {kPtMin, "ptMin"}, + {kRapMax, "rapMax"}, + {kMassMin, "massMin"}, + {kMassMax, "massMax"}}; + +/// Cut class containing and executing all Sigma0 selection bits and loose filters. +class Sigma0Selection : public baseselection::BaseSelection +{ + public: + Sigma0Selection() = default; + ~Sigma0Selection() override = default; + + template + void configure(o2::framework::HistogramRegistry* registry, T1& config, T2& filter) + { + this->init(config.passThrough.value); + + mPtMin = filter.ptMin.value; + mRapMax = filter.rapMax.value; + mMassMin = filter.massMin.value; + mMassMax = filter.massMax.value; + + this->addSelection(kSigmaMassWindow, sigma0SelectionNames.at(kSigmaMassWindow), config.massWindow.value, limits::kAbsUpperLimit, true, true, false); + this->addSelection(kSigmaAbsRapMax, sigma0SelectionNames.at(kSigmaAbsRapMax), config.absRapMax.value, limits::kAbsUpperLimit, true, true, false); + this->addSelection(kSigmaPtMin, sigma0SelectionNames.at(kSigmaPtMin), config.ptMin.value, limits::kLowerLimit, true, true, false); + + this->setupSelectionHistogram(registry); + this->template setupFilterHistogram( + registry, + { + {sigma0FilterNames.at(kPtMin), mPtMin}, + {sigma0FilterNames.at(kRapMax), mRapMax}, + {sigma0FilterNames.at(kMassMin), mMassMin}, + {sigma0FilterNames.at(kMassMax), mMassMax}, + }); + } + + /// Evaluate the selection bits for a Lambda-photon pair. + void applySelections(float mass, float rapidity, float pt) + { + this->reset(); + this->evaluateObservable(kSigmaMassWindow, mass - o2::constants::physics::MassSigma0); + this->evaluateObservable(kSigmaAbsRapMax, rapidity); + this->evaluateObservable(kSigmaPtMin, pt); + this->assembleBitmask(); + } + + /// Apply the loose preselection to a Lambda-photon pair. + bool checkFilters(float mass, float rapidity, float pt) const + { + bool pass = true; + bool p = false; + + p = pt > mPtMin; + this->template fillFilter(kPtMin, p); + pass &= p; + + p = std::abs(rapidity) < mRapMax; + this->template fillFilter(kRapMax, p); + pass &= p; + + p = mass > mMassMin; + this->template fillFilter(kMassMin, p); + pass &= p; + + p = mass < mMassMax; + this->template fillFilter(kMassMax, p); + pass &= p; + + this->template fillFilterSummary(pass); + return this->isPassThrough() || pass; + } + + protected: + float mPtMin = 0.f; + float mRapMax = 1.f; + float mMassMin = 1.1f; + float mMassMax = 1.3f; +}; + +struct Sigma0BuilderProducts : o2::framework::ProducesGroup { + o2::framework::Produces producedSigma0s; + o2::framework::Produces producedLiteSigma0s; + o2::framework::Produces producedSigma0Masks; +}; + +struct ConfSigma0Tables : o2::framework::ConfigurableGroup { + std::string prefix = std::string("Sigma0Tables"); + o2::framework::Configurable produceSigma0s{"produceSigma0s", -1, "Produce Sigma0s (-1: auto; 0 off; 1 on)"}; + o2::framework::Configurable produceLiteSigma0s{"produceLiteSigma0s", -1, "Produce LiteSigma0s (-1: auto; 0 off; 1 on)"}; + o2::framework::Configurable produceSigma0Masks{"produceSigma0Masks", -1, "Produce Sigma0Masks (-1: auto; 0 off; 1 on)"}; +}; + +class Sigma0Builder +{ + public: + Sigma0Builder() = default; + ~Sigma0Builder() = default; + + template + void init(o2::framework::HistogramRegistry* registry, T1& filter, T2& bits, T3& table, T4& initContext) + { + LOG(info) << "Initialize femto Sigma0 builder..."; + mRegistry = registry; + + mProduceSigma0s = utils::enableTable("FSigma0s_001", table.produceSigma0s.value, initContext); + mProduceLiteSigma0s = utils::enableTable("FLiteSigma0s_001", table.produceLiteSigma0s.value, initContext); + mProduceSigma0Masks = utils::enableTable("FSigma0Masks_002", table.produceSigma0Masks.value, initContext); + + if (mProduceSigma0s && mProduceLiteSigma0s) { + LOG(fatal) << "FSigma0s and FLiteSigma0s are mutually exclusive -- enable only one. " + << "FLiteSigma0s is meant to replace FSigma0s at the producer stage for better compression in derived data."; + } + + mFillAnyTable = mProduceSigma0s || mProduceLiteSigma0s || mProduceSigma0Masks; + if (!mFillAnyTable) { + LOG(info) << "No tables configured, Sigma0 selection object will not be configured..."; + LOG(info) << "Initialization done..."; + return; + } + + mPhotonMask = filter.photonMask.value; + mPhotonPtMin = filter.photonPtMin.value; + mPhotonRapMax = filter.photonRapMax.value; + + mLambdaMask = filter.lambdaMask.value; + mLambdaSign = filter.lambdaSign.value; + mLambdaPtMin = filter.lambdaPtMin.value; + mLambdaRapMax = filter.lambdaRapMax.value; + mLambdaMassWindow = filter.lambdaMassWindow.value; + + mSigma0Selection.configure(registry, bits, filter); + mSigma0Selection.printSelections(Sigma0SelsName); + + // Daughter cut-flow histograms. Bin N is filled when the candidate passes cut N. + mRegistry->add("hPhotonSelection", "Photon selection;;Entries", o2::framework::HistType::kTH1D, {{4, 0.5, 4.5}}); + setBinLabels(mRegistry->get(HIST("hPhotonSelection")), {"No Sel", "Mask", "pT", "Y"}); + + mRegistry->add("hLambdaSelection", "Lambda selection;;Entries", o2::framework::HistType::kTH1D, {{6, 0.5, 6.5}}); + setBinLabels(mRegistry->get(HIST("hLambdaSelection")), {"No Sel", "Mask", "Sign", "pT", "Y", "Mass"}); + mRegistry->add("hLambdaMassBeforeSel", "Lambda mass before Lambda selections;#it{M}_{#Lambda} (GeV/#it{c}^{2});Entries", o2::framework::HistType::kTH1D, {{500, 1.10f, 1.30f}}); + mRegistry->add("hLambdaMassSelected", "Lambda mass after Lambda selections;#it{M}_{#Lambda} (GeV/#it{c}^{2});Entries", o2::framework::HistType::kTH1D, {{500, 1.10f, 1.30f}}); + mRegistry->add("hSigmaMassBeforeSel", "Sigma0 mass before selection;#it{M}_{#Lambda#gamma} (GeV/#it{c}^{2});Entries", o2::framework::HistType::kTH1D, {{500, 1.10f, 1.30f}}); + mRegistry->add("hSigmaMassSelected", "Sigma0 mass after selection;#it{M}_{#Lambda#gamma} (GeV/#it{c}^{2});Entries", o2::framework::HistType::kTH1D, {{500, 1.10f, 1.30f}}); + + LOG(info) << "Initialization done..."; + } + + /// Build Sigma0 candidates from Lambda and photon tables belonging to the same collision. + template + void fillSigma0s(TProducts& products, TLambdas const& lambdas, TPhotons const& photons, TTracks const& tracks) + { + if (!mFillAnyTable) { + return; + } + + // Preselect photons once and group their row indices by collision. + std::unordered_map> photonRowsPerCollision; + for (const auto& photon : photons) { + if (selectPhoton(photon)) { + photonRowsPerCollision[photon.fColId()].push_back(photon.globalIndex()); + } + } + if (photonRowsPerCollision.empty()) { + return; + } + + for (const auto& lambda : lambdas) { + if (!selectLambda(lambda)) { + continue; + } + const auto posDau = lambda.posDau(); + const auto negDau = lambda.negDau(); + + const auto photonRows = photonRowsPerCollision.find(lambda.fColId()); + if (photonRows == photonRowsPerCollision.end()) { + continue; + } + for (const auto photonRow : photonRows->second) { + const auto photon = photons.rawIteratorAt(photonRow); + buildSigma0(products, lambda, photon, posDau, negDau); + } + } + } + + private: + template + static void setBinLabels(H const& hist, std::initializer_list labels) + { + int bin = 1; + for (const char* label : labels) { + hist->GetXaxis()->SetBinLabel(bin++, label); + } + } + + static std::array momentum(float pt, float eta, float phi) + { + return {pt * std::cos(phi), pt * std::sin(phi), pt * std::sinh(eta)}; + } + + template + bool selectPhoton(T const& photon) + { + mRegistry->fill(HIST("hPhotonSelection"), 1.); + if ((photon.mask() & mPhotonMask) != mPhotonMask) { + return false; + } + mRegistry->fill(HIST("hPhotonSelection"), 2.); + if (photon.pt() < mPhotonPtMin) { + return false; + } + mRegistry->fill(HIST("hPhotonSelection"), 3.); + // For a massless photon, rapidity equals pseudorapidity. + if (std::abs(photon.eta()) > mPhotonRapMax) { + return false; + } + mRegistry->fill(HIST("hPhotonSelection"), 4.); + return true; + } + + template + bool selectLambda(T const& lambda) + { + mRegistry->fill(HIST("hLambdaMassBeforeSel"), lambda.mass()); + mRegistry->fill(HIST("hLambdaSelection"), 1.); + if ((lambda.mask() & mLambdaMask) != mLambdaMask) { + return false; + } + mRegistry->fill(HIST("hLambdaSelection"), 2.); + + const bool isAntiLambda = lambda.signedPt() < 0.f; + if ((mLambdaSign > 0 && isAntiLambda) || (mLambdaSign < 0 && !isAntiLambda)) { + return false; + } + mRegistry->fill(HIST("hLambdaSelection"), 3.); + + const float pt = std::abs(lambda.signedPt()); + if (pt < mLambdaPtMin) { + return false; + } + mRegistry->fill(HIST("hLambdaSelection"), 4.); + + const auto pLambda = momentum(pt, lambda.eta(), lambda.phi()); + if (std::abs(RecoDecay::y(pLambda, o2::constants::physics::MassLambda0)) > mLambdaRapMax) { + return false; + } + mRegistry->fill(HIST("hLambdaSelection"), 5.); + + if (mLambdaMassWindow > 0.f && std::abs(lambda.mass() - o2::constants::physics::MassLambda0) > mLambdaMassWindow) { + return false; + } + mRegistry->fill(HIST("hLambdaSelection"), 6.); + mRegistry->fill(HIST("hLambdaMassSelected"), lambda.mass()); + return true; + } + + template + bool buildSigma0(TProducts& products, TLambda const& lambda, TPhoton const& photon, TPosDau const& posDau, TNegDau const& negDau) + { + const float lambdaPt = std::abs(lambda.signedPt()); + const std::array pLambda = momentum(lambdaPt, lambda.eta(), lambda.phi()); + const std::array pPhoton = momentum(photon.pt(), photon.eta(), photon.phi()); + const std::array pSigma = {pLambda[0] + pPhoton[0], pLambda[1] + pPhoton[1], pLambda[2] + pPhoton[2]}; + + const float sigmaPt = std::hypot(pSigma[0], pSigma[1]); + if (sigmaPt <= 0.f) { + return false; + } + + // Compute the pair mass with the PDG masses of Lambda and photon. + const float sigmaMass = RecoDecay::m(std::array{pPhoton, pLambda}, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassLambda0}); + const float sigmaY = RecoDecay::y(pSigma, o2::constants::physics::MassSigma0); + mRegistry->fill(HIST("hSigmaMassBeforeSel"), sigmaMass); + + if (!mSigma0Selection.checkFilters(sigmaMass, sigmaY, sigmaPt)) { + return false; + } + mSigma0Selection.applySelections(sigmaMass, sigmaY, sigmaPt); + if (!mSigma0Selection.passesAllRequiredSelections()) { + return false; + } + mRegistry->fill(HIST("hSigmaMassSelected"), sigmaMass); + + const float sigmaEta = std::asinh(pSigma[2] / sigmaPt); + const float sigmaPhi = RecoDecay::phi(pSigma[0], pSigma[1]); + const float sign = lambda.signedPt() < 0.f ? -1.f : 1.f; + + if (mProduceSigma0s) { + products.producedSigma0s(lambda.fColId(), + sign * sigmaPt, + sigmaEta, + sigmaPhi, + sigmaMass, + static_cast(lambda.globalIndex()), + static_cast(photon.globalIndex()), + static_cast(posDau.globalIndex()), + static_cast(negDau.globalIndex())); + } + if (mProduceLiteSigma0s) { + products.producedLiteSigma0s(lambda.fColId(), + o2::aod::femtobase::lite::binSignedPt(sign * sigmaPt), + o2::aod::femtobase::lite::binEta(sigmaEta), + o2::aod::femtobase::lite::binPhi(sigmaPhi), + o2::aod::femtosigma0s::lite::binSigma0Mass(sigmaMass), + static_cast(lambda.globalIndex()), + static_cast(photon.globalIndex())); + } + if (mProduceSigma0Masks) { + products.producedSigma0Masks(mSigma0Selection.getBitmask()); + } + return true; + } + + o2::framework::HistogramRegistry* mRegistry = nullptr; + Sigma0Selection mSigma0Selection; + bool mFillAnyTable = false; + bool mProduceSigma0s = false; + bool mProduceLiteSigma0s = false; + bool mProduceSigma0Masks = false; + + // Photon preselection. + datatypes::PhotonMaskType mPhotonMask = 0; + float mPhotonPtMin = 0.f; + float mPhotonRapMax = 0.5f; + + // Lambda preselection. + datatypes::V0MaskType mLambdaMask = 0; + int mLambdaSign = 0; + float mLambdaPtMin = 0.f; + float mLambdaRapMax = 0.5f; + float mLambdaMassWindow = 0.015f; +}; + +} // namespace o2::analysis::femto::sigma0builder +#endif // PWGCF_FEMTO_CORE_SIGMA0BUILDER_H_ diff --git a/PWGCF/Femto/Core/sigma0HistManager.h b/PWGCF/Femto/Core/sigma0HistManager.h new file mode 100644 index 00000000000..46eff0f47ad --- /dev/null +++ b/PWGCF/Femto/Core/sigma0HistManager.h @@ -0,0 +1,523 @@ +// 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 sigma0HistManager.h +/// \brief histogram manager for sigm histograms +/// \author Yakiv Paroviak, CTU in Prague, yakiv.paroviak@cern.ch + +#ifndef PWGCF_FEMTO_CORE_SIGMA0HISTMANAGER_H_ +#define PWGCF_FEMTO_CORE_SIGMA0HISTMANAGER_H_ + +#include "PWGCF/Femto/Core/histManager.h" +#include "PWGCF/Femto/Core/modes.h" +#include "PWGCF/Femto/Core/trackHistManager.h" +#include "PWGCF/Femto/Core/v0HistManager.h" +#include "PWGCF/Femto/Core/photonHistManager.h" + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace o2::analysis::femto::sigma0histmanager +{ +// enum for histograms +enum Sigma0Hist { + // analysis + kPt, + kEta, + kPhi, + kMass, + kSign, + kPtVsMass, + // qa + kMassSigma0, + kMassAntiSigma0, + kCosPa, + kDecayVtxX, + kDecayVtxY, + kDecayVtxZ, + kDecayVtx, + // 2d qa + kPtVsEta, + kPtVsPhi, + kPhiVsEta, + kPtVsCosPa, + kPtVsSigma0Mass, + kPtVsAntiSigma0Mass, + kSigma0MassVsAntiSigma0Mass, + // mc + kOrigin, + kPdg, + kTruePtVsPt, + kTrueEtaVsEta, + kTruePhiVsPhi, + // histograms for fraction estimation of sigma0s + kNoMcParticle, + kPrimary, + + kSigma0HistLast +}; + +constexpr std::size_t MaxSecondary = 3; + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define SIGMA0_DEFAULT_BINNING(defaultMassMin, defaultMassMax) \ + o2::framework::ConfigurableAxis pt{"pt", {{600, 0, 6}}, "Pt"}; \ + o2::framework::ConfigurableAxis eta{"eta", {{300, -1.5, 1.5}}, "Eta"}; \ + o2::framework::ConfigurableAxis phi{"phi", {{720, 0, 1.f * o2::constants::math::TwoPI}}, "Phi"}; \ + o2::framework::ConfigurableAxis mass{"mass", {{200, (defaultMassMin), (defaultMassMax)}}, "Mass"}; \ + o2::framework::ConfigurableAxis sign{"sign", {{3, -1.5, 1.5}}, "Sign"}; \ + o2::framework::ConfigurableAxis pdgCodes{"pdgCodes", {{8001, -4000.5, 4000.5}}, "MC ONLY: PDG codes of reconstructed Sigma0s"}; + +template +struct ConfSigma0Binning : o2::framework::ConfigurableGroup { + std::string prefix = Prefix; + SIGMA0_DEFAULT_BINNING(1.07, 1.32) // rough estimate of 5-sigma mass window for Sigma0 +}; + +#undef SIGMA0_DEFAULT_BINNING + +constexpr const char PrefixSigma0Binning[] = "Sigma0Binning"; +using ConfSigma0BinningDefault = ConfSigma0Binning; + +template +struct ConfSigma0QaBinning : o2::framework::ConfigurableGroup { + std::string prefix = Prefix; + o2::framework::Configurable plot2d{"plot2d", true, "Generate various 2D QA plots"}; + o2::framework::ConfigurableAxis cosPa{"cosPa", {{100, 0.9, 1}}, "Cosine of pointing angle"}; + o2::framework::ConfigurableAxis decayVertex{"decayVertex", {{100, 0, 100}}, "Decay vertex"}; + o2::framework::ConfigurableAxis massSigma0{"massSigma0", {{200, 1, 1.2}}, "mass for particle hypothesis"}; + o2::framework::ConfigurableAxis massAntiSigma0{"massAntiSigma0", {{100, 1, 1.2}}, "mass for antiparticle hypothesis"}; +}; + +constexpr const char PrefixSigma0QaBinning[] = "Sigma0QaBinning"; +using ConfSigma0QaBinningDefault = ConfSigma0QaBinning; + +// must be in sync with enum +constexpr std::array, kSigma0HistLast> HistTable = { + {{kPt, o2::framework::HistType::kTH1F, "hPt", "Transverse Momentum; p_{T} (GeV/#it{c}); Entries"}, + {kEta, o2::framework::HistType::kTH1F, "hEta", "Pseudorapdity; #eta; Entries"}, + {kPhi, o2::framework::HistType::kTH1F, "hPhi", "Azimuthal angle; #varphi; Entries"}, + {kMass, o2::framework::HistType::kTH1F, "hMass", "Invariant Mass; m_{Inv} (GeV/#it{c}^{2}); Entries"}, + {kSign, o2::framework::HistType::kTH1F, "hSign", "Sign (-1 -> antiparticle, 0 -> self conjugate, +1 -> particle); sign; Entries"}, + {kPtVsMass, o2::framework::HistType::kTH2F, "hPtVsMass", "Transverse momentum vs invariant mass; p_{T} (GeV/#it{c}); m_{Inv} (GeV/#it{c}^{2})"}, + {kMassSigma0, o2::framework::HistType::kTH1F, "hMassSigma0", "#Sigma0 mass; m_{p#pi^{-}} (GeV/#it{c}^{2}); Entries"}, + {kMassAntiSigma0, o2::framework::HistType::kTH1F, "hMassAntiSigma0", "#bar{#Sigma0} mass; m_{#bar{p}#pi^{+}} (GeV/#it{c}^{2}); Entries"}, + {kCosPa, o2::framework::HistType::kTH1F, "hCosPa", "Cosine of pointing angle; cos(#alpha); Entries"}, + {kDecayVtxX, o2::framework::HistType::kTH1F, "hDecayVtxX", "X coordinate of decay vertex ; DV_{X} (cm); Entries"}, + {kDecayVtxY, o2::framework::HistType::kTH1F, "hDecayVtxY", "Y coordinate of decay vertex ; DV_{Y} (cm); Entries"}, + {kDecayVtxZ, o2::framework::HistType::kTH1F, "hDecayVtxZ", "Z coordinate of decay vertex ; DV_{Z} (cm); Entries"}, + {kDecayVtx, o2::framework::HistType::kTH1F, "hDecayVtx", "Distance of decay vertex from primary vertex ; DV (cm); Entries"}, + {kPtVsEta, o2::framework::HistType::kTH2F, "hPtVsEta", "p_{T} vs #eta; p_{T} (GeV/#it{c}) ; #eta"}, + {kPtVsPhi, o2::framework::HistType::kTH2F, "hPtVsPhi", "p_{T} vs #varphi; p_{T} (GeV/#it{c}) ; #varphi"}, + {kPhiVsEta, o2::framework::HistType::kTH2F, "hPhiVsEta", "#varphi vs #eta; #varphi ; #eta"}, + {kPtVsCosPa, o2::framework::HistType::kTH2F, "hPtVsCosPa", "p_{T} vs Cosine of pointing angle;p_{T} (GeV/#it{c}); cos(#alpha);"}, + {kPtVsSigma0Mass, o2::framework::HistType::kTH2F, "hPtVsSigma0Mass", "p_{T} vs #Sigma0 mass; p_{T} (GeV/#it{c}); m_{p#pi^{-}} (GeV/#it{c}^{2})"}, + {kPtVsAntiSigma0Mass, o2::framework::HistType::kTH2F, "hPtVsAntiSigma0Mass", "p_{T} vs #bar{#Sigma0} mass; p_{T} (GeV/#it{c}); m_{#bar{p}#pi^{+}} (GeV/#it{c}^{2})"}, + {kSigma0MassVsAntiSigma0Mass, o2::framework::HistType::kTH2F, "hSigma0MassVsAntiSigma0Mass", "#Sigma0 mass vs #bar{#Sigma0}; m_{p#pi^{-}} (GeV/#it{c}^{2}); m_{#bar{p}#pi^{+}} (GeV/#it{c}^{2})"}, + {kOrigin, o2::framework::HistType::kTH1F, "hOrigin", "Status Codes (=Origin); Status Code; Entries"}, + {kPdg, o2::framework::HistType::kTH1F, "hPdg", "PDG Codes of reconstructed sigma0; PDG Code; Entries"}, + {kTruePtVsPt, o2::framework::HistType::kTH2F, "hTruePtVsPt", "True transverse momentum vs transverse momentum; p_{T,True} (GeV/#it{c}); p_{T,True} (GeV/#it{c})"}, + {kTrueEtaVsEta, o2::framework::HistType::kTH2F, "hTrueEtaVsEta", "True pseudorapdity vs pseudorapdity; #eta_{True}; #eta"}, + {kTruePhiVsPhi, o2::framework::HistType::kTH2F, "hTruePhiVsPhi", "True azimuthal angle vs azimuthal angle; #varphi_{True}; #varphi"}, + {kNoMcParticle, o2::framework::HistType::kTH2F, "hNoMcParticle", "Wrongly reconstructed particles; p_{T} (GeV/#it{c}); cos(#alpha)"}, + {kPrimary, o2::framework::HistType::kTH2F, "hPrimary", "Primary particles; p_{T} (GeV/#it{c}); cos(#alpha)"}}, +}; + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define SIGMA0_HIST_ANALYSIS_MAP(conf) \ + {kPt, {(conf).pt}}, \ + {kEta, {(conf).eta}}, \ + {kPhi, {(conf).phi}}, \ + {kMass, {(conf).mass}}, \ + {kSign, {(conf).sign}}, \ + {kPtVsMass, {(conf).pt, (conf).mass}}, + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define SIGMA0_HIST_MC_MAP(conf) \ + {kTruePtVsPt, {(conf).pt, (conf).pt}}, \ + {kTrueEtaVsEta, {(conf).eta, (conf).eta}}, \ + {kTruePhiVsPhi, {(conf).phi, (conf).phi}}, \ + {kPdg, {(conf).pdgCodes}}, + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define SIGMA0_HIST_QA_MAP(confAnalysis, confQa) \ + {kCosPa, {(confQa).cosPa}}, \ + {kDecayVtxX, {(confQa).decayVertex}}, \ + {kDecayVtxY, {(confQa).decayVertex}}, \ + {kDecayVtxZ, {(confQa).decayVertex}}, \ + {kDecayVtx, {(confQa).decayVertex}}, \ + {kPtVsEta, {(confAnalysis).pt, (confAnalysis).eta}}, \ + {kPtVsPhi, {(confAnalysis).pt, (confAnalysis).phi}}, \ + {kPhiVsEta, {(confAnalysis).phi, (confAnalysis).eta}}, \ + {kPtVsCosPa, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kMassSigma0, {(confQa).massSigma0}}, \ + {kMassAntiSigma0, {(confQa).massAntiSigma0}}, \ + {kPtVsSigma0Mass, {(confAnalysis).pt, (confQa).massSigma0}}, \ + {kPtVsAntiSigma0Mass, {(confAnalysis).pt, (confQa).massAntiSigma0}}, \ + {kSigma0MassVsAntiSigma0Mass, {(confQa).massSigma0, (confQa).massAntiSigma0}}, + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define SIGMA0_HIST_MC_QA_MAP(confAnalysis, confQa) \ + {kNoMcParticle, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kPrimary, {(confAnalysis).pt, (confQa).cosPa}}, + +template +auto makeSigma0HistSpecMap(const T& confBinningAnalysis) +{ + return std::map>{ + SIGMA0_HIST_ANALYSIS_MAP(confBinningAnalysis)}; +} + +template +auto makeSigma0McHistSpecMap(const T& confBinningAnalysis) +{ + return std::map>{ + SIGMA0_HIST_ANALYSIS_MAP(confBinningAnalysis) + SIGMA0_HIST_MC_MAP(confBinningAnalysis)}; +} + +template +std::map> makeSigma0QaHistSpecMap(T1 const& confBinningAnalysis, T2 const& confBinningQa) +{ + return std::map>{ + SIGMA0_HIST_ANALYSIS_MAP(confBinningAnalysis) + SIGMA0_HIST_QA_MAP(confBinningAnalysis, confBinningQa)}; +} + +template +std::map> makeSigma0McQaHistSpecMap(T1 const& confBinningAnalysis, T2 const& confBinningQa) +{ + return std::map>{ + SIGMA0_HIST_ANALYSIS_MAP(confBinningAnalysis) + SIGMA0_HIST_QA_MAP(confBinningAnalysis, confBinningQa) + SIGMA0_HIST_MC_MAP(confBinningAnalysis) + SIGMA0_HIST_MC_QA_MAP(confBinningAnalysis, confBinningQa)}; +} + +#undef SIGMA0_HIST_ANALYSIS_MAP +#undef SIGMA0_HIST_QA_MAP +#undef SIGMA0_HIST_MC_MAP +#undef SIGMA0_HIST_MC_QA_MAP + +constexpr char PrefixSigma0Qa[] = "Sigma0QA/"; +constexpr char PrefixSigma0[] = "Sigma0/"; +constexpr char PrefixSigma0Cascade[] = "Sigma0CascadeQa/"; + +constexpr std::string_view AnalysisDir = "Analysis/"; +constexpr std::string_view QaDir = "QA/"; +constexpr std::string_view McDir = "MC/"; + +/// \class Sigma0HistManager +/// \brief Class for histogramming sigma0 +template +class Sigma0HistManager +{ + public: + Sigma0HistManager() = default; + ~Sigma0HistManager() = default; + + // minimal init + template + void init(o2::framework::HistogramRegistry* registry, + std::map> const& Sigma0Specs, + T1 const& ConfSigma0Selection) + { + mHistogramRegistry = registry; + mPdgCode = std::abs(ConfSigma0Selection.pdgCodeAbs.value); + if (mPdgCode != PDG_t::kSigma0) { + LOG(fatal) << "PDG code for Sigma0 has to be Sigma0"; + } + if (ConfSigma0Selection.sign.value <= 0) { + mPdgCode = -mPdgCode; + } + + if constexpr (modes::isFlagSet(mode, modes::Mode::kReco)) { + this->initAnalysis(Sigma0Specs); + } + if constexpr (modes::isFlagSet(mode, modes::Mode::kMc)) { + this->initMc(Sigma0Specs); + } + } + + // init with qa + template + void init(o2::framework::HistogramRegistry* registry, + std::map> const& Sigma0Specs, + T1 const& ConfSigma0Selection, + T2 const& ConfSigma0BinningQa) + { + this->template init(registry, Sigma0Specs, ConfSigma0Selection); + this->enableOptionalHistograms(ConfSigma0BinningQa); + if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { + this->initQa(Sigma0Specs); + } + } + + // init with qa + lambda and photon managers + template + void init(o2::framework::HistogramRegistry* registry, + std::map> const& Sigma0Specs, + T1 const& ConfSigma0Selection, + T2 const& ConfSigma0BinningQa, + std::map> const& LambdaSpecs, + T3 const& ConfLambdaSelection, + std::map> const& PosDauSpecs, + std::map> const& NegDauSpecs, + std::map> const& PhotonSpecs) + { + this->template init(registry, Sigma0Specs, ConfSigma0Selection, ConfSigma0BinningQa); + mLambdaManager.template init(registry, LambdaSpecs, ConfLambdaSelection, PosDauSpecs, NegDauSpecs); + mPhotonManager.template init(registry, PhotonSpecs); + } + + // fill only sigma0 + template + void fill(T1 const& sigma0candidate) + { + if constexpr (modes::isFlagSet(mode, modes::Mode::kReco)) { + this->fillAnalysis(sigma0candidate); + } + if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { + this->fillQa(sigma0candidate); + } + } + + // wrapper for tripletProcessHelpers + template + void fill(T1 const& sigma0candidate, T2 const& tracks) + { + this->fillAnalysis(sigma0candidate); + } + + // fill sigma0 + lambda + photon + template + void fill(T1 const& sigma0candidate, T2 const& v0table, T3 const& photontable, T4 const& tracks) + { + this->template fill(sigma0candidate); + auto lambdau = v0table.rawIteratorAt(sigma0candidate.lambdaId() - v0table.offset()); + mLambdaManager.template fill(lambdau, tracks); // do not fill qa for daughters + auto photondau = photontable.rawIteratorAt(sigma0candidate.photonId() - photontable.offset()); + mPhotonManager.template fill(photondau); + } + // fill mc + template + void fill(T1 const& sigma0candidate, T2 const& col, T3 const& mcParticles, T4 const& mcMothers, T5 const& mcPartonicMothers) + { + this->template fill(sigma0candidate); + if constexpr (modes::isFlagSet(mode, modes::Mode::kMc)) { + this->template fillMc(sigma0candidate, col, mcParticles, mcMothers, mcPartonicMothers); + } + } + // wrapper for tripletProcessHelpers + template + void fill(T1 const& sigma0candidate, T2 const& trackTable, T3 const& col, T4 const& mcParticles, T5 const& mcMothers, T6 const& mcPartonicMothers) + { + this->template fillMc(sigma0candidate, col, mcParticles, mcMothers, mcPartonicMothers); + } + // fill mc + lambda + photon + template + void fill(T1 const& sigma0candidate, T2 const& col, T3 const& mcParticles, T4 const& mcMothers, T5 const& mcPartonicMothers, T6 const& v0table, T7 const& tracks) + { + this->template fillMc(sigma0candidate, col, mcParticles, mcMothers, mcPartonicMothers); + auto lambdau = v0table.rawIteratorAt(sigma0candidate.lambdaId() - v0table.offset()); + mLambdaManager.template fill(lambdau, tracks, col, mcParticles, mcMothers, mcPartonicMothers); + // photon MC manager is not implemented yet + // auto photondau = photontable.rawIteratorAt(sigma0candidate.photonId() - photontable.offset()); + // mPhotonManager.template fill(photondau, col, mcParticles, mcMothers, mcPartonicMothers); + } + + private: + template + void enableOptionalHistograms(T1 const& Sigma0ConfBinningQa) + { + mPlot2d = Sigma0ConfBinningQa.plot2d.value; + mPlotOrigins = Sigma0ConfBinningQa.plotOrigins.value; + mPlotNSecondaries = Sigma0ConfBinningQa.pdgCodesForMothersOfSecondary.value.size(); + for (std::size_t i = 0; i < MaxSecondary; i++) { + if (i < Sigma0ConfBinningQa.pdgCodesForMothersOfSecondary.value.size()) { + mPdgCodesSecondaryMother.at(i) = std::abs(Sigma0ConfBinningQa.pdgCodesForMothersOfSecondary.value.at(i)); + } else { + mPdgCodesSecondaryMother.at(i) = 0; + } + } + } + + void initAnalysis(std::map> const& Sigma0Specs) + { + std::string analysisDir = std::string(sigma0Prefix) + std::string(AnalysisDir); + mHistogramRegistry->add(analysisDir + getHistNameV2(kPt, HistTable), getHistDesc(kPt, HistTable), getHistType(kPt, HistTable), {Sigma0Specs.at(kPt)}); + mHistogramRegistry->add(analysisDir + getHistNameV2(kEta, HistTable), getHistDesc(kEta, HistTable), getHistType(kEta, HistTable), {Sigma0Specs.at(kEta)}); + mHistogramRegistry->add(analysisDir + getHistNameV2(kPhi, HistTable), getHistDesc(kPhi, HistTable), getHistType(kPhi, HistTable), {Sigma0Specs.at(kPhi)}); + mHistogramRegistry->add(analysisDir + getHistNameV2(kMass, HistTable), getHistDesc(kMass, HistTable), getHistType(kMass, HistTable), {Sigma0Specs.at(kMass)}); + mHistogramRegistry->add(analysisDir + getHistNameV2(kSign, HistTable), getHistDesc(kSign, HistTable), getHistType(kSign, HistTable), {Sigma0Specs.at(kSign)}); + mHistogramRegistry->add(analysisDir + getHistNameV2(kPtVsMass, HistTable), getHistDesc(kPtVsMass, HistTable), getHistType(kPtVsMass, HistTable), {Sigma0Specs.at(kPtVsMass)}); + } + + void initQa(std::map> const& Sigma0Specs) + { + std::string qaDir = std::string(sigma0Prefix) + std::string(QaDir); + + mHistogramRegistry->add(qaDir + getHistNameV2(kCosPa, HistTable), getHistDesc(kCosPa, HistTable), getHistType(kCosPa, HistTable), {Sigma0Specs.at(kCosPa)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kDecayVtxX, HistTable), getHistDesc(kDecayVtxX, HistTable), getHistType(kDecayVtxX, HistTable), {Sigma0Specs.at(kDecayVtxX)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kDecayVtxY, HistTable), getHistDesc(kDecayVtxY, HistTable), getHistType(kDecayVtxY, HistTable), {Sigma0Specs.at(kDecayVtxY)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kDecayVtxZ, HistTable), getHistDesc(kDecayVtxZ, HistTable), getHistType(kDecayVtxZ, HistTable), {Sigma0Specs.at(kDecayVtxZ)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kDecayVtx, HistTable), getHistDesc(kDecayVtx, HistTable), getHistType(kDecayVtx, HistTable), {Sigma0Specs.at(kDecayVtx)}); + + if (mPlot2d) { + mHistogramRegistry->add(qaDir + getHistNameV2(kPtVsEta, HistTable), getHistDesc(kPtVsEta, HistTable), getHistType(kPtVsEta, HistTable), {Sigma0Specs.at(kPtVsEta)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kPtVsPhi, HistTable), getHistDesc(kPtVsPhi, HistTable), getHistType(kPtVsPhi, HistTable), {Sigma0Specs.at(kPtVsPhi)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kPhiVsEta, HistTable), getHistDesc(kPhiVsEta, HistTable), getHistType(kPhiVsEta, HistTable), {Sigma0Specs.at(kPhiVsEta)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kPtVsCosPa, HistTable), getHistDesc(kPtVsCosPa, HistTable), getHistType(kPtVsCosPa, HistTable), {Sigma0Specs.at(kPtVsCosPa)}); + + mHistogramRegistry->add(qaDir + getHistNameV2(kMassSigma0, HistTable), getHistDesc(kMassSigma0, HistTable), getHistType(kMassSigma0, HistTable), {Sigma0Specs.at(kMassSigma0)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kMassAntiSigma0, HistTable), getHistDesc(kMassAntiSigma0, HistTable), getHistType(kMassAntiSigma0, HistTable), {Sigma0Specs.at(kMassAntiSigma0)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kPtVsSigma0Mass, HistTable), getHistDesc(kPtVsSigma0Mass, HistTable), getHistType(kPtVsSigma0Mass, HistTable), {Sigma0Specs.at(kPtVsSigma0Mass)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kPtVsAntiSigma0Mass, HistTable), getHistDesc(kPtVsAntiSigma0Mass, HistTable), getHistType(kPtVsAntiSigma0Mass, HistTable), {Sigma0Specs.at(kPtVsAntiSigma0Mass)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kSigma0MassVsAntiSigma0Mass, HistTable), getHistDesc(kSigma0MassVsAntiSigma0Mass, HistTable), getHistType(kSigma0MassVsAntiSigma0Mass, HistTable), {Sigma0Specs.at(kSigma0MassVsAntiSigma0Mass)}); + } + } + + void initMc(std::map> const& Sigma0Specs) + { + std::string mcDir = std::string(sigma0Prefix) + std::string(McDir); + mHistogramRegistry->add(mcDir + getHistNameV2(kTruePtVsPt, HistTable), getHistDesc(kTruePtVsPt, HistTable), getHistType(kTruePtVsPt, HistTable), {Sigma0Specs.at(kTruePtVsPt)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueEtaVsEta, HistTable), getHistDesc(kTrueEtaVsEta, HistTable), getHistType(kTrueEtaVsEta, HistTable), {Sigma0Specs.at(kTrueEtaVsEta)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTruePhiVsPhi, HistTable), getHistDesc(kTruePhiVsPhi, HistTable), getHistType(kTruePhiVsPhi, HistTable), {Sigma0Specs.at(kTruePhiVsPhi)}); + + // mc origin can be configured here + const o2::framework::AxisSpec axisOrigin = {static_cast(modes::McOrigin::kMcOriginLast), -0.5, static_cast(modes::McOrigin::kMcOriginLast) - 0.5}; + mHistogramRegistry->add(mcDir + getHistNameV2(kOrigin, HistTable), getHistDesc(kOrigin, HistTable), getHistType(kOrigin, HistTable), {axisOrigin}); + mHistogramRegistry->get(HIST(sigma0Prefix) + HIST(McDir) + HIST(histmanager::getHistName(kOrigin, HistTable)))->GetXaxis()->SetBinLabel(1 + static_cast(modes::McOrigin::kNoMcParticle), modes::mcOriginToString(modes::McOrigin::kNoMcParticle)); + mHistogramRegistry->get(HIST(sigma0Prefix) + HIST(McDir) + HIST(histmanager::getHistName(kOrigin, HistTable)))->GetXaxis()->SetBinLabel(1 + static_cast(modes::McOrigin::kFromWrongCollision), modes::mcOriginToString(modes::McOrigin::kFromWrongCollision)); + mHistogramRegistry->get(HIST(sigma0Prefix) + HIST(McDir) + HIST(histmanager::getHistName(kOrigin, HistTable)))->GetXaxis()->SetBinLabel(1 + static_cast(modes::McOrigin::kPhysicalPrimary), modes::mcOriginToString(modes::McOrigin::kPhysicalPrimary)); + + mHistogramRegistry->add(mcDir + getHistNameV2(kPdg, HistTable), getHistDesc(kPdg, HistTable), getHistType(kPdg, HistTable), {Sigma0Specs.at(kPdg)}); + + if (mPlotOrigins) { + mHistogramRegistry->add(mcDir + getHistNameV2(kNoMcParticle, HistTable), getHistDesc(kNoMcParticle, HistTable), getHistType(kNoMcParticle, HistTable), {Sigma0Specs.at(kNoMcParticle)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kPrimary, HistTable), getHistDesc(kPrimary, HistTable), getHistType(kPrimary, HistTable), {Sigma0Specs.at(kPrimary)}); + } + } + + template + void fillAnalysis(T const& sigma0candidate) + { + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(AnalysisDir) + HIST(getHistName(kPt, HistTable)), sigma0candidate.pt()); + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(AnalysisDir) + HIST(getHistName(kEta, HistTable)), sigma0candidate.eta()); + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(AnalysisDir) + HIST(getHistName(kPhi, HistTable)), sigma0candidate.phi()); + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(AnalysisDir) + HIST(getHistName(kMass, HistTable)), sigma0candidate.mass()); + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(AnalysisDir) + HIST(getHistName(kPtVsMass, HistTable)), sigma0candidate.pt(), sigma0candidate.mass()); + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(AnalysisDir) + HIST(getHistName(kSign, HistTable)), sigma0candidate.sign()); + } + + template + void fillQa(T1 const& sigma0candidate) + { + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(QaDir) + HIST(getHistName(kCosPa, HistTable)), sigma0candidate.cosPa()); + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(QaDir) + HIST(getHistName(kDecayVtxX, HistTable)), sigma0candidate.decayVtxX()); + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(QaDir) + HIST(getHistName(kDecayVtxY, HistTable)), sigma0candidate.decayVtxY()); + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(QaDir) + HIST(getHistName(kDecayVtxZ, HistTable)), sigma0candidate.decayVtxZ()); + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(QaDir) + HIST(getHistName(kDecayVtx, HistTable)), sigma0candidate.decayVtx()); + + float massSigma0 = 0; + float massAntiSigma0 = 0; + + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(QaDir) + HIST(getHistName(kMassSigma0, HistTable)), massSigma0); + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(QaDir) + HIST(getHistName(kMassAntiSigma0, HistTable)), massAntiSigma0); + + if (mPlot2d) { + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(QaDir) + HIST(getHistName(kPtVsEta, HistTable)), sigma0candidate.pt(), sigma0candidate.eta()); + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(QaDir) + HIST(getHistName(kPtVsPhi, HistTable)), sigma0candidate.pt(), sigma0candidate.phi()); + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(QaDir) + HIST(getHistName(kPhiVsEta, HistTable)), sigma0candidate.phi(), sigma0candidate.eta()); + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(QaDir) + HIST(getHistName(kPtVsCosPa, HistTable)), sigma0candidate.pt(), sigma0candidate.cosPa()); + + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(QaDir) + HIST(getHistName(kPtVsSigma0Mass, HistTable)), sigma0candidate.pt(), massSigma0); + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(QaDir) + HIST(getHistName(kPtVsAntiSigma0Mass, HistTable)), sigma0candidate.pt(), massAntiSigma0); + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(QaDir) + HIST(getHistName(kSigma0MassVsAntiSigma0Mass, HistTable)), massSigma0, massAntiSigma0); + } + } + + template + void fillMc(T1 const& sigma0Candidate, T2 const& col, T3 const& /*mcParticles*/, T4 const& /*mcMothers*/, T5 const& /*mcPartonicMothers*/) + { + // No MC Particle + if (!sigma0Candidate.has_fMcParticle()) { + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(McDir) + HIST(getHistName(kPdg, HistTable)), 0); + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(McDir) + HIST(getHistName(kOrigin, HistTable)), static_cast(modes::McOrigin::kNoMcParticle)); + if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { + if (mPlotOrigins) { + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(McDir) + HIST(getHistName(kNoMcParticle, HistTable)), sigma0Candidate.pt(), sigma0Candidate.cosPa()); + } + } + return; + } + + // Retrieve MC particle + auto mcParticle = sigma0Candidate.template fMcParticle_as(); + + // whether a particle is associated to a wrong collision or not cannot be known by the producer so we check it here + bool fromWrongCollision = mcParticle.fMcColId() != col.fMcColId(); + + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(McDir) + HIST(getHistName(kTruePtVsPt, HistTable)), mcParticle.pt(), sigma0Candidate.pt()); + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(McDir) + HIST(getHistName(kTrueEtaVsEta, HistTable)), mcParticle.eta(), sigma0Candidate.eta()); + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(McDir) + HIST(getHistName(kTruePhiVsPhi, HistTable)), mcParticle.phi(), sigma0Candidate.phi()); + if (!fromWrongCollision) { + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(McDir) + HIST(getHistName(kOrigin, HistTable)), mcParticle.origin()); + } + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(McDir) + HIST(getHistName(kPdg, HistTable)), mcParticle.pdgCode()); + + if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { + if (mPlotOrigins) { + // check first if particle is missidentified + if (!fromWrongCollision) { + // if not, we fill it acccoridng to its origin + switch (static_cast(mcParticle.origin())) { + case modes::McOrigin::kPhysicalPrimary: + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(McDir) + HIST(getHistName(kPrimary, HistTable)), sigma0Candidate.pt(), sigma0Candidate.cosPa()); + break; + default: + LOG(warn) << "Encountered particle with unknown origin!"; + break; + } + } + } + } + } + + o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; + int mPdgCode = 0; + bool mPlotOrigins = false; + int mPlotNSecondaries = 0; + std::array mPdgCodesSecondaryMother = {0}; + bool mPlot2d = false; + + inline static constexpr std::string_view PrefixLambda = "Sigma0/DauLambda/"; + inline static constexpr std::string_view PrefixPos = "Sigma0/DauLambda/PosDau/"; + inline static constexpr std::string_view PrefixNeg = "Sigma0/DauLambda/NegDau/"; + inline static constexpr std::string_view PrefixPhoton = "Sigma0/DauPhoton/"; + v0histmanager::V0HistManager mLambdaManager; + photonhistmanager::PhotonHistManager mPhotonManager; +}; +}; // namespace o2::analysis::femto::sigma0histmanager +#endif // PWGCF_FEMTO_CORE_Sigma0HISTMANAGER_H_ diff --git a/PWGCF/Femto/Core/tripletBuilder.h b/PWGCF/Femto/Core/tripletBuilder.h index 8a39f818c8b..4912b58827c 100644 --- a/PWGCF/Femto/Core/tripletBuilder.h +++ b/PWGCF/Femto/Core/tripletBuilder.h @@ -28,6 +28,7 @@ #include "PWGCF/Femto/Core/tripletHistManager.h" #include "PWGCF/Femto/Core/tripletProcessHelpers.h" #include "PWGCF/Femto/Core/v0HistManager.h" +#include "PWGCF/Femto/Core/sigma0HistManager.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" #include @@ -1008,6 +1009,282 @@ class TripletTrackTrackCascadeBuilder std::uniform_int_distribution<> mDist; }; +template +class TripletTrackTrackSigma0Builder +{ + public: + TripletTrackTrackSigma0Builder() = default; + ~TripletTrackTrackSigma0Builder() = default; + + template + void init(o2::framework::HistogramRegistry* registry, + T1 const& confCollisionBinning, + T2 const& confTrackSelection1, + T3 const& confTrackSelection2, + T4 const& confSigma0Selection, + T5 const& confCleaner1, + T6 const& confCleaner2, + T7 const& confSigma0Cleaner, + T8 const& confCtr, + T9 const& confMixing, + T10 const& confTripletBinning, + T11 const& confTripletCuts, + std::map> const& colHistSpec, + std::map> const& trackHistSpec1, + std::map> const& trackHistSpec2, + std::map> const& sigma0histSpec, + std::map> const& tripletHistSpec, + std::map> const& ctrHistSpec, + std::map> const& tripletCleanerHistSpec) + { + // check if correlating the same track species/selections or not + mTrack1Track2AreSameSpecies = confMixing.particle12AreSameSpecies.value; + + mColHistManager.template init(registry, colHistSpec, confCollisionBinning); + mTripletHistManagerSe.template init(registry, tripletHistSpec, confTripletBinning, confTripletCuts, confMixing); + mTripletHistManagerMe.template init(registry, tripletHistSpec, confTripletBinning, confTripletCuts, confMixing); + + mTcSe.template init(registry, tripletCleanerHistSpec, confTripletCuts); + mTcMe.template init(registry, tripletCleanerHistSpec, confTripletCuts); + + mSigma0Cleaner.init(confSigma0Cleaner); + + if (mTrack1Track2AreSameSpecies) { + // Track1 & Track2 are the same species and track 3 is Sigma0 + mCleaner1.init(confCleaner1); + mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); + mSigma0HistManager.template init(registry, sigma0histSpec, confSigma0Selection); + + mTripletHistManagerSe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection1.pdgCodeAbs.value, confSigma0Selection.pdgCodeAbs.value); + mTripletHistManagerSe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value, 1); + mCtrSe.init(registry, ctrHistSpec, confCtr, confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value); + + mTripletHistManagerMe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection1.pdgCodeAbs.value, confSigma0Selection.pdgCodeAbs.value); + mTripletHistManagerMe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value, 1); + mCtrMe.init(registry, ctrHistSpec, confCtr, confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value); + } else { + // all three tracks are different + mCleaner1.init(confCleaner1); + mCleaner2.init(confCleaner2); + mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); + mTrackHistManager2.template init(registry, trackHistSpec2, confTrackSelection2); + mSigma0HistManager.template init(registry, sigma0histSpec, confSigma0Selection); + + mTripletHistManagerSe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection2.pdgCodeAbs.value, confSigma0Selection.pdgCodeAbs.value); + mTripletHistManagerSe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection2.chargeAbs.value, 1); + mCtrSe.init(registry, ctrHistSpec, confCtr, confTrackSelection1.chargeAbs.value, confTrackSelection2.chargeAbs.value); + + mTripletHistManagerMe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection2.pdgCodeAbs.value, confSigma0Selection.pdgCodeAbs.value); + mTripletHistManagerMe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection2.chargeAbs.value, 1); + mCtrMe.init(registry, ctrHistSpec, confCtr, confTrackSelection1.chargeAbs.value, confTrackSelection2.chargeAbs.value); + } + + // setup mixing + mMixingPolicy = static_cast(confMixing.policy.value); + mMixingDepth = confMixing.depth.value; + + // setup rng if necessary + if (confMixing.seed.value >= 0) { + uint64_t randomSeed = 0; + mMixIdenticalParticles = true; + if (confMixing.seed.value == 0) { + randomSeed = static_cast(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); + } else { + randomSeed = static_cast(confMixing.seed.value); + } + mRng = std::mt19937(randomSeed); + mDist = std::uniform_int_distribution<>(tripletprocesshelpers::kOrder123, tripletprocesshelpers::kOrder213); + } + } + + // data + /// \return true if at least one triplet passed all triplet selections (usable as triplet trigger) + template + bool processSameEvent(T1 const& col, T2& trackTable, T3& partition1, T4& partition2, T5& partition3, T6& cache) + { + tripletprocesshelpers::TripletOrder tripletOrder = tripletprocesshelpers::kOrder123; + if (mTrack1Track2AreSameSpecies) { + auto trackSlice1 = partition1->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + auto sigma0Slice = partition3->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + if (trackSlice1.size() < nLimitPartitionIdenticalParticles12 || sigma0Slice.size() < nLimitPartitionParticles) { + return false; + } + mColHistManager.template fill(col); + mCtrSe.setMagField(col.magField()); + if (mMixIdenticalParticles) { + tripletOrder = static_cast(mDist(mRng)); + } + return tripletprocesshelpers::processSameEvent(trackSlice1, sigma0Slice, trackTable, col, mTrackHistManager1, mSigma0HistManager, mTripletHistManagerSe, mCtrSe, mTcSe, tripletOrder); + } + + auto trackSlice1 = partition1->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + auto trackSlice2 = partition2->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + auto sigma0Slice = partition3->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + if (trackSlice1.size() < nLimitPartitionParticles || trackSlice2.size() < nLimitPartitionParticles || sigma0Slice.size() < nLimitPartitionParticles) { + return false; + } + mColHistManager.template fill(col); + mCtrSe.setMagField(col.magField()); + return tripletprocesshelpers::processSameEvent(trackSlice1, trackSlice2, sigma0Slice, trackTable, col, mTrackHistManager1, mTrackHistManager2, mSigma0HistManager, mTripletHistManagerSe, mCtrSe, mTcSe); + } + + // mc + /// \return true if at least one triplet passed all triplet selections (usable as triplet trigger) + template + bool processSameEvent(T1 const& col, T2 const& mcCols, T3& trackTable, T4& partition1, T5& partition2, T6& partition3, T7 const& mcParticles, T8 const& mcMothers, T9 const& mcPartonicMothers, T10& cache) + { + tripletprocesshelpers::TripletOrder tripletOrder = tripletprocesshelpers::kOrder123; + if (mTrack1Track2AreSameSpecies) { + auto trackSlice1 = partition1->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + auto sigma0Slice = partition3->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + if (trackSlice1.size() < nLimitPartitionIdenticalParticles12 || sigma0Slice.size() < nLimitPartitionParticles) { + return false; + } + mColHistManager.template fill(col, mcCols); + mCtrSe.setMagField(col.magField()); + if (mMixIdenticalParticles) { + tripletOrder = static_cast(mDist(mRng)); + } + return tripletprocesshelpers::processSameEvent(trackSlice1, sigma0Slice, trackTable, mcParticles, mcMothers, mcPartonicMothers, col, mcCols, mTrackHistManager1, mSigma0HistManager, mTripletHistManagerSe, mCleaner1, mSigma0Cleaner, mCtrSe, mTcSe, tripletOrder); + } + + auto trackSlice1 = partition1->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + auto trackSlice2 = partition2->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + auto sigma0Slice = partition3->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + if (trackSlice1.size() < nLimitPartitionParticles || trackSlice2.size() < nLimitPartitionParticles || sigma0Slice.size() < nLimitPartitionParticles) { + return false; + } + mColHistManager.template fill(col, mcCols); + mCtrSe.setMagField(col.magField()); + return tripletprocesshelpers::processSameEvent(trackSlice1, trackSlice2, sigma0Slice, trackTable, mcParticles, mcMothers, mcPartonicMothers, col, mcCols, mTrackHistManager1, mTrackHistManager2, mSigma0HistManager, mTripletHistManagerSe, mCleaner1, mCleaner2, mSigma0Cleaner, mCtrSe, mTcSe); + } + + // data + template + void processMixedEvent(T1 const& cols, T2& trackTable, T3& partition1, T4& partition2, T5& partition3, T6& cache, T7& binsVtxMult, T8& binsVtxCent, T9& binsVtxMultCent) + { + if (mTrack1Track2AreSameSpecies) { + switch (mMixingPolicy) { + case static_cast(pairhistmanager::kVtxMult): + tripletprocesshelpers::processMixedEvent(cols, partition1, partition1, partition3, trackTable, cache, binsVtxMult, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager1, mSigma0HistManager); + break; + case static_cast(pairhistmanager::kVtxCent): + tripletprocesshelpers::processMixedEvent(cols, partition1, partition1, partition3, trackTable, cache, binsVtxCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager1, mSigma0HistManager); + break; + case static_cast(pairhistmanager::kVtxMultCent): + tripletprocesshelpers::processMixedEvent(cols, partition1, partition1, partition3, trackTable, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager1, mSigma0HistManager); + break; + default: + LOG(fatal) << "Invalid binning policy specifed. Breaking..."; + } + } else { + switch (mMixingPolicy) { + case static_cast(pairhistmanager::kVtxMult): + tripletprocesshelpers::processMixedEvent(cols, partition1, partition2, partition3, trackTable, cache, binsVtxMult, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager2, mSigma0HistManager); + break; + case static_cast(pairhistmanager::kVtxCent): + tripletprocesshelpers::processMixedEvent(cols, partition1, partition2, partition3, trackTable, cache, binsVtxCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager2, mSigma0HistManager); + break; + case static_cast(pairhistmanager::kVtxMultCent): + tripletprocesshelpers::processMixedEvent(cols, partition1, partition2, partition3, trackTable, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager2, mSigma0HistManager); + break; + default: + LOG(fatal) << "Invalid binning policy specifed. Breaking..."; + } + } + } + + // mc — NOTE: now takes mcMothers, mcPartonicMothers (required by the fixed tripletprocesshelpers mc overload) + template + void processMixedEvent(T1 const& cols, T2 const& mcCols, T3& trackTable, T4& partition1, T5& partition2, T6& partition3, T7 const& mcParticles, T8 const& mcMothers, T9 const& mcPartonicMothers, T10& cache, T11& binsVtxMult, T12& binsVtxCent, T13& binsVtxMultCent) + { + if (mTrack1Track2AreSameSpecies) { + switch (mMixingPolicy) { + case static_cast(pairhistmanager::kVtxMult): + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition1, partition3, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxMult, mMixingDepth, mTripletHistManagerMe, mCleaner1, mCleaner1, mSigma0Cleaner, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager1, mSigma0HistManager); + break; + case static_cast(pairhistmanager::kVtxCent): + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition1, partition3, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxCent, mMixingDepth, mTripletHistManagerMe, mCleaner1, mCleaner1, mSigma0Cleaner, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager1, mSigma0HistManager); + break; + case static_cast(pairhistmanager::kVtxMultCent): + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition1, partition3, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCleaner1, mCleaner1, mSigma0Cleaner, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager1, mSigma0HistManager); + break; + default: + LOG(fatal) << "Invalid binning policy specifed. Breaking..."; + } + } else { + switch (mMixingPolicy) { + case static_cast(pairhistmanager::kVtxMult): + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition2, partition3, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxMult, mMixingDepth, mTripletHistManagerMe, mCleaner1, mCleaner2, mSigma0Cleaner, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager2, mSigma0HistManager); + break; + case static_cast(pairhistmanager::kVtxCent): + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition2, partition3, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxCent, mMixingDepth, mTripletHistManagerMe, mCleaner1, mCleaner2, mSigma0Cleaner, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager2, mSigma0HistManager); + break; + case static_cast(pairhistmanager::kVtxMultCent): + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition2, partition3, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCleaner1, mCleaner2, mSigma0Cleaner, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager2, mSigma0HistManager); + break; + default: + LOG(fatal) << "Invalid binning policy specifed. Breaking..."; + } + } + } + + private: + colhistmanager::CollisionHistManager mColHistManager; + trackhistmanager::TrackHistManager mTrackHistManager1; + trackhistmanager::TrackHistManager mTrackHistManager2; + sigma0histmanager::Sigma0HistManager mSigma0HistManager; + particlecleaner::ParticleCleaner mCleaner1; + particlecleaner::ParticleCleaner mCleaner2; + particlecleaner::ParticleCleaner mSigma0Cleaner; + triplethistmanager::TripletHistManager mTripletHistManagerSe; + triplethistmanager::TripletHistManager mTripletHistManagerMe; + + closetripletrejection::CloseTripletRejectionTrackTrackSigma0 mCtrSe; + closetripletrejection::CloseTripletRejectionTrackTrackSigma0 mCtrMe; + tripletcleaner::TrackTrackSigma0TripletCleaner mTcSe; + tripletcleaner::TrackTrackSigma0TripletCleaner mTcMe; + triplethistmanager::MixingPolicy mMixingPolicy = triplethistmanager::MixingPolicy::kVtxMult; + bool mTrack1Track2AreSameSpecies = false; + int mEventStride = 1; + int mMixingDepth = 5; + bool mMixIdenticalParticles = false; + std::mt19937 mRng; + std::uniform_int_distribution<> mDist; +}; + + // builder for triplets of generated particles (mc truth only, kMc without kReco) // covers all triplet types, since e.g. a lambda is just another mc particle template +class TrackTrackSigma0TripletCleaner : public paircleaner::BasePairCleaner +{ + public: + TrackTrackSigma0TripletCleaner() = default; + ~TrackTrackSigma0TripletCleaner() override = default; + + template + bool isCleanTriplet(T1 const& track1, T2 const& track2, T3 const& sigma0, T4 const& trackTable, T5 const& tripletHistManager) const + { + this->fillAll(); + auto posDaughter = trackTable.rawIteratorAt(sigma0.posDauId() - trackTable.offset()); + auto negDaughter = trackTable.rawIteratorAt(sigma0.negDauId() - trackTable.offset()); + bool isClean = this->isCleanParticlePair(track1, track2) && + this->isCleanParticlePair(track1, posDaughter) && + this->isCleanParticlePair(track1, negDaughter) && + this->isCleanParticlePair(track2, posDaughter) && + this->isCleanParticlePair(track2, negDaughter); + if (!isClean) { + this->fillBlocked(tripletHistManager.getKinematic(this->mKinematicVariable)); + } + return isClean; + } + + template + bool isCleanTriplet(T1 const& track1, T2 const& track2, T3 const& sigma0, T4 const& trackTable, T5 const& mcParticles, T6 const& partonicMothers, T7 const& tripletHistManager) const + { + if (!this->isCleanTriplet(track1, track2, sigma0, trackTable, tripletHistManager)) { + return false; + } + // pair is clean + // no check if we require common or non-common ancestry + auto posDaughter = trackTable.rawIteratorAt(sigma0.posDauId() - trackTable.offset()); + auto negDaughter = trackTable.rawIteratorAt(sigma0.negDauId() - trackTable.offset()); + if (this->mMixPairsWithCommonAncestor) { + return this->pairHasCommonAncestor(track1, track2, mcParticles, partonicMothers) && + this->pairHasCommonAncestor(track1, posDaughter, mcParticles, partonicMothers) && + this->pairHasCommonAncestor(track1, negDaughter, mcParticles, partonicMothers) && + this->pairHasCommonAncestor(track2, posDaughter, mcParticles, partonicMothers) && + this->pairHasCommonAncestor(track2, negDaughter, mcParticles, partonicMothers); + } + if (this->mMixPairsWithNonCommonAncestor) { + return this->pairHasNonCommonAncestor(track1, track2, mcParticles, partonicMothers) && + this->pairHasNonCommonAncestor(track1, posDaughter, mcParticles, partonicMothers) && + this->pairHasNonCommonAncestor(track1, negDaughter, mcParticles, partonicMothers) && + this->pairHasNonCommonAncestor(track2, posDaughter, mcParticles, partonicMothers) && + this->pairHasNonCommonAncestor(track2, negDaughter, mcParticles, partonicMothers); + } + return true; + } +}; + // triplet of generated particles; there are no daughters to share, so only the // (non-)common ancestry requirement can reject a triplet template diff --git a/PWGCF/Femto/Core/tripletHistManager.h b/PWGCF/Femto/Core/tripletHistManager.h index b7eadec7642..ff298434806 100644 --- a/PWGCF/Femto/Core/tripletHistManager.h +++ b/PWGCF/Femto/Core/tripletHistManager.h @@ -306,6 +306,9 @@ constexpr char PrefixMcParticleMcParticleMcParticleMe[] = "McParticleMcParticleM constexpr char PrefixTrackTrackCascadeSe[] = "TrackTrackCascade/SE/"; constexpr char PrefixTrackTrackCascadeMe[] = "TrackTrackCascade/ME/"; +constexpr char PrefixTrackTrackSigma0Se[] = "TrackTrackSigma0/SE/"; +constexpr char PrefixTrackTrackSigma0Me[] = "TrackTrackSigma0/ME/"; + constexpr std::string_view AnalysisDir = "Analysis/"; constexpr std::string_view QaDir = "QA/"; constexpr std::string_view McDir = "MC/"; diff --git a/PWGCF/Femto/DataModel/FemtoTables.h b/PWGCF/Femto/DataModel/FemtoTables.h index 4816b1527b7..8d69506b0b7 100644 --- a/PWGCF/Femto/DataModel/FemtoTables.h +++ b/PWGCF/Femto/DataModel/FemtoTables.h @@ -1344,6 +1344,79 @@ DECLARE_SOA_TABLE_STAGED_VERSIONED(FSigmaPlusPcmExtras_001, "FSIGMAPCMEXTRA", 1, using FSigmaPlusPcmExtras = FSigmaPlusPcmExtras_001; using StoredFSigmaPlusPcmExtras = StoredFSigmaPlusPcmExtras_001; +namespace femtosigma0s +{ +DECLARE_SOA_COLUMN(Mask, mask, o2::analysis::femto::datatypes::Sigma0MaskType); //! Bitmask for track selections +DECLARE_SOA_INDEX_COLUMN_FULL(Lambda, lambda, int32_t, FLambdas, "_lambda"); ///< row in FLambdas +DECLARE_SOA_INDEX_COLUMN_FULL(Photon, photon, int32_t, FPhotons, "_photon"); ///< row in FPhotons +// id columns for Lambda daughter tracks +DECLARE_SOA_INDEX_COLUMN_FULL(PosDau, posDau, int32_t, FTracks, "_PosDau"); //! index column for positive daughter track +DECLARE_SOA_INDEX_COLUMN_FULL(NegDau, negDau, int32_t, FTracks, "_NegDau"); //! index column for negative daughter track + +namespace lite +{ +// Sigma0 1.192 +-100 MeV +constexpr float SigmaMassMin = 1.1f; +constexpr float SigmaMassMax = 1.3f; +constexpr float SigmaMassStep = (SigmaMassMax - SigmaMassMin) / 65536.f; + +inline uint16_t binSigma0Mass(float mass) { return o2::analysis::femto::utils::binLinear(mass, SigmaMassMin, SigmaMassMax, SigmaMassStep); } +inline float unBinSigma0Mass(uint16_t binned) { return o2::analysis::femto::utils::unBinLinear(binned, SigmaMassMin, SigmaMassStep); } + +DECLARE_SOA_COLUMN(BinnedSigma0Mass, binnedSigma0Mass, uint16_t); + +DECLARE_SOA_DYNAMIC_COLUMN(Mass, mass, + [](uint16_t binnedSigmaMass) -> float { + return unBinSigma0Mass(binnedSigmaMass); + }); + +// index for lite decay products +DECLARE_SOA_INDEX_COLUMN_FULL(Lambda, lambda, int32_t, FLiteLambdas, "_lambda"); +DECLARE_SOA_INDEX_COLUMN_FULL(Photon, photon, int32_t, FLitePhotons, "_photon"); +} // namespace lite +} // namespace femtosigma0s + +// Same collision index column as FLambdas/FPhotons, so Sigma0s can be sliced by femto collision +DECLARE_SOA_TABLE_STAGED_VERSIONED(FSigma0s_001, "FSIGMA0", 1, + o2::soa::Index<>, + femtobase::stored::FColId, + femtobase::stored::SignedPt, + femtobase::stored::Eta, + femtobase::stored::Phi, + femtobase::stored::Mass, + femtosigma0s::LambdaId, + femtosigma0s::PosDauId, + femtosigma0s::NegDauId, + femtosigma0s::PhotonId, + femtobase::dynamic::Pt, + femtobase::dynamic::Sign); +using FSigma0s = FSigma0s_001; + +DECLARE_SOA_TABLE_STAGED_VERSIONED(FSigma0Masks_001, "FSIGMA0MASK", 1, //! sigma0 masks + femtosigma0s::Mask); +using FSigma0Masks = FSigma0Masks_001; +// using StoredFSigma0Masks = StoredFSigma0Masks_001; + +// table for basic lambda information with compressed/binned kinematics +DECLARE_SOA_TABLE_STAGED_VERSIONED(FLiteSigma0s_001, "FLITESIGMA0", 1, + o2::soa::Index<>, + femtobase::stored::FLiteColId, + femtobase::lite::SignedBinnedPt, + femtobase::lite::BinnedEta, + femtobase::lite::BinnedPhi, + femtosigma0s::lite::BinnedSigma0Mass, + femtosigma0s::lite::LambdaId, + femtosigma0s::lite::PhotonId, + femtobase::lite::Sign, + femtobase::lite::SignedPt, + femtobase::lite::signedpt::Pt, + femtobase::lite::Eta, + femtobase::lite::Phi, + femtosigma0s::lite::Mass); +using FLiteSigma0s = FLiteSigma0s_001; +using FLiteSigma0 = FLiteSigma0s::iterator; +using StoredFLiteSigma0s = StoredFLiteSigma0s_001; + namespace femtocascades { // columns for cascade bit masks @@ -1832,6 +1905,13 @@ using FSigmaPlusLabel = FSigmaPlusLabels::iterator; using StoredFSigmaPlusLabels = StoredFSigmaPlusLabels_001; using StoredFSigmaPlusLabel = StoredFSigmaPlusLabels::iterator; +DECLARE_SOA_TABLE_STAGED_VERSIONED(FSigma0Labels_001, "FSIGMA0LABEL", 1, //! label from femto sigma to femto mc particle + femtolabels::FMcParticleId); +using FSigma0Labels = FSigma0Labels_001; +using FSigma0Label = FSigma0Labels::iterator; +using StoredFSigma0Labels = StoredFSigma0Labels_001; +using StoredFSigma0Label = StoredFSigma0Labels::iterator; + DECLARE_SOA_TABLE_STAGED_VERSIONED(FSigmaPlusPcmLabels_001, "FSIGMAPCMLABEL", 1, //! label from femto sigma plus (PCM) to femto mc particle femtolabels::FMcParticleId); using FSigmaPlusPcmLabels = FSigmaPlusPcmLabels_001; diff --git a/PWGCF/Femto/TableProducer/CMakeLists.txt b/PWGCF/Femto/TableProducer/CMakeLists.txt index 9658d1b354f..d8d03d762dc 100644 --- a/PWGCF/Femto/TableProducer/CMakeLists.txt +++ b/PWGCF/Femto/TableProducer/CMakeLists.txt @@ -48,3 +48,8 @@ o2physics_add_dpl_workflow(femto-producer-track-track-two-photon-resonances SOURCES ./femtoProducerTrackTrackTwoPhotonResonances.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(femto-sigma0-producer + SOURCES ./femtoSigma0Producer.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGCF/Femto/TableProducer/femtoSigma0Producer.cxx b/PWGCF/Femto/TableProducer/femtoSigma0Producer.cxx new file mode 100644 index 00000000000..f0f557a37ad --- /dev/null +++ b/PWGCF/Femto/TableProducer/femtoSigma0Producer.cxx @@ -0,0 +1,60 @@ +// 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 femtoSigma0Producer.cxx +/// \brief Derived-to-derived task: builds femto Sigma0 -> Lambda + gamma candidates from FLambdas and FPhotons +/// +/// Needs the full-precision FLambdas, FLambdaMasks, FPhotons and FPhotonMasks as input (i.e. the +/// producer ran with LambdaTables.produceLambdas and PhotonTables.producePhotons, not the Lite variants, +/// or the Lite tables were converted back before running this task). +/// \author Yakiv Paroviak, CTU in Prague, yakiv.paroviak@cern.ch + +#include "PWGCF/Femto/Core/sigma0Builder.h" +#include "PWGCF/Femto/DataModel/FemtoTables.h" + +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::analysis::femto; + +struct FemtoSigma0Producer { + using Lambdas = o2::soa::Join; + using Photons = o2::soa::Join; + + sigma0builder::Sigma0BuilderProducts products; + sigma0builder::ConfSigma0Filters filters; + sigma0builder::ConfSigma0Bits bits; + sigma0builder::ConfSigma0Tables tables; + sigma0builder::Sigma0Builder sigma0Builder; + + HistogramRegistry registry{"Sigma0", {}, OutputObjHandlingPolicy::AnalysisObject}; + + void init(InitContext& initContext) + { + sigma0Builder.init(®istry, filters, bits, tables, initContext); + } + + void process(Lambdas const& lambdas, Photons const& photons, o2::aod::FTracks const& tracks, o2::aod::FCols const& /**/, o2::aod::FColMasks const& /**/, o2::aod::FTrackMasks const& /**/) + { + sigma0Builder.fillSigma0s(products, lambdas, photons, tracks); + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} + diff --git a/PWGCF/Femto/Tasks/CMakeLists.txt b/PWGCF/Femto/Tasks/CMakeLists.txt index 1f9647bd7b2..7ade497aa96 100644 --- a/PWGCF/Femto/Tasks/CMakeLists.txt +++ b/PWGCF/Femto/Tasks/CMakeLists.txt @@ -129,6 +129,11 @@ o2physics_add_dpl_workflow(femto-triplet-track-track-cascade PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(femto-triplet-track-track-sigma0 + SOURCES femtoTripletTrackTrackSigma0.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(femto-triplet-mc-particle-mc-particle-mc-particle SOURCES femtoTripletMcParticleMcParticleMcParticle.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore diff --git a/PWGCF/Femto/Tasks/femtoTripletTrackTrackSigma0.cxx b/PWGCF/Femto/Tasks/femtoTripletTrackTrackSigma0.cxx new file mode 100644 index 00000000000..23a8a66f275 --- /dev/null +++ b/PWGCF/Femto/Tasks/femtoTripletTrackTrackSigma0.cxx @@ -0,0 +1,225 @@ +// 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 femtoTripletTrackTrackV0.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/closeTripletRejection.h" +#include "PWGCF/Femto/Core/collisionBuilder.h" +#include "PWGCF/Femto/Core/collisionHistManager.h" +#include "PWGCF/Femto/Core/modes.h" +#include "PWGCF/Femto/Core/pairCleaner.h" +#include "PWGCF/Femto/Core/particleCleaner.h" +#include "PWGCF/Femto/Core/partitions.h" +#include "PWGCF/Femto/Core/trackBuilder.h" +#include "PWGCF/Femto/Core/trackHistManager.h" +#include "PWGCF/Femto/Core/tripletBuilder.h" +#include "PWGCF/Femto/Core/tripletHistManager.h" +#include "PWGCF/Femto/Core/sigma0Builder.h" +#include "PWGCF/Femto/Core/sigma0HistManager.h" +#include "PWGCF/Femto/Core/v0HistManager.h" +#include "PWGCF/Femto/Core/photonHistManager.h" +#include "PWGCF/Femto/DataModel/FemtoTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +using namespace o2::analysis::femto; + +struct FemtoTripletTrackTrackSigma0 { + + // setup tables + using FemtoCollisions = o2::soa::Join; + using FilteredFemtoCollisions = o2::soa::Filtered; + using FilteredFemtoCollision = FilteredFemtoCollisions::iterator; + + using FemtoCollisionsWithLabel = o2::soa::Join; + using FilteredFemtoCollisionsWithLabel = o2::soa::Filtered; + using FilteredFemtoCollisionWithLabel = FilteredFemtoCollisionsWithLabel::iterator; + + using FemtoTracks = o2::soa::Join; + using FemtoSigma0s = o2::soa::Join; + + using FemtoTracksWithLabel = o2::soa::Join; + using FemtoSigma0sWithLabel = o2::soa::Join; + + using FemtoMcParticlesWithLabel = o2::soa::Join; + + o2::framework::SliceCache cache; + + // setup collisions + collisionbuilder::ConfCollisionSelection collisionSelection; + o2::framework::expressions::Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); + colhistmanager::ConfCollisionBinning confCollisionBinning; + + // setup tracks + trackbuilder::ConfTrackSelection1 confTrackSelections1; + trackhistmanager::ConfTrackBinning1 confTrackBinning1; + trackbuilder::ConfTrackSelection2 confTrackSelections2; + trackhistmanager::ConfTrackBinning2 confTrackBinning2; + inline static constexpr std::string_view PrefixTrack1 = "Track1/"; + inline static constexpr std::string_view PrefixTrack2 = "Track2/"; + + // particle cleaners (mc only) + particlecleaner::ConfTrackCleaner1 confTrackCleaner1; + particlecleaner::ConfTrackCleaner2 confTrackCleaner2; + particlecleaner::ConfSigma0Cleaner confSigma0Cleaner; + + o2::framework::Partition trackPartition1 = MAKE_TRACK_PARTITION(confTrackSelections1); + o2::framework::Partition trackPartition2 = MAKE_TRACK_PARTITION(confTrackSelections2); + o2::framework::Preslice perColtracks = o2::aod::femtobase::stored::fColId; + + o2::framework::Partition trackWithLabelPartition1 = MAKE_TRACK_PARTITION(confTrackSelections1); + o2::framework::Partition trackWithLabelPartition2 = MAKE_TRACK_PARTITION(confTrackSelections2); + o2::framework::Preslice perColtracksWithLabel = o2::aod::femtobase::stored::fColId; + + // setup for photon and lambda + v0histmanager::ConfLambdaBinning1 confLambdaBinning; + inline static constexpr std::string_view PrefixPhoton = "Sigma0/DauPhoton/"; + photonhistmanager::ConfPhotonBinning confPhotonBinning; + inline static constexpr std::string_view PrefixLambda = "Sigma0/DauLambda/"; + + // setup sigma0s + sigma0builder::ConfSigma0SelectionDefault confSigma0Selection; + sigma0histmanager::ConfSigma0BinningDefault confSigma0Binning; + + o2::framework::Partition sigma0Partition = MAKE_SIGMA0_PARTITION(confSigma0Selection); + o2::framework::Preslice perColSigma0s = o2::aod::femtobase::stored::fColId; + + o2::framework::Partition sigma0WithLabelPartition = MAKE_SIGMA0_PARTITION(confSigma0Selection); + o2::framework::Preslice perColSigma0sWithLabel = o2::aod::femtobase::stored::fColId; + + // setup triplets + triplethistmanager::ConfTripletBinning confTripletBinning; + triplethistmanager::ConfTripletCuts confTripletCuts; + paircleaner::ConfPairCleanerBinning confTripletCleanerBinning; + + closetripletrejection::ConfCtrTrackTrackV0 confCtr; + closepairrejection::ConfCprTrackV0Daughter confCpr; + + tripletbuilder::TripletTrackTrackSigma0Builder< + PrefixTrack1, + PrefixTrack2, + sigma0histmanager::PrefixSigma0, + PrefixLambda, + PrefixPhoton, + triplethistmanager::PrefixTrackTrackSigma0Se, + triplethistmanager::PrefixTrackTrackSigma0Me, + closetripletrejection::PrefixTrack1Track2Se, + closetripletrejection::PrefixTrack1Sigma0Se, + closetripletrejection::PrefixTrack2Sigma0Se, + closetripletrejection::PrefixTrack1Track2Me, + closetripletrejection::PrefixTrack1Sigma0Me, + closetripletrejection::PrefixTrack2Sigma0Me> + tripletTrackTrackSigma0Builder; + + // setup mixing + std::vector defaultVtxBins{10, -10, 10}; + std::vector defaultMultBins{50, 0, 200}; + std::vector defaultCentBins{10, 0, 100}; + o2::framework::ColumnBinningPolicy mixBinsVtxMult{{defaultVtxBins, defaultMultBins}}; + o2::framework::ColumnBinningPolicy mixBinsVtxCent{{defaultVtxBins, defaultCentBins}}; + o2::framework::ColumnBinningPolicy mixBinsVtxMultCent{{defaultVtxBins, defaultMultBins, defaultCentBins}}; + triplethistmanager::ConfMixing confMixing; + + o2::framework::HistogramRegistry hRegistry{"FemtoTrackTrackSigma0", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject}; + + void init(o2::framework::InitContext&) + { + if ((static_cast(doprocessSameEvent) + static_cast(doprocessSameEventMc)) > 1 || (static_cast(doprocessMixedEvent) + static_cast(doprocessMixedEventMc)) > 1) { + LOG(fatal) << "More than 1 same or mixed event process function is activated. Breaking..."; + } + bool processData = doprocessSameEvent || doprocessMixedEvent; + bool processMc = doprocessSameEventMc || doprocessMixedEventMc; + if (processData && processMc) { + LOG(fatal) << "Both data and mc processing is activated. Breaking..."; + } + + // setup columnpolicy for binning + // default values are used during instantiation, so we need to explicity update them here + mixBinsVtxMult = {{confMixing.vtxBins.value, confMixing.multBins.value}}; + mixBinsVtxCent = {{confMixing.vtxBins.value, confMixing.centBins.value}}; + mixBinsVtxMultCent = {{confMixing.vtxBins.value, confMixing.multBins.value, confMixing.centBins.value}}; + + // setup histogram specs + std::map> colHistSpec; + std::map> trackHistSpec1; + std::map> trackHistSpec2; + + std::map> lambdaSpec; + std::map> photonSpec; + std::map> sigma0HistSpec; + std::map> tripletHistSpec; + std::map> ctrHistSpec = closepairrejection::makeCprHistSpecMap(confCtr); + std::map> cprHistSpec = closepairrejection::makeCprHistSpecMap(confCpr); + std::map> tripletCleanerHistSpec = paircleaner::makePairCleanerHistSpecMap(confTripletCleanerBinning); + + if (processData) { + colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); + trackHistSpec1 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning1); + trackHistSpec2 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning2); + sigma0HistSpec = sigma0histmanager::makeSigma0HistSpecMap(confSigma0Binning); + lambdaSpec = v0histmanager::makeV0HistSpecMap(confLambdaBinning); + photonSpec = photonhistmanager::makePhotonHistSpecMap(confPhotonBinning); + tripletHistSpec = triplethistmanager::makeTripletHistSpecMap(confTripletBinning, confMixing); + tripletTrackTrackSigma0Builder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confSigma0Selection, confTrackCleaner1, confTrackCleaner2, confSigma0Cleaner, confCtr, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, sigma0HistSpec, tripletHistSpec, ctrHistSpec, tripletCleanerHistSpec); + } else { + } + hRegistry.print(); + }; + + void processSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoSigma0s const& /*sigmas*/) + { + tripletTrackTrackSigma0Builder.processSameEvent(col, tracks, trackPartition1, trackPartition2, sigma0Partition, cache); + } + PROCESS_SWITCH(FemtoTripletTrackTrackSigma0, processSameEvent, "Enable processing same event processing", true); + + void processSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigma0sWithLabel const& /*sigmas*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + { + tripletTrackTrackSigma0Builder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, sigma0WithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); + } + PROCESS_SWITCH(FemtoTripletTrackTrackSigma0, processSameEventMc, "Enable processing same event processing", false); + + void processMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks, FemtoSigma0s const& /*sigmas*/) + { + tripletTrackTrackSigma0Builder.processMixedEvent(cols, tracks, trackPartition1, trackPartition2, sigma0Partition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + } + PROCESS_SWITCH(FemtoTripletTrackTrackSigma0, processMixedEvent, "Enable processing mixed event processing", true); + + void processMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigma0sWithLabel const& /*sigmas*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + { + tripletTrackTrackSigma0Builder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, sigma0WithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + } + PROCESS_SWITCH(FemtoTripletTrackTrackSigma0, processMixedEventMc, "Enable processing mixed event processing", false); +}; + +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) +{ + o2::framework::WorkflowSpec workflow{ + adaptAnalysisTask(context), + }; + return workflow; +} From 88cef53f10010657b0b144d333f7b0f3410a8bcd Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Tue, 10 Nov 2026 07:09:09 +0000 Subject: [PATCH 2/4] Please consider the following formatting changes --- PWGCF/Femto/Core/closeTripletRejection.h | 2 +- PWGCF/Femto/Core/sigma0HistManager.h | 54 +++++++++---------- PWGCF/Femto/Core/tripletBuilder.h | 3 +- PWGCF/Femto/DataModel/FemtoTables.h | 28 +++++----- .../TableProducer/femtoSigma0Producer.cxx | 1 - .../Tasks/femtoTripletTrackTrackSigma0.cxx | 16 +++--- 6 files changed, 51 insertions(+), 53 deletions(-) diff --git a/PWGCF/Femto/Core/closeTripletRejection.h b/PWGCF/Femto/Core/closeTripletRejection.h index 2b6025c4db5..ece3024343b 100644 --- a/PWGCF/Femto/Core/closeTripletRejection.h +++ b/PWGCF/Femto/Core/closeTripletRejection.h @@ -258,7 +258,7 @@ class CloseTripletRejectionTrackTrackSigma0 bool isClose12 = mCtrTrack12.isClosePair(track1, track2, trackTable, tripletHistManager); bool isClose1Sigma0 = mCtrTrack1Sigma0.isClosePair(track1, sigma0, trackTable, tripletHistManager); bool isClose2Sigma0 = mCtrTrack2Sigma0.isClosePair(track2, sigma0, trackTable, tripletHistManager); - return isClose12 || isClose1Sigma0|| isClose2Sigma0; + return isClose12 || isClose1Sigma0 || isClose2Sigma0; } private: diff --git a/PWGCF/Femto/Core/sigma0HistManager.h b/PWGCF/Femto/Core/sigma0HistManager.h index 46eff0f47ad..e89c342923d 100644 --- a/PWGCF/Femto/Core/sigma0HistManager.h +++ b/PWGCF/Femto/Core/sigma0HistManager.h @@ -18,9 +18,9 @@ #include "PWGCF/Femto/Core/histManager.h" #include "PWGCF/Femto/Core/modes.h" +#include "PWGCF/Femto/Core/photonHistManager.h" #include "PWGCF/Femto/Core/trackHistManager.h" #include "PWGCF/Femto/Core/v0HistManager.h" -#include "PWGCF/Femto/Core/photonHistManager.h" #include #include @@ -158,29 +158,29 @@ constexpr std::array, kSigma0HistLast> HistTab {kTruePtVsPt, {(conf).pt, (conf).pt}}, \ {kTrueEtaVsEta, {(conf).eta, (conf).eta}}, \ {kTruePhiVsPhi, {(conf).phi, (conf).phi}}, \ - {kPdg, {(conf).pdgCodes}}, + {kPdg, {(conf).pdgCodes}}, // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define SIGMA0_HIST_QA_MAP(confAnalysis, confQa) \ - {kCosPa, {(confQa).cosPa}}, \ - {kDecayVtxX, {(confQa).decayVertex}}, \ - {kDecayVtxY, {(confQa).decayVertex}}, \ - {kDecayVtxZ, {(confQa).decayVertex}}, \ - {kDecayVtx, {(confQa).decayVertex}}, \ - {kPtVsEta, {(confAnalysis).pt, (confAnalysis).eta}}, \ - {kPtVsPhi, {(confAnalysis).pt, (confAnalysis).phi}}, \ - {kPhiVsEta, {(confAnalysis).phi, (confAnalysis).eta}}, \ - {kPtVsCosPa, {(confAnalysis).pt, (confQa).cosPa}}, \ - {kMassSigma0, {(confQa).massSigma0}}, \ - {kMassAntiSigma0, {(confQa).massAntiSigma0}}, \ - {kPtVsSigma0Mass, {(confAnalysis).pt, (confQa).massSigma0}}, \ - {kPtVsAntiSigma0Mass, {(confAnalysis).pt, (confQa).massAntiSigma0}}, \ +#define SIGMA0_HIST_QA_MAP(confAnalysis, confQa) \ + {kCosPa, {(confQa).cosPa}}, \ + {kDecayVtxX, {(confQa).decayVertex}}, \ + {kDecayVtxY, {(confQa).decayVertex}}, \ + {kDecayVtxZ, {(confQa).decayVertex}}, \ + {kDecayVtx, {(confQa).decayVertex}}, \ + {kPtVsEta, {(confAnalysis).pt, (confAnalysis).eta}}, \ + {kPtVsPhi, {(confAnalysis).pt, (confAnalysis).phi}}, \ + {kPhiVsEta, {(confAnalysis).phi, (confAnalysis).eta}}, \ + {kPtVsCosPa, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kMassSigma0, {(confQa).massSigma0}}, \ + {kMassAntiSigma0, {(confQa).massAntiSigma0}}, \ + {kPtVsSigma0Mass, {(confAnalysis).pt, (confQa).massSigma0}}, \ + {kPtVsAntiSigma0Mass, {(confAnalysis).pt, (confQa).massAntiSigma0}}, \ {kSigma0MassVsAntiSigma0Mass, {(confQa).massSigma0, (confQa).massAntiSigma0}}, // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define SIGMA0_HIST_MC_QA_MAP(confAnalysis, confQa) \ - {kNoMcParticle, {(confAnalysis).pt, (confQa).cosPa}}, \ - {kPrimary, {(confAnalysis).pt, (confQa).cosPa}}, +#define SIGMA0_HIST_MC_QA_MAP(confAnalysis, confQa) \ + {kNoMcParticle, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kPrimary, {(confAnalysis).pt, (confQa).cosPa}}, template auto makeSigma0HistSpecMap(const T& confBinningAnalysis) @@ -237,7 +237,7 @@ class Sigma0HistManager Sigma0HistManager() = default; ~Sigma0HistManager() = default; - // minimal init + // minimal init template void init(o2::framework::HistogramRegistry* registry, std::map> const& Sigma0Specs, @@ -273,7 +273,7 @@ class Sigma0HistManager this->initQa(Sigma0Specs); } } - + // init with qa + lambda and photon managers template void init(o2::framework::HistogramRegistry* registry, @@ -296,18 +296,18 @@ class Sigma0HistManager void fill(T1 const& sigma0candidate) { if constexpr (modes::isFlagSet(mode, modes::Mode::kReco)) { - this->fillAnalysis(sigma0candidate); - } + this->fillAnalysis(sigma0candidate); + } if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { - this->fillQa(sigma0candidate); + this->fillQa(sigma0candidate); } } - // wrapper for tripletProcessHelpers + // wrapper for tripletProcessHelpers template void fill(T1 const& sigma0candidate, T2 const& tracks) { - this->fillAnalysis(sigma0candidate); + this->fillAnalysis(sigma0candidate); } // fill sigma0 + lambda + photon @@ -333,7 +333,7 @@ class Sigma0HistManager template void fill(T1 const& sigma0candidate, T2 const& trackTable, T3 const& col, T4 const& mcParticles, T5 const& mcMothers, T6 const& mcPartonicMothers) { - this->template fillMc(sigma0candidate, col, mcParticles, mcMothers, mcPartonicMothers); + this->template fillMc(sigma0candidate, col, mcParticles, mcMothers, mcPartonicMothers); } // fill mc + lambda + photon template diff --git a/PWGCF/Femto/Core/tripletBuilder.h b/PWGCF/Femto/Core/tripletBuilder.h index 4912b58827c..fc516d59942 100644 --- a/PWGCF/Femto/Core/tripletBuilder.h +++ b/PWGCF/Femto/Core/tripletBuilder.h @@ -23,12 +23,12 @@ #include "PWGCF/Femto/Core/modes.h" #include "PWGCF/Femto/Core/pairHistManager.h" #include "PWGCF/Femto/Core/particleCleaner.h" +#include "PWGCF/Femto/Core/sigma0HistManager.h" #include "PWGCF/Femto/Core/trackHistManager.h" #include "PWGCF/Femto/Core/tripletCleaner.h" #include "PWGCF/Femto/Core/tripletHistManager.h" #include "PWGCF/Femto/Core/tripletProcessHelpers.h" #include "PWGCF/Femto/Core/v0HistManager.h" -#include "PWGCF/Femto/Core/sigma0HistManager.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" #include @@ -1284,7 +1284,6 @@ class TripletTrackTrackSigma0Builder std::uniform_int_distribution<> mDist; }; - // builder for triplets of generated particles (mc truth only, kMc without kReco) // covers all triplet types, since e.g. a lambda is just another mc particle template , - femtobase::stored::FColId, - femtobase::stored::SignedPt, - femtobase::stored::Eta, - femtobase::stored::Phi, - femtobase::stored::Mass, - femtosigma0s::LambdaId, - femtosigma0s::PosDauId, - femtosigma0s::NegDauId, - femtosigma0s::PhotonId, - femtobase::dynamic::Pt, - femtobase::dynamic::Sign); + o2::soa::Index<>, + femtobase::stored::FColId, + femtobase::stored::SignedPt, + femtobase::stored::Eta, + femtobase::stored::Phi, + femtobase::stored::Mass, + femtosigma0s::LambdaId, + femtosigma0s::PosDauId, + femtosigma0s::NegDauId, + femtosigma0s::PhotonId, + femtobase::dynamic::Pt, + femtobase::dynamic::Sign); using FSigma0s = FSigma0s_001; DECLARE_SOA_TABLE_STAGED_VERSIONED(FSigma0Masks_001, "FSIGMA0MASK", 1, //! sigma0 masks diff --git a/PWGCF/Femto/TableProducer/femtoSigma0Producer.cxx b/PWGCF/Femto/TableProducer/femtoSigma0Producer.cxx index f0f557a37ad..3945612dc39 100644 --- a/PWGCF/Femto/TableProducer/femtoSigma0Producer.cxx +++ b/PWGCF/Femto/TableProducer/femtoSigma0Producer.cxx @@ -57,4 +57,3 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc)}; } - diff --git a/PWGCF/Femto/Tasks/femtoTripletTrackTrackSigma0.cxx b/PWGCF/Femto/Tasks/femtoTripletTrackTrackSigma0.cxx index 23a8a66f275..a7340854fbe 100644 --- a/PWGCF/Femto/Tasks/femtoTripletTrackTrackSigma0.cxx +++ b/PWGCF/Femto/Tasks/femtoTripletTrackTrackSigma0.cxx @@ -21,14 +21,14 @@ #include "PWGCF/Femto/Core/pairCleaner.h" #include "PWGCF/Femto/Core/particleCleaner.h" #include "PWGCF/Femto/Core/partitions.h" +#include "PWGCF/Femto/Core/photonHistManager.h" +#include "PWGCF/Femto/Core/sigma0Builder.h" +#include "PWGCF/Femto/Core/sigma0HistManager.h" #include "PWGCF/Femto/Core/trackBuilder.h" #include "PWGCF/Femto/Core/trackHistManager.h" #include "PWGCF/Femto/Core/tripletBuilder.h" #include "PWGCF/Femto/Core/tripletHistManager.h" -#include "PWGCF/Femto/Core/sigma0Builder.h" -#include "PWGCF/Femto/Core/sigma0HistManager.h" #include "PWGCF/Femto/Core/v0HistManager.h" -#include "PWGCF/Femto/Core/photonHistManager.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" #include @@ -44,8 +44,8 @@ #include #include -#include #include +#include using namespace o2::analysis::femto; @@ -80,8 +80,8 @@ struct FemtoTripletTrackTrackSigma0 { trackhistmanager::ConfTrackBinning1 confTrackBinning1; trackbuilder::ConfTrackSelection2 confTrackSelections2; trackhistmanager::ConfTrackBinning2 confTrackBinning2; - inline static constexpr std::string_view PrefixTrack1 = "Track1/"; - inline static constexpr std::string_view PrefixTrack2 = "Track2/"; + inline static constexpr std::string_view PrefixTrack1 = "Track1/"; + inline static constexpr std::string_view PrefixTrack2 = "Track2/"; // particle cleaners (mc only) particlecleaner::ConfTrackCleaner1 confTrackCleaner1; @@ -98,9 +98,9 @@ struct FemtoTripletTrackTrackSigma0 { // setup for photon and lambda v0histmanager::ConfLambdaBinning1 confLambdaBinning; - inline static constexpr std::string_view PrefixPhoton = "Sigma0/DauPhoton/"; + inline static constexpr std::string_view PrefixPhoton = "Sigma0/DauPhoton/"; photonhistmanager::ConfPhotonBinning confPhotonBinning; - inline static constexpr std::string_view PrefixLambda = "Sigma0/DauLambda/"; + inline static constexpr std::string_view PrefixLambda = "Sigma0/DauLambda/"; // setup sigma0s sigma0builder::ConfSigma0SelectionDefault confSigma0Selection; From 94cd0612742e2faec515c47c989abeaa7edc4b5c Mon Sep 17 00:00:00 2001 From: yakparo Date: Fri, 13 Nov 2026 07:12:29 +0100 Subject: [PATCH 3/4] Adjusted for lastest Femto update --- PWGCF/Femto/Core/sigma0Builder.h | 8 +- PWGCF/Femto/Core/sigma0HistManager.h | 39 +++++++- PWGCF/Femto/Core/tripletBuilder.h | 91 +++++++++---------- PWGCF/Femto/Core/tripletHistManager.h | 24 +++++ .../TableProducer/femtoSigma0Producer.cxx | 6 +- .../Tasks/femtoTripletTrackTrackSigma0.cxx | 53 ++++------- 6 files changed, 131 insertions(+), 90 deletions(-) diff --git a/PWGCF/Femto/Core/sigma0Builder.h b/PWGCF/Femto/Core/sigma0Builder.h index ac6817539a5..f5922ed9074 100644 --- a/PWGCF/Femto/Core/sigma0Builder.h +++ b/PWGCF/Femto/Core/sigma0Builder.h @@ -279,7 +279,7 @@ class Sigma0Builder /// Build Sigma0 candidates from Lambda and photon tables belonging to the same collision. template - void fillSigma0s(TProducts& products, TLambdas const& lambdas, TPhotons const& photons, TTracks const& tracks) + void fillSigma0s(TProducts& products, TLambdas const& lambdas, TPhotons const& photons, TTracks const& /*tracks*/) { if (!mFillAnyTable) { return; @@ -300,8 +300,10 @@ class Sigma0Builder if (!selectLambda(lambda)) { continue; } - const auto posDau = lambda.posDau(); - const auto negDau = lambda.negDau(); + // const auto posDau = lambda.posDau(); + // const auto negDau = lambda.negDau(); + const auto& posDau = lambda.template posDau_as(); + const auto& negDau = lambda.template negDau_as(); const auto photonRows = photonRowsPerCollision.find(lambda.fColId()); if (photonRows == photonRowsPerCollision.end()) { diff --git a/PWGCF/Femto/Core/sigma0HistManager.h b/PWGCF/Femto/Core/sigma0HistManager.h index e89c342923d..a46e5009547 100644 --- a/PWGCF/Femto/Core/sigma0HistManager.h +++ b/PWGCF/Femto/Core/sigma0HistManager.h @@ -57,6 +57,8 @@ enum Sigma0Hist { kDecayVtxY, kDecayVtxZ, kDecayVtx, + kPosDauEta, + kNegDauEta, // 2d qa kPtVsEta, kPtVsPhi, @@ -110,6 +112,8 @@ struct ConfSigma0QaBinning : o2::framework::ConfigurableGroup { o2::framework::ConfigurableAxis massAntiSigma0{"massAntiSigma0", {{100, 1, 1.2}}, "mass for antiparticle hypothesis"}; }; +constexpr char PrefixSigma0Se[] = "Sigma0/SE/"; +constexpr char PrefixSigma0Me[] = "Sigma0/ME/"; constexpr const char PrefixSigma0QaBinning[] = "Sigma0QaBinning"; using ConfSigma0QaBinningDefault = ConfSigma0QaBinning; @@ -128,6 +132,8 @@ constexpr std::array, kSigma0HistLast> HistTab {kDecayVtxY, o2::framework::HistType::kTH1F, "hDecayVtxY", "Y coordinate of decay vertex ; DV_{Y} (cm); Entries"}, {kDecayVtxZ, o2::framework::HistType::kTH1F, "hDecayVtxZ", "Z coordinate of decay vertex ; DV_{Z} (cm); Entries"}, {kDecayVtx, o2::framework::HistType::kTH1F, "hDecayVtx", "Distance of decay vertex from primary vertex ; DV (cm); Entries"}, + {kPosDauEta, o2::framework::HistType::kTH1F, "hPosDAuEta", "#eta of positive v0 track ; #eta; Entries"}, + {kNegDauEta, o2::framework::HistType::kTH1F, "hNegDAuEta", "#eta of negative v0 track ; #eta; Entries"}, {kPtVsEta, o2::framework::HistType::kTH2F, "hPtVsEta", "p_{T} vs #eta; p_{T} (GeV/#it{c}) ; #eta"}, {kPtVsPhi, o2::framework::HistType::kTH2F, "hPtVsPhi", "p_{T} vs #varphi; p_{T} (GeV/#it{c}) ; #varphi"}, {kPhiVsEta, o2::framework::HistType::kTH2F, "hPhiVsEta", "#varphi vs #eta; #varphi ; #eta"}, @@ -167,6 +173,8 @@ constexpr std::array, kSigma0HistLast> HistTab {kDecayVtxY, {(confQa).decayVertex}}, \ {kDecayVtxZ, {(confQa).decayVertex}}, \ {kDecayVtx, {(confQa).decayVertex}}, \ + {kPosDauEta, {(confAnalysis).eta}}, \ + {kNegDauEta, {(confAnalysis).eta}}, \ {kPtVsEta, {(confAnalysis).pt, (confAnalysis).eta}}, \ {kPtVsPhi, {(confAnalysis).pt, (confAnalysis).phi}}, \ {kPhiVsEta, {(confAnalysis).phi, (confAnalysis).eta}}, \ @@ -177,6 +185,7 @@ constexpr std::array, kSigma0HistLast> HistTab {kPtVsAntiSigma0Mass, {(confAnalysis).pt, (confQa).massAntiSigma0}}, \ {kSigma0MassVsAntiSigma0Mass, {(confQa).massSigma0, (confQa).massAntiSigma0}}, + // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define SIGMA0_HIST_MC_QA_MAP(confAnalysis, confQa) \ {kNoMcParticle, {(confAnalysis).pt, (confQa).cosPa}}, \ @@ -303,11 +312,16 @@ class Sigma0HistManager } } - // wrapper for tripletProcessHelpers + //FIXME: dummy wrapper to satisfy triplet process helpers; rehaul Sigma0 QA and find a better solution for process helpers table consumption template - void fill(T1 const& sigma0candidate, T2 const& tracks) + void fill(T1 const& sigma0candidate, T2 const& trackTable) { this->fillAnalysis(sigma0candidate); + auto posDau = trackTable.rawIteratorAt(sigma0candidate.posDauId() - trackTable.offset()); + auto negDau = trackTable.rawIteratorAt(sigma0candidate.negDauId() - trackTable.offset()); + if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { + this->fillQaLite(sigma0candidate, posDau, negDau); + } } // fill sigma0 + lambda + photon @@ -329,11 +343,16 @@ class Sigma0HistManager this->template fillMc(sigma0candidate, col, mcParticles, mcMothers, mcPartonicMothers); } } - // wrapper for tripletProcessHelpers + //FIXME: dummy wrapper to satisfy triplet process helpers; rehaul Sigma0 QA and find a better solution for process helpers table consumption template void fill(T1 const& sigma0candidate, T2 const& trackTable, T3 const& col, T4 const& mcParticles, T5 const& mcMothers, T6 const& mcPartonicMothers) { this->template fillMc(sigma0candidate, col, mcParticles, mcMothers, mcPartonicMothers); + auto posDau = trackTable.rawIteratorAt(sigma0candidate.posDauId() - trackTable.offset()); + auto negDau = trackTable.rawIteratorAt(sigma0candidate.negDauId() - trackTable.offset()); + if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { + this->fillQaLite(sigma0candidate, posDau, negDau); + } } // fill mc + lambda + photon template @@ -383,6 +402,9 @@ class Sigma0HistManager mHistogramRegistry->add(qaDir + getHistNameV2(kDecayVtxY, HistTable), getHistDesc(kDecayVtxY, HistTable), getHistType(kDecayVtxY, HistTable), {Sigma0Specs.at(kDecayVtxY)}); mHistogramRegistry->add(qaDir + getHistNameV2(kDecayVtxZ, HistTable), getHistDesc(kDecayVtxZ, HistTable), getHistType(kDecayVtxZ, HistTable), {Sigma0Specs.at(kDecayVtxZ)}); mHistogramRegistry->add(qaDir + getHistNameV2(kDecayVtx, HistTable), getHistDesc(kDecayVtx, HistTable), getHistType(kDecayVtx, HistTable), {Sigma0Specs.at(kDecayVtx)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kDecayVtx, HistTable), getHistDesc(kDecayVtx, HistTable), getHistType(kDecayVtx, HistTable), {Sigma0Specs.at(kDecayVtx)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kPosDauEta, HistTable), getHistDesc(kPosDauEta, HistTable), getHistType(kPosDauEta, HistTable), {Sigma0Specs.at(kPosDauEta)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kNegDauEta, HistTable), getHistDesc(kNegDauEta, HistTable), getHistType(kNegDauEta, HistTable), {Sigma0Specs.at(kNegDauEta)}); if (mPlot2d) { mHistogramRegistry->add(qaDir + getHistNameV2(kPtVsEta, HistTable), getHistDesc(kPtVsEta, HistTable), getHistType(kPtVsEta, HistTable), {Sigma0Specs.at(kPtVsEta)}); @@ -458,6 +480,15 @@ class Sigma0HistManager } } + //TODO: currently wrapper for triplet process helpers, eventually a wrapper for Tracks-only dependent QA filling + template + void fillQaLite(T1 const& sigma0candidate, T2 const& posDau, T2 const& negDau) + { + this->template fillQa(sigma0candidate); + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(QaDir) + HIST(getHistName(kPosDauEta, HistTable)), posDau.eta()); + mHistogramRegistry->fill(HIST(sigma0Prefix) + HIST(QaDir) + HIST(getHistName(kNegDauEta, HistTable)), negDau.eta()); + } + template void fillMc(T1 const& sigma0Candidate, T2 const& col, T3 const& /*mcParticles*/, T4 const& /*mcMothers*/, T5 const& /*mcPartonicMothers*/) { @@ -520,4 +551,4 @@ class Sigma0HistManager photonhistmanager::PhotonHistManager mPhotonManager; }; }; // namespace o2::analysis::femto::sigma0histmanager -#endif // PWGCF_FEMTO_CORE_Sigma0HISTMANAGER_H_ +#endif // PWGCF_FEMTO_CORE_SIGMA0HISTMANAGER_H_ diff --git a/PWGCF/Femto/Core/tripletBuilder.h b/PWGCF/Femto/Core/tripletBuilder.h index d1af29e1046..7bc14f656d7 100644 --- a/PWGCF/Femto/Core/tripletBuilder.h +++ b/PWGCF/Femto/Core/tripletBuilder.h @@ -1009,19 +1009,6 @@ class TripletTrackTrackCascadeBuilder std::uniform_int_distribution<> mDist; }; -template class TripletTrackTrackSigma0Builder { public: @@ -1071,8 +1058,9 @@ class TripletTrackTrackSigma0Builder // check if correlating the same track species/selections or not mTrack1Track2AreSameSpecies = confMixing.particle12AreSameSpecies.value; - mColHistManager.template init(registry, colHistSpec, confCollisionBinning); + mColHistManagerSe.template init(registry, colHistSpec, confCollisionBinning); mTripletHistManagerSe.template init(registry, tripletHistSpec, confTripletBinning, confTripletCuts, confMixing); + mColHistManagerMe.template init(registry, colHistSpec, confCollisionBinning); mTripletHistManagerMe.template init(registry, tripletHistSpec, confTripletBinning, confTripletCuts, confMixing); mTcSe.template init(registry, tripletCleanerHistSpec, confTripletCuts); @@ -1083,13 +1071,16 @@ class TripletTrackTrackSigma0Builder if (mTrack1Track2AreSameSpecies) { // Track1 & Track2 are the same species and track 3 is Sigma0 mCleaner1.init(confCleaner1); - mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); - mSigma0HistManager.template init(registry, sigma0histSpec, confSigma0Selection); + mTrackHistManager1Se.template init(registry, trackHistSpec1, confTrackSelection1); + mSigma0HistManagerSe.template init(registry, sigma0histSpec, confSigma0Selection); mTripletHistManagerSe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection1.pdgCodeAbs.value, confSigma0Selection.pdgCodeAbs.value); mTripletHistManagerSe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value, 1); mCtrSe.init(registry, ctrHistSpec, confCtr, confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value); + mTrackHistManager1Me.template init(registry, trackHistSpec1, confTrackSelection1); + mSigma0HistManagerMe.template init(registry, sigma0histSpec, confSigma0Selection); + mTripletHistManagerMe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection1.pdgCodeAbs.value, confSigma0Selection.pdgCodeAbs.value); mTripletHistManagerMe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value, 1); mCtrMe.init(registry, ctrHistSpec, confCtr, confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value); @@ -1097,14 +1088,18 @@ class TripletTrackTrackSigma0Builder // all three tracks are different mCleaner1.init(confCleaner1); mCleaner2.init(confCleaner2); - mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); - mTrackHistManager2.template init(registry, trackHistSpec2, confTrackSelection2); - mSigma0HistManager.template init(registry, sigma0histSpec, confSigma0Selection); + mTrackHistManager1Se.template init(registry, trackHistSpec1, confTrackSelection1); + mTrackHistManager2Se.template init(registry, trackHistSpec2, confTrackSelection2); + mSigma0HistManagerSe.template init(registry, sigma0histSpec, confSigma0Selection); mTripletHistManagerSe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection2.pdgCodeAbs.value, confSigma0Selection.pdgCodeAbs.value); mTripletHistManagerSe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection2.chargeAbs.value, 1); mCtrSe.init(registry, ctrHistSpec, confCtr, confTrackSelection1.chargeAbs.value, confTrackSelection2.chargeAbs.value); + mTrackHistManager1Me.template init(registry, trackHistSpec1, confTrackSelection1); + mSigma0HistManagerMe.template init(registry, sigma0histSpec, confSigma0Selection); + mTrackHistManager2Me.template init(registry, trackHistSpec2, confTrackSelection2); + mTripletHistManagerMe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection2.pdgCodeAbs.value, confSigma0Selection.pdgCodeAbs.value); mTripletHistManagerMe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection2.chargeAbs.value, 1); mCtrMe.init(registry, ctrHistSpec, confCtr, confTrackSelection1.chargeAbs.value, confTrackSelection2.chargeAbs.value); @@ -1140,12 +1135,11 @@ class TripletTrackTrackSigma0Builder if (trackSlice1.size() < nLimitPartitionIdenticalParticles12 || sigma0Slice.size() < nLimitPartitionParticles) { return false; } - mColHistManager.template fill(col); mCtrSe.setMagField(col.magField()); if (mMixIdenticalParticles) { tripletOrder = static_cast(mDist(mRng)); } - return tripletprocesshelpers::processSameEvent(trackSlice1, sigma0Slice, trackTable, col, mTrackHistManager1, mSigma0HistManager, mTripletHistManagerSe, mCtrSe, mTcSe, tripletOrder); + return tripletprocesshelpers::processSameEvent(trackSlice1, sigma0Slice, trackTable, col, mTrackHistManager1Se, mSigma0HistManagerSe, mTripletHistManagerSe, mCtrSe, mTcSe, tripletOrder, mColHistManagerSe); } auto trackSlice1 = partition1->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); @@ -1154,9 +1148,8 @@ class TripletTrackTrackSigma0Builder if (trackSlice1.size() < nLimitPartitionParticles || trackSlice2.size() < nLimitPartitionParticles || sigma0Slice.size() < nLimitPartitionParticles) { return false; } - mColHistManager.template fill(col); mCtrSe.setMagField(col.magField()); - return tripletprocesshelpers::processSameEvent(trackSlice1, trackSlice2, sigma0Slice, trackTable, col, mTrackHistManager1, mTrackHistManager2, mSigma0HistManager, mTripletHistManagerSe, mCtrSe, mTcSe); + return tripletprocesshelpers::processSameEvent(trackSlice1, trackSlice2, sigma0Slice, trackTable, col, mTrackHistManager1Se, mTrackHistManager2Se, mSigma0HistManagerSe, mTripletHistManagerSe, mCtrSe, mTcSe, mColHistManagerSe); } // mc @@ -1171,12 +1164,11 @@ class TripletTrackTrackSigma0Builder if (trackSlice1.size() < nLimitPartitionIdenticalParticles12 || sigma0Slice.size() < nLimitPartitionParticles) { return false; } - mColHistManager.template fill(col, mcCols); mCtrSe.setMagField(col.magField()); if (mMixIdenticalParticles) { tripletOrder = static_cast(mDist(mRng)); } - return tripletprocesshelpers::processSameEvent(trackSlice1, sigma0Slice, trackTable, mcParticles, mcMothers, mcPartonicMothers, col, mcCols, mTrackHistManager1, mSigma0HistManager, mTripletHistManagerSe, mCleaner1, mSigma0Cleaner, mCtrSe, mTcSe, tripletOrder); + return tripletprocesshelpers::processSameEvent(trackSlice1, sigma0Slice, trackTable, mcParticles, mcMothers, mcPartonicMothers, col, mcCols, mTrackHistManager1Se, mSigma0HistManagerSe, mTripletHistManagerSe, mCleaner1, mSigma0Cleaner, mCtrSe, mTcSe, tripletOrder, mColHistManagerSe); } auto trackSlice1 = partition1->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); @@ -1185,9 +1177,8 @@ class TripletTrackTrackSigma0Builder if (trackSlice1.size() < nLimitPartitionParticles || trackSlice2.size() < nLimitPartitionParticles || sigma0Slice.size() < nLimitPartitionParticles) { return false; } - mColHistManager.template fill(col, mcCols); mCtrSe.setMagField(col.magField()); - return tripletprocesshelpers::processSameEvent(trackSlice1, trackSlice2, sigma0Slice, trackTable, mcParticles, mcMothers, mcPartonicMothers, col, mcCols, mTrackHistManager1, mTrackHistManager2, mSigma0HistManager, mTripletHistManagerSe, mCleaner1, mCleaner2, mSigma0Cleaner, mCtrSe, mTcSe); + return tripletprocesshelpers::processSameEvent(trackSlice1, trackSlice2, sigma0Slice, trackTable, mcParticles, mcMothers, mcPartonicMothers, col, mcCols, mTrackHistManager1Se, mTrackHistManager2Se, mSigma0HistManagerSe, mTripletHistManagerSe, mCleaner1, mCleaner2, mSigma0Cleaner, mCtrSe, mTcSe, mColHistManagerSe); } // data @@ -1197,13 +1188,13 @@ class TripletTrackTrackSigma0Builder if (mTrack1Track2AreSameSpecies) { switch (mMixingPolicy) { case static_cast(pairhistmanager::kVtxMult): - tripletprocesshelpers::processMixedEvent(cols, partition1, partition1, partition3, trackTable, cache, binsVtxMult, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager1, mSigma0HistManager); + tripletprocesshelpers::processMixedEvent(cols, partition1, partition1, partition3, trackTable, cache, binsVtxMult, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTcMe, mEventStride, mTrackHistManager1Me, mTrackHistManager1Me, mSigma0HistManagerMe, mColHistManagerMe); break; case static_cast(pairhistmanager::kVtxCent): - tripletprocesshelpers::processMixedEvent(cols, partition1, partition1, partition3, trackTable, cache, binsVtxCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager1, mSigma0HistManager); + tripletprocesshelpers::processMixedEvent(cols, partition1, partition1, partition3, trackTable, cache, binsVtxCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTcMe, mEventStride, mTrackHistManager1Me, mTrackHistManager1Me, mSigma0HistManagerMe, mColHistManagerMe); break; case static_cast(pairhistmanager::kVtxMultCent): - tripletprocesshelpers::processMixedEvent(cols, partition1, partition1, partition3, trackTable, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager1, mSigma0HistManager); + tripletprocesshelpers::processMixedEvent(cols, partition1, partition1, partition3, trackTable, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTcMe, mEventStride, mTrackHistManager1Me, mTrackHistManager1Me, mSigma0HistManagerMe, mColHistManagerMe); break; default: LOG(fatal) << "Invalid binning policy specifed. Breaking..."; @@ -1211,13 +1202,13 @@ class TripletTrackTrackSigma0Builder } else { switch (mMixingPolicy) { case static_cast(pairhistmanager::kVtxMult): - tripletprocesshelpers::processMixedEvent(cols, partition1, partition2, partition3, trackTable, cache, binsVtxMult, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager2, mSigma0HistManager); + tripletprocesshelpers::processMixedEvent(cols, partition1, partition2, partition3, trackTable, cache, binsVtxMult, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTcMe, mEventStride, mTrackHistManager1Me, mTrackHistManager2Me, mSigma0HistManagerMe, mColHistManagerMe); break; case static_cast(pairhistmanager::kVtxCent): - tripletprocesshelpers::processMixedEvent(cols, partition1, partition2, partition3, trackTable, cache, binsVtxCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager2, mSigma0HistManager); + tripletprocesshelpers::processMixedEvent(cols, partition1, partition2, partition3, trackTable, cache, binsVtxCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTcMe, mEventStride, mTrackHistManager1Me, mTrackHistManager2Me, mSigma0HistManagerMe, mColHistManagerMe); break; case static_cast(pairhistmanager::kVtxMultCent): - tripletprocesshelpers::processMixedEvent(cols, partition1, partition2, partition3, trackTable, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager2, mSigma0HistManager); + tripletprocesshelpers::processMixedEvent(cols, partition1, partition2, partition3, trackTable, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTcMe, mEventStride, mTrackHistManager1Me, mTrackHistManager2Me, mSigma0HistManagerMe, mColHistManagerMe); break; default: LOG(fatal) << "Invalid binning policy specifed. Breaking..."; @@ -1232,13 +1223,13 @@ class TripletTrackTrackSigma0Builder if (mTrack1Track2AreSameSpecies) { switch (mMixingPolicy) { case static_cast(pairhistmanager::kVtxMult): - tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition1, partition3, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxMult, mMixingDepth, mTripletHistManagerMe, mCleaner1, mCleaner1, mSigma0Cleaner, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager1, mSigma0HistManager); + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition1, partition3, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxMult, mMixingDepth, mTripletHistManagerMe, mCleaner1, mCleaner1, mSigma0Cleaner, mCtrMe, mTcMe, mEventStride, mTrackHistManager1Me, mTrackHistManager1Me, mSigma0HistManagerMe, mColHistManagerMe); break; case static_cast(pairhistmanager::kVtxCent): - tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition1, partition3, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxCent, mMixingDepth, mTripletHistManagerMe, mCleaner1, mCleaner1, mSigma0Cleaner, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager1, mSigma0HistManager); + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition1, partition3, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxCent, mMixingDepth, mTripletHistManagerMe, mCleaner1, mCleaner1, mSigma0Cleaner, mCtrMe, mTcMe, mEventStride, mTrackHistManager1Me, mTrackHistManager1Me, mSigma0HistManagerMe, mColHistManagerMe); break; case static_cast(pairhistmanager::kVtxMultCent): - tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition1, partition3, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCleaner1, mCleaner1, mSigma0Cleaner, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager1, mSigma0HistManager); + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition1, partition3, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCleaner1, mCleaner1, mSigma0Cleaner, mCtrMe, mTcMe, mEventStride, mTrackHistManager1Me, mTrackHistManager1Me, mSigma0HistManagerMe, mColHistManagerMe); break; default: LOG(fatal) << "Invalid binning policy specifed. Breaking..."; @@ -1246,13 +1237,13 @@ class TripletTrackTrackSigma0Builder } else { switch (mMixingPolicy) { case static_cast(pairhistmanager::kVtxMult): - tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition2, partition3, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxMult, mMixingDepth, mTripletHistManagerMe, mCleaner1, mCleaner2, mSigma0Cleaner, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager2, mSigma0HistManager); + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition2, partition3, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxMult, mMixingDepth, mTripletHistManagerMe, mCleaner1, mCleaner2, mSigma0Cleaner, mCtrMe, mTcMe, mEventStride, mTrackHistManager1Me, mTrackHistManager2Me, mSigma0HistManagerMe, mColHistManagerMe); break; case static_cast(pairhistmanager::kVtxCent): - tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition2, partition3, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxCent, mMixingDepth, mTripletHistManagerMe, mCleaner1, mCleaner2, mSigma0Cleaner, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager2, mSigma0HistManager); + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition2, partition3, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxCent, mMixingDepth, mTripletHistManagerMe, mCleaner1, mCleaner2, mSigma0Cleaner, mCtrMe, mTcMe, mEventStride, mTrackHistManager2Me, mTrackHistManager1Me, mSigma0HistManagerMe, mColHistManagerMe); break; case static_cast(pairhistmanager::kVtxMultCent): - tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition2, partition3, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCleaner1, mCleaner2, mSigma0Cleaner, mCtrMe, mTcMe, mEventStride, mTrackHistManager1, mTrackHistManager2, mSigma0HistManager); + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition2, partition3, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCleaner1, mCleaner2, mSigma0Cleaner, mCtrMe, mTcMe, mEventStride, mTrackHistManager1Me, mTrackHistManager2Me, mSigma0HistManagerMe, mColHistManagerMe); break; default: LOG(fatal) << "Invalid binning policy specifed. Breaking..."; @@ -1261,18 +1252,24 @@ class TripletTrackTrackSigma0Builder } private: - colhistmanager::CollisionHistManager mColHistManager; - trackhistmanager::TrackHistManager mTrackHistManager1; - trackhistmanager::TrackHistManager mTrackHistManager2; - sigma0histmanager::Sigma0HistManager mSigma0HistManager; + // SE triplets + colhistmanager::CollisionHistManager mColHistManagerSe; + trackhistmanager::TrackHistManager mTrackHistManager1Se; + trackhistmanager::TrackHistManager mTrackHistManager2Se; + sigma0histmanager::Sigma0HistManager mSigma0HistManagerSe; + // ME triplets + colhistmanager::CollisionHistManager mColHistManagerMe; + trackhistmanager::TrackHistManager mTrackHistManager1Me; + trackhistmanager::TrackHistManager mTrackHistManager2Me; + sigma0histmanager::Sigma0HistManager mSigma0HistManagerMe; particlecleaner::ParticleCleaner mCleaner1; particlecleaner::ParticleCleaner mCleaner2; particlecleaner::ParticleCleaner mSigma0Cleaner; - triplethistmanager::TripletHistManager mTripletHistManagerSe; - triplethistmanager::TripletHistManager mTripletHistManagerMe; + triplethistmanager::TripletHistManager mTripletHistManagerSe; + triplethistmanager::TripletHistManager mTripletHistManagerMe; - closetripletrejection::CloseTripletRejectionTrackTrackSigma0 mCtrSe; - closetripletrejection::CloseTripletRejectionTrackTrackSigma0 mCtrMe; + closetripletrejection::CloseTripletRejectionTrackTrackSigma0 mCtrSe; + closetripletrejection::CloseTripletRejectionTrackTrackSigma0 mCtrMe; tripletcleaner::TrackTrackSigma0TripletCleaner mTcSe; tripletcleaner::TrackTrackSigma0TripletCleaner mTcMe; triplethistmanager::MixingPolicy mMixingPolicy = triplethistmanager::MixingPolicy::kVtxMult; diff --git a/PWGCF/Femto/Core/tripletHistManager.h b/PWGCF/Femto/Core/tripletHistManager.h index 592e37b3786..a4643fb275f 100644 --- a/PWGCF/Femto/Core/tripletHistManager.h +++ b/PWGCF/Femto/Core/tripletHistManager.h @@ -52,6 +52,9 @@ enum TripletHist { kPt1VsQ3, kPt2VsQ3, kPt3VsQ3, + kM1VsQ3, + kM2VsQ3, + kM3VsQ3, kQ3VsMt, kQ3VsMult, kQ3VsCent, @@ -177,6 +180,9 @@ constexpr std::array, kTripletHistogramLast> {kPt1VsQ3, o2::framework::HistType::kTH2F, "hPt1VsQ3", "p_{T,1} vs Q_{3}; p_{T,1} (GeV/#it{c}); Q_{3} (GeV/#it{c})"}, {kPt2VsQ3, o2::framework::HistType::kTH2F, "hPt2VsQ3", "p_{T,2} vs Q_{3}; p_{T,2} (GeV/#it{c}); Q_{3} (GeV/#it{c})"}, {kPt3VsQ3, o2::framework::HistType::kTH2F, "hPt3VsQ3", "p_{T,3} vs Q_{3}; p_{T,3} (GeV/#it{c}); Q_{3} (GeV/#it{c})"}, + {kM1VsQ3, o2::framework::HistType::kTH2F, "hM1VsQ3", "mass_{1} vs Q_{3}; m_{1} (GeV/#it{c}^{2}); Q_{3} (GeV/#it{c})"}, + {kM2VsQ3, o2::framework::HistType::kTH2F, "hM2VsQ3", "mass_{2} vs Q_{3}; m_{2} (GeV/#it{c}^{2}); Q_{3} (GeV/#it{c})"}, + {kM3VsQ3, o2::framework::HistType::kTH2F, "hM3VsQ3", "mass_{3} vs Q_{3}; m_{3} (GeV/#it{c}^{2}); Q_{3} (GeV/#it{c})"}, {kQ3VsMt, o2::framework::HistType::kTH2F, "hQ3VsMt", "Q_{3} vs m_{T}; Q_{3} (GeV/#it{c}); m_{T} (GeV/#it{c}^{2})"}, {kQ3VsMult, o2::framework::HistType::kTH2F, "hQ3VsMult", "Q_{3} vs Multiplicity; Q_{3} (GeV/#it{c}); Multiplicity"}, {kQ3VsCent, o2::framework::HistType::kTH2F, "hQ3VsCent", "Q_{3} vs Centrality; Q_{3} (GeV/#it{c}); Centrality"}, @@ -223,6 +229,9 @@ constexpr std::array, kTripletHistogramLast> {kPt1VsQ3, {(conf).pt1, (conf).q3}}, \ {kPt2VsQ3, {(conf).pt2, (conf).q3}}, \ {kPt3VsQ3, {(conf).pt3, (conf).q3}}, \ + {kM1VsQ3, {(conf).mass1, (conf).q3}}, \ + {kM2VsQ3, {(conf).mass2, (conf).q3}}, \ + {kM3VsQ3, {(conf).mass3, (conf).q3}}, \ {kQ3VsMt, {(conf).q3, (conf).mt}}, \ {kQ3VsMult, {(conf).q3, (conf).multiplicity}}, \ {kQ3VsCent, {(conf).q3, (conf).centrality}}, \ @@ -685,6 +694,9 @@ class TripletHistManager mHistogramRegistry->add(analysisDir + getHistNameV2(kPt1VsQ3, HistTable), getHistDesc(kPt1VsQ3, HistTable), getHistType(kPt1VsQ3, HistTable), {Specs.at(kPt1VsQ3)}); mHistogramRegistry->add(analysisDir + getHistNameV2(kPt2VsQ3, HistTable), getHistDesc(kPt2VsQ3, HistTable), getHistType(kPt2VsQ3, HistTable), {Specs.at(kPt2VsQ3)}); mHistogramRegistry->add(analysisDir + getHistNameV2(kPt3VsQ3, HistTable), getHistDesc(kPt3VsQ3, HistTable), getHistType(kPt3VsQ3, HistTable), {Specs.at(kPt3VsQ3)}); + if (mPlotMass1VsQ3) mHistogramRegistry->add(analysisDir + getHistNameV2(kM1VsQ3, HistTable), getHistDesc(kM1VsQ3, HistTable), getHistType(kM1VsQ3, HistTable), {Specs.at(kM1VsQ3)}); + if (mPlotMass2VsQ3) mHistogramRegistry->add(analysisDir + getHistNameV2(kM2VsQ3, HistTable), getHistDesc(kM2VsQ3, HistTable), getHistType(kM2VsQ3, HistTable), {Specs.at(kM2VsQ3)}); + if (mPlotMass3VsQ3) mHistogramRegistry->add(analysisDir + getHistNameV2(kM3VsQ3, HistTable), getHistDesc(kM3VsQ3, HistTable), getHistType(kM3VsQ3, HistTable), {Specs.at(kM3VsQ3)}); mHistogramRegistry->add(analysisDir + getHistNameV2(kQ3VsMt, HistTable), getHistDesc(kQ3VsMt, HistTable), getHistType(kQ3VsMt, HistTable), {Specs.at(kQ3VsMt)}); mHistogramRegistry->add(analysisDir + getHistNameV2(kQ3VsMult, HistTable), getHistDesc(kQ3VsMult, HistTable), getHistType(kQ3VsMult, HistTable), {Specs.at(kQ3VsMult)}); mHistogramRegistry->add(analysisDir + getHistNameV2(kQ3VsCent, HistTable), getHistDesc(kQ3VsCent, HistTable), getHistType(kQ3VsCent, HistTable), {Specs.at(kQ3VsCent)}); @@ -798,6 +810,9 @@ class TripletHistManager mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(getHistName(kPt1VsQ3, HistTable)), mParticle1.Pt(), mQ3); mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(getHistName(kPt2VsQ3, HistTable)), mParticle2.Pt(), mQ3); mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(getHistName(kPt3VsQ3, HistTable)), mParticle3.Pt(), mQ3); + if (mPlotMass1VsQ3) mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(getHistName(kM1VsQ3, HistTable)), mMass1, mQ3); + if (mPlotMass2VsQ3) mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(getHistName(kM2VsQ3, HistTable)), mMass2, mQ3); + if (mPlotMass3VsQ3) mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(getHistName(kM3VsQ3, HistTable)), mMass3, mQ3); mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(getHistName(kQ3VsMt, HistTable)), mQ3, mMt); mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(getHistName(kQ3VsMult, HistTable)), mQ3, mMult); mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(getHistName(kQ3VsCent, HistTable)), mQ3, mCent); @@ -900,6 +915,15 @@ class TripletHistManager bool mPlot1d = true; bool mPlot2d = true; + // initialize mass vs Q3 histograms only if table has mass column + static constexpr bool hasMassColumn(modes::Particle p) + { + return p == modes::Particle::kSigma0 || p == modes::Particle::kCascade; + } + bool mPlotMass1VsQ3 = hasMassColumn(particleType1); + bool mPlotMass2VsQ3 = hasMassColumn(particleType2); + bool mPlotMass3VsQ3 = hasMassColumn(particleType3); + bool mPlotPt1VsPt2VsPt3 = false; bool mPlotQ3VsPt1VsPt2VsPt3 = false; bool mPlotQ3VsMtVsMult = false; diff --git a/PWGCF/Femto/TableProducer/femtoSigma0Producer.cxx b/PWGCF/Femto/TableProducer/femtoSigma0Producer.cxx index 3945612dc39..92151935fb4 100644 --- a/PWGCF/Femto/TableProducer/femtoSigma0Producer.cxx +++ b/PWGCF/Femto/TableProducer/femtoSigma0Producer.cxx @@ -47,7 +47,11 @@ struct FemtoSigma0Producer { sigma0Builder.init(®istry, filters, bits, tables, initContext); } - void process(Lambdas const& lambdas, Photons const& photons, o2::aod::FTracks const& tracks, o2::aod::FCols const& /**/, o2::aod::FColMasks const& /**/, o2::aod::FTrackMasks const& /**/) + // void process(Lambdas const& lambdas, Photons const& photons, o2::aod::FTracks const& tracks, o2::aod::FCols const& /**/, o2::aod::FColMasks const& /**/, o2::aod::FTrackMasks const& /**/) + // { + // sigma0Builder.fillSigma0s(products, lambdas, photons, tracks); + // } + void process(Lambdas const& lambdas, Photons const& photons, o2::aod::FTracks const& tracks, o2::aod::FCols const& /**/, o2::aod::FColMasks const& /**/, o2::aod::FTrackMasks const& /**/) { sigma0Builder.fillSigma0s(products, lambdas, photons, tracks); } diff --git a/PWGCF/Femto/Tasks/femtoTripletTrackTrackSigma0.cxx b/PWGCF/Femto/Tasks/femtoTripletTrackTrackSigma0.cxx index a7340854fbe..ffce1dd9af7 100644 --- a/PWGCF/Femto/Tasks/femtoTripletTrackTrackSigma0.cxx +++ b/PWGCF/Femto/Tasks/femtoTripletTrackTrackSigma0.cxx @@ -9,9 +9,9 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file femtoTripletTrackTrackV0.cxx -/// \brief Tasks that computes correlation between two tracks -/// \author Anton Riedel, TU München, anton.riedel@cern.ch +/// \file femtoTripletTrackTrackSigma0.cxx +/// \brief Tasks that computes correlation between two tracks and a sigma0 +/// \author Yakiv Paroviak, CTU Prague, yakiv.paroviak@cern.ch #include "PWGCF/Femto/Core/closePairRejection.h" #include "PWGCF/Femto/Core/closeTripletRejection.h" @@ -21,14 +21,14 @@ #include "PWGCF/Femto/Core/pairCleaner.h" #include "PWGCF/Femto/Core/particleCleaner.h" #include "PWGCF/Femto/Core/partitions.h" -#include "PWGCF/Femto/Core/photonHistManager.h" +// #include "PWGCF/Femto/Core/photonHistManager.h" #include "PWGCF/Femto/Core/sigma0Builder.h" #include "PWGCF/Femto/Core/sigma0HistManager.h" #include "PWGCF/Femto/Core/trackBuilder.h" #include "PWGCF/Femto/Core/trackHistManager.h" #include "PWGCF/Femto/Core/tripletBuilder.h" #include "PWGCF/Femto/Core/tripletHistManager.h" -#include "PWGCF/Femto/Core/v0HistManager.h" +// #include "PWGCF/Femto/Core/v0HistManager.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" #include @@ -80,8 +80,6 @@ struct FemtoTripletTrackTrackSigma0 { trackhistmanager::ConfTrackBinning1 confTrackBinning1; trackbuilder::ConfTrackSelection2 confTrackSelections2; trackhistmanager::ConfTrackBinning2 confTrackBinning2; - inline static constexpr std::string_view PrefixTrack1 = "Track1/"; - inline static constexpr std::string_view PrefixTrack2 = "Track2/"; // particle cleaners (mc only) particlecleaner::ConfTrackCleaner1 confTrackCleaner1; @@ -96,11 +94,9 @@ struct FemtoTripletTrackTrackSigma0 { o2::framework::Partition trackWithLabelPartition2 = MAKE_TRACK_PARTITION(confTrackSelections2); o2::framework::Preslice perColtracksWithLabel = o2::aod::femtobase::stored::fColId; - // setup for photon and lambda - v0histmanager::ConfLambdaBinning1 confLambdaBinning; - inline static constexpr std::string_view PrefixPhoton = "Sigma0/DauPhoton/"; - photonhistmanager::ConfPhotonBinning confPhotonBinning; - inline static constexpr std::string_view PrefixLambda = "Sigma0/DauLambda/"; + // // setup for photon and lambda + // v0histmanager::ConfLambdaBinning1 confLambdaBinning; + // photonhistmanager::ConfPhotonBinning confPhotonBinning; // setup sigma0s sigma0builder::ConfSigma0SelectionDefault confSigma0Selection; @@ -117,24 +113,11 @@ struct FemtoTripletTrackTrackSigma0 { triplethistmanager::ConfTripletCuts confTripletCuts; paircleaner::ConfPairCleanerBinning confTripletCleanerBinning; - closetripletrejection::ConfCtrTrackTrackV0 confCtr; - closepairrejection::ConfCprTrackV0Daughter confCpr; - - tripletbuilder::TripletTrackTrackSigma0Builder< - PrefixTrack1, - PrefixTrack2, - sigma0histmanager::PrefixSigma0, - PrefixLambda, - PrefixPhoton, - triplethistmanager::PrefixTrackTrackSigma0Se, - triplethistmanager::PrefixTrackTrackSigma0Me, - closetripletrejection::PrefixTrack1Track2Se, - closetripletrejection::PrefixTrack1Sigma0Se, - closetripletrejection::PrefixTrack2Sigma0Se, - closetripletrejection::PrefixTrack1Track2Me, - closetripletrejection::PrefixTrack1Sigma0Me, - closetripletrejection::PrefixTrack2Sigma0Me> - tripletTrackTrackSigma0Builder; + closetripletrejection::ConfCtrTrackTrackSigma0 confCtr; + // closepairrejection::ClosePairRejectionTrackTrack confCpr12; + // closepairrejection::ClosePairRejectionTrackSigma0 confCpr13; + + tripletbuilder::TripletTrackTrackSigma0Builder tripletTrackTrackSigma0Builder; // setup mixing std::vector defaultVtxBins{10, -10, 10}; @@ -169,12 +152,12 @@ struct FemtoTripletTrackTrackSigma0 { std::map> trackHistSpec1; std::map> trackHistSpec2; - std::map> lambdaSpec; - std::map> photonSpec; + // std::map> lambdaSpec; + // std::map> photonSpec; std::map> sigma0HistSpec; std::map> tripletHistSpec; std::map> ctrHistSpec = closepairrejection::makeCprHistSpecMap(confCtr); - std::map> cprHistSpec = closepairrejection::makeCprHistSpecMap(confCpr); + // std::map> cprHistSpec = closepairrejection::makeCprHistSpecMap(confCpr12); std::map> tripletCleanerHistSpec = paircleaner::makePairCleanerHistSpecMap(confTripletCleanerBinning); if (processData) { @@ -182,8 +165,8 @@ struct FemtoTripletTrackTrackSigma0 { trackHistSpec1 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning1); trackHistSpec2 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning2); sigma0HistSpec = sigma0histmanager::makeSigma0HistSpecMap(confSigma0Binning); - lambdaSpec = v0histmanager::makeV0HistSpecMap(confLambdaBinning); - photonSpec = photonhistmanager::makePhotonHistSpecMap(confPhotonBinning); + // lambdaSpec = v0histmanager::makeV0HistSpecMap(confLambdaBinning); + // photonSpec = photonhistmanager::makePhotonHistSpecMap(confPhotonBinning); tripletHistSpec = triplethistmanager::makeTripletHistSpecMap(confTripletBinning, confMixing); tripletTrackTrackSigma0Builder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confSigma0Selection, confTrackCleaner1, confTrackCleaner2, confSigma0Cleaner, confCtr, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, sigma0HistSpec, tripletHistSpec, ctrHistSpec, tripletCleanerHistSpec); } else { From be494282604d9601a66ecb1b5027e06708d2570a Mon Sep 17 00:00:00 2001 From: yakparo Date: Fri, 13 Nov 2026 07:14:55 +0100 Subject: [PATCH 4/4] Formatting --- PWGCF/Femto/Core/sigma0HistManager.h | 9 ++++---- PWGCF/Femto/Core/tripletHistManager.h | 22 ++++++++++++------- .../TableProducer/femtoSigma0Producer.cxx | 2 +- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/PWGCF/Femto/Core/sigma0HistManager.h b/PWGCF/Femto/Core/sigma0HistManager.h index a46e5009547..06ed5d5b5aa 100644 --- a/PWGCF/Femto/Core/sigma0HistManager.h +++ b/PWGCF/Femto/Core/sigma0HistManager.h @@ -185,7 +185,6 @@ constexpr std::array, kSigma0HistLast> HistTab {kPtVsAntiSigma0Mass, {(confAnalysis).pt, (confQa).massAntiSigma0}}, \ {kSigma0MassVsAntiSigma0Mass, {(confQa).massSigma0, (confQa).massAntiSigma0}}, - // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define SIGMA0_HIST_MC_QA_MAP(confAnalysis, confQa) \ {kNoMcParticle, {(confAnalysis).pt, (confQa).cosPa}}, \ @@ -312,7 +311,7 @@ class Sigma0HistManager } } - //FIXME: dummy wrapper to satisfy triplet process helpers; rehaul Sigma0 QA and find a better solution for process helpers table consumption + // FIXME: dummy wrapper to satisfy triplet process helpers; rehaul Sigma0 QA and find a better solution for process helpers table consumption template void fill(T1 const& sigma0candidate, T2 const& trackTable) { @@ -343,7 +342,7 @@ class Sigma0HistManager this->template fillMc(sigma0candidate, col, mcParticles, mcMothers, mcPartonicMothers); } } - //FIXME: dummy wrapper to satisfy triplet process helpers; rehaul Sigma0 QA and find a better solution for process helpers table consumption + // FIXME: dummy wrapper to satisfy triplet process helpers; rehaul Sigma0 QA and find a better solution for process helpers table consumption template void fill(T1 const& sigma0candidate, T2 const& trackTable, T3 const& col, T4 const& mcParticles, T5 const& mcMothers, T6 const& mcPartonicMothers) { @@ -480,7 +479,7 @@ class Sigma0HistManager } } - //TODO: currently wrapper for triplet process helpers, eventually a wrapper for Tracks-only dependent QA filling + // TODO: currently wrapper for triplet process helpers, eventually a wrapper for Tracks-only dependent QA filling template void fillQaLite(T1 const& sigma0candidate, T2 const& posDau, T2 const& negDau) { @@ -551,4 +550,4 @@ class Sigma0HistManager photonhistmanager::PhotonHistManager mPhotonManager; }; }; // namespace o2::analysis::femto::sigma0histmanager -#endif // PWGCF_FEMTO_CORE_SIGMA0HISTMANAGER_H_ +#endif // PWGCF_FEMTO_CORE_SIGMA0HISTMANAGER_H_ diff --git a/PWGCF/Femto/Core/tripletHistManager.h b/PWGCF/Femto/Core/tripletHistManager.h index a4643fb275f..7dfe8ee1520 100644 --- a/PWGCF/Femto/Core/tripletHistManager.h +++ b/PWGCF/Femto/Core/tripletHistManager.h @@ -694,9 +694,12 @@ class TripletHistManager mHistogramRegistry->add(analysisDir + getHistNameV2(kPt1VsQ3, HistTable), getHistDesc(kPt1VsQ3, HistTable), getHistType(kPt1VsQ3, HistTable), {Specs.at(kPt1VsQ3)}); mHistogramRegistry->add(analysisDir + getHistNameV2(kPt2VsQ3, HistTable), getHistDesc(kPt2VsQ3, HistTable), getHistType(kPt2VsQ3, HistTable), {Specs.at(kPt2VsQ3)}); mHistogramRegistry->add(analysisDir + getHistNameV2(kPt3VsQ3, HistTable), getHistDesc(kPt3VsQ3, HistTable), getHistType(kPt3VsQ3, HistTable), {Specs.at(kPt3VsQ3)}); - if (mPlotMass1VsQ3) mHistogramRegistry->add(analysisDir + getHistNameV2(kM1VsQ3, HistTable), getHistDesc(kM1VsQ3, HistTable), getHistType(kM1VsQ3, HistTable), {Specs.at(kM1VsQ3)}); - if (mPlotMass2VsQ3) mHistogramRegistry->add(analysisDir + getHistNameV2(kM2VsQ3, HistTable), getHistDesc(kM2VsQ3, HistTable), getHistType(kM2VsQ3, HistTable), {Specs.at(kM2VsQ3)}); - if (mPlotMass3VsQ3) mHistogramRegistry->add(analysisDir + getHistNameV2(kM3VsQ3, HistTable), getHistDesc(kM3VsQ3, HistTable), getHistType(kM3VsQ3, HistTable), {Specs.at(kM3VsQ3)}); + if (mPlotMass1VsQ3) + mHistogramRegistry->add(analysisDir + getHistNameV2(kM1VsQ3, HistTable), getHistDesc(kM1VsQ3, HistTable), getHistType(kM1VsQ3, HistTable), {Specs.at(kM1VsQ3)}); + if (mPlotMass2VsQ3) + mHistogramRegistry->add(analysisDir + getHistNameV2(kM2VsQ3, HistTable), getHistDesc(kM2VsQ3, HistTable), getHistType(kM2VsQ3, HistTable), {Specs.at(kM2VsQ3)}); + if (mPlotMass3VsQ3) + mHistogramRegistry->add(analysisDir + getHistNameV2(kM3VsQ3, HistTable), getHistDesc(kM3VsQ3, HistTable), getHistType(kM3VsQ3, HistTable), {Specs.at(kM3VsQ3)}); mHistogramRegistry->add(analysisDir + getHistNameV2(kQ3VsMt, HistTable), getHistDesc(kQ3VsMt, HistTable), getHistType(kQ3VsMt, HistTable), {Specs.at(kQ3VsMt)}); mHistogramRegistry->add(analysisDir + getHistNameV2(kQ3VsMult, HistTable), getHistDesc(kQ3VsMult, HistTable), getHistType(kQ3VsMult, HistTable), {Specs.at(kQ3VsMult)}); mHistogramRegistry->add(analysisDir + getHistNameV2(kQ3VsCent, HistTable), getHistDesc(kQ3VsCent, HistTable), getHistType(kQ3VsCent, HistTable), {Specs.at(kQ3VsCent)}); @@ -810,9 +813,12 @@ class TripletHistManager mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(getHistName(kPt1VsQ3, HistTable)), mParticle1.Pt(), mQ3); mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(getHistName(kPt2VsQ3, HistTable)), mParticle2.Pt(), mQ3); mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(getHistName(kPt3VsQ3, HistTable)), mParticle3.Pt(), mQ3); - if (mPlotMass1VsQ3) mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(getHistName(kM1VsQ3, HistTable)), mMass1, mQ3); - if (mPlotMass2VsQ3) mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(getHistName(kM2VsQ3, HistTable)), mMass2, mQ3); - if (mPlotMass3VsQ3) mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(getHistName(kM3VsQ3, HistTable)), mMass3, mQ3); + if (mPlotMass1VsQ3) + mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(getHistName(kM1VsQ3, HistTable)), mMass1, mQ3); + if (mPlotMass2VsQ3) + mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(getHistName(kM2VsQ3, HistTable)), mMass2, mQ3); + if (mPlotMass3VsQ3) + mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(getHistName(kM3VsQ3, HistTable)), mMass3, mQ3); mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(getHistName(kQ3VsMt, HistTable)), mQ3, mMt); mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(getHistName(kQ3VsMult, HistTable)), mQ3, mMult); mHistogramRegistry->fill(HIST(prefix) + HIST(AnalysisDir) + HIST(getHistName(kQ3VsCent, HistTable)), mQ3, mCent); @@ -915,14 +921,14 @@ class TripletHistManager bool mPlot1d = true; bool mPlot2d = true; - // initialize mass vs Q3 histograms only if table has mass column + // initialize mass vs Q3 histograms only if table has mass column static constexpr bool hasMassColumn(modes::Particle p) { return p == modes::Particle::kSigma0 || p == modes::Particle::kCascade; } bool mPlotMass1VsQ3 = hasMassColumn(particleType1); bool mPlotMass2VsQ3 = hasMassColumn(particleType2); - bool mPlotMass3VsQ3 = hasMassColumn(particleType3); + bool mPlotMass3VsQ3 = hasMassColumn(particleType3); bool mPlotPt1VsPt2VsPt3 = false; bool mPlotQ3VsPt1VsPt2VsPt3 = false; diff --git a/PWGCF/Femto/TableProducer/femtoSigma0Producer.cxx b/PWGCF/Femto/TableProducer/femtoSigma0Producer.cxx index 92151935fb4..af6ad9e9d8f 100644 --- a/PWGCF/Femto/TableProducer/femtoSigma0Producer.cxx +++ b/PWGCF/Femto/TableProducer/femtoSigma0Producer.cxx @@ -51,7 +51,7 @@ struct FemtoSigma0Producer { // { // sigma0Builder.fillSigma0s(products, lambdas, photons, tracks); // } - void process(Lambdas const& lambdas, Photons const& photons, o2::aod::FTracks const& tracks, o2::aod::FCols const& /**/, o2::aod::FColMasks const& /**/, o2::aod::FTrackMasks const& /**/) + void process(Lambdas const& lambdas, Photons const& photons, o2::aod::FTracks const& tracks, o2::aod::FCols const& /**/, o2::aod::FColMasks const& /**/, o2::aod::FTrackMasks const& /**/) { sigma0Builder.fillSigma0s(products, lambdas, photons, tracks); }