diff --git a/PWGCF/Femto/Core/cascadeBuilder.h b/PWGCF/Femto/Core/cascadeBuilder.h index 93c0ab29388..84fd8ddbd41 100644 --- a/PWGCF/Femto/Core/cascadeBuilder.h +++ b/PWGCF/Femto/Core/cascadeBuilder.h @@ -132,10 +132,10 @@ enum CascadeSels { kCascadeTransRadMin, ///< max. transverse radius // selection for lambda daughter - kLambdaCpaMin, ///< Min. DCA of the lambda daughers at primary vertex - kLambdaDcaDauMax, ///< TPC PID for daughters (Pion/Proton) - kLambdaTransRadMin, ///< Min. number of TPC clusters of daughter - kLambdaDcaToPvMin, ///< Min. DCA to primary vertex of daughter lambda + kLambdaCpaMin, ///< Min. CPA of the lambda + kLambdaDcaDauMax, ///< Max. DCA between the lambda daughters at lambda decay vertex + kLambdaTransRadMin, ///< Min. tranverse radius of the lambda + kLambdaDcaToPvMin, ///< Min. DCA of the lambda to the primary vertex // selection for bachelor/daugthers kDauAbsEtaMax, ///< Max. |eta| of daughter tracks @@ -181,9 +181,7 @@ const std::unordered_map cascadeSelectionNames = { {kPosDauTpc, "Positive Daughter TPC PID"}, {kNegDauTpc, "Negative Daughter TPC PID"}, {kPosDauTof, "Positive Daughter TOF PID"}, - {kNegDauTof, "Negative Daughter TOF PID"}, - - {kCascadeSelsMax, "Cascade Selections Max"}}; + {kNegDauTof, "Negative Daughter TOF PID"}}; /// enum for all cascade pre-filters (evaluated in checkFilters, before the selection bitmask) enum CascadeFilters { @@ -237,6 +235,17 @@ class CascadeSelection : public baseselection::BaseSelectioninit(config.passThrough.value); + mPtMin = filter.ptMin.value; + mPtMax = filter.ptMax.value; + mEtaMin = filter.etaMin.value; + mEtaMax = filter.etaMax.value; + mPhiMin = filter.phiMin.value; + mPhiMax = filter.phiMax.value; + mLambdaMassMin = filter.massLambdaMin.value; + mLambdaMassMax = filter.massLambdaMax.value; + mRequireTof = config.requireTof.value; + mKeepTracksWithoutTof = config.keepTracksWithoutTof.value; + if constexpr (modes::isEqual(cascadeType, modes::Cascade::kXi)) { mXiMassLowerLimit = filter.massXiMin.value; mXiMassUpperLimit = filter.massXiMax.value; @@ -256,17 +265,6 @@ class CascadeSelection : public baseselection::BaseSelectionaddSelection(kBachelorTofKaon, cascadeSelectionNames.at(kBachelorTofKaon), config.bachelorTofKaon.value, limits::kAbsUpperLimit, true, mRequireTof, false); } - mPtMin = filter.ptMin.value; - mPtMax = filter.ptMax.value; - mEtaMin = filter.etaMin.value; - mEtaMax = filter.etaMax.value; - mPhiMin = filter.phiMin.value; - mPhiMax = filter.phiMax.value; - mLambdaMassMin = filter.massLambdaMin.value; - mLambdaMassMax = filter.massLambdaMax.value; - mRequireTof = config.requireTof.value; - mKeepTracksWithoutTof = config.keepTracksWithoutTof.value; - this->addSelection(kPosDauTpc, cascadeSelectionNames.at(kPosDauTpc), config.posDauTpc.value, limits::kAbsUpperLimit, true, true, false); this->addSelection(kNegDauTpc, cascadeSelectionNames.at(kNegDauTpc), config.negDauTpc.value, limits::kAbsUpperLimit, true, true, false); this->addSelection(kPosDauTof, cascadeSelectionNames.at(kPosDauTof), config.posDauTof.value, limits::kAbsUpperLimit, true, mRequireTof, false); @@ -324,56 +322,64 @@ class CascadeSelection : public baseselection::BaseSelection(); // daughter selections - std::array etaDaughters = {std::fabs(bachelor.eta()), std::fabs(posDaughter.eta()), std::fabs(negDaughter.eta())}; + std::array etaDaughters = {std::fabs(cascade.bacheloreta()), std::fabs(cascade.positiveeta()), std::fabs(cascade.negativeeta())}; this->evaluateObservable(kDauAbsEtaMax, *std::max_element(etaDaughters.begin(), etaDaughters.end())); - std::array dcaDaughters = {std::fabs(bachelor.dcaXY()), std::fabs(posDaughter.dcaXY()), std::fabs(negDaughter.dcaXY())}; + std::array dcaDaughters = {std::fabs(cascade.dcabachtopv()), std::fabs(cascade.dcapostopv()), std::fabs(cascade.dcanegtopv())}; this->evaluateObservable(kDauAbsDcaxyMin, *std::min_element(dcaDaughters.begin(), dcaDaughters.end())); std::array clustersDaughters = {1.f * bachelor.tpcNClsFound(), 1.f * posDaughter.tpcNClsFound(), 1.f * negDaughter.tpcNClsFound()}; this->evaluateObservable(kDauTpcClsMin, *std::min_element(clustersDaughters.begin(), clustersDaughters.end())); - // bachelor pid selection - // check both pion and kaon PID for xi and omega - this->evaluateObservable(kBachelorTpcPion, bachelor.tpcNSigmaPi()); - this->evaluateObservable(kBachelorTpcKaon, bachelor.tpcNSigmaKa()); - if (bachelor.hasTOF()) { - this->evaluateObservable(kBachelorTofPion, bachelor.tofNSigmaPi()); - this->evaluateObservable(kBachelorTofKaon, bachelor.tofNSigmaKa()); - } else if (mKeepTracksWithoutTof) { - this->evaluateObservable(kBachelorTofPion, 0); - this->evaluateObservable(kBachelorTofKaon, 0); - } - - // depending on the charge, we check lambda or antilambda hypothesis - if (cascade.sign() < 0) { - this->evaluateObservable(kPosDauTpc, posDaughter.tpcNSigmaPr()); - this->evaluateObservable(kNegDauTpc, negDaughter.tpcNSigmaPi()); - if (posDaughter.hasTOF()) { - this->evaluateObservable(kPosDauTof, posDaughter.tofNSigmaPr()); + // pid selections + // TPC nSigma comes from the daughter track, TOF nSigma and the has-TOF flags from the cascade candidate + // if a daughter has no TOF signal, feed 0 so the bit passes any limit (opt-in via keepTracksWithoutTof) + auto evaluatePid = [this](CascadeSels tpcBit, float tpcNSigma, + CascadeSels tofBit, float tofNSigma, bool hasTof) { + this->evaluateObservable(tpcBit, tpcNSigma); + if (hasTof) { + this->evaluateObservable(tofBit, tofNSigma); } else if (mKeepTracksWithoutTof) { - this->evaluateObservable(kPosDauTof, 0); + this->evaluateObservable(tofBit, 0.f); } - if (negDaughter.hasTOF()) { - this->evaluateObservable(kNegDauTof, negDaughter.tofNSigmaPi()); - } else if (mKeepTracksWithoutTof) { - this->evaluateObservable(kNegDauTof, 0); - } - } else if (cascade.sign() > 0) { - this->evaluateObservable(kPosDauTpc, posDaughter.tpcNSigmaPi()); - this->evaluateObservable(kNegDauTpc, negDaughter.tpcNSigmaPr()); - if (posDaughter.hasTOF()) { - this->evaluateObservable(kPosDauTof, posDaughter.tofNSigmaPi()); - } else if (mKeepTracksWithoutTof) { - this->evaluateObservable(kPosDauTof, 0); - } - if (negDaughter.hasTOF()) { - this->evaluateObservable(kNegDauTof, negDaughter.tofNSigmaPr()); - } else if (mKeepTracksWithoutTof) { - this->evaluateObservable(kNegDauTof, 0); - } - } else { + }; + + const bool bachHasTof = cascade.bachelorHasTOF(); + const bool posHasTof = cascade.positiveHasTOF(); + const bool negHasTof = cascade.negativeHasTOF(); + + // bachelor: pion for Xi, kaon for Omega + if constexpr (modes::isEqual(cascadeType, modes::Cascade::kXi)) { + evaluatePid(kBachelorTpcPion, bachelor.tpcNSigmaPi(), + kBachelorTofPion, cascade.tofNSigmaXiPi(), bachHasTof); + } else if constexpr (modes::isEqual(cascadeType, modes::Cascade::kOmega)) { + evaluatePid(kBachelorTpcKaon, bachelor.tpcNSigmaKa(), + kBachelorTofKaon, cascade.tofNSigmaOmKa(), bachHasTof); + } + + // v0 daughters: charge of the cascade fixes the Lambda vs. AntiLambda hypothesis + if (cascade.sign() == 0) { LOG(warn) << "Encountered Cascade candidate with 0 charge"; + } else { + // sign < 0: Xi-/Omega- -> Lambda -> p pi- (pos = proton, neg = pion) + // sign > 0: Xi+/Omega+ -> AntiLambda (pos = pion, neg = antiproton) + const bool isMatter = cascade.sign() < 0; + + const float tpcPosDau = isMatter ? posDaughter.tpcNSigmaPr() : posDaughter.tpcNSigmaPi(); + const float tpcNegDau = isMatter ? negDaughter.tpcNSigmaPi() : negDaughter.tpcNSigmaPr(); + + float tofPosDau = 0.f; + float tofNegDau = 0.f; + if constexpr (modes::isEqual(cascadeType, modes::Cascade::kXi)) { + tofPosDau = isMatter ? cascade.tofNSigmaXiLaPr() : cascade.tofNSigmaXiLaPi(); + tofNegDau = isMatter ? cascade.tofNSigmaXiLaPi() : cascade.tofNSigmaXiLaPr(); + } else if constexpr (modes::isEqual(cascadeType, modes::Cascade::kOmega)) { + tofPosDau = isMatter ? cascade.tofNSigmaOmLaPr() : cascade.tofNSigmaOmLaPi(); + tofNegDau = isMatter ? cascade.tofNSigmaOmLaPi() : cascade.tofNSigmaOmLaPr(); + } + + evaluatePid(kPosDauTpc, tpcPosDau, kPosDauTof, tofPosDau, posHasTof); + evaluatePid(kNegDauTpc, tpcNegDau, kNegDauTof, tofNegDau, negHasTof); } this->assembleBitmask(); @@ -657,6 +663,22 @@ class CascadeBuilder template void fillCascade(T1& collisionBuilder, T2& cascadeProducts, T3 const& cascade, T4 const& col, int bachelorIndex, int posDaughterIndex, int negDaughterIndex) { + float strangeTofBachelor = 0.f; + float strangeTofPosDau = 0.f; + float strangeTofNegDau = 0.f; + const bool isMatter = cascade.sign() < 0; // Xi-/Omega- -> Lambda -> p pi- (pos=proton, neg=pion) + + if constexpr (modes::isEqual(cascadeType, modes::Cascade::kXi)) { + strangeTofBachelor = cascade.tofNSigmaXiPi(); + strangeTofPosDau = isMatter ? cascade.tofNSigmaXiLaPr() : cascade.tofNSigmaXiLaPi(); + strangeTofNegDau = isMatter ? cascade.tofNSigmaXiLaPi() : cascade.tofNSigmaXiLaPr(); + } + if constexpr (modes::isEqual(cascadeType, modes::Cascade::kOmega)) { + strangeTofBachelor = cascade.tofNSigmaOmKa(); + strangeTofPosDau = isMatter ? cascade.tofNSigmaOmLaPr() : cascade.tofNSigmaOmLaPi(); + strangeTofNegDau = isMatter ? cascade.tofNSigmaOmLaPi() : cascade.tofNSigmaOmLaPr(); + } + if constexpr (modes::isEqual(cascadeType, modes::Cascade::kXi)) { if (mProduceXis) { cascadeProducts.producedXis(collisionBuilder.collisionIndex(), @@ -691,7 +713,10 @@ class CascadeBuilder cascade.v0cosPA(col.posX(), col.posY(), col.posZ()), cascade.dcaV0daughters(), cascade.v0radius(), - cascade.dcav0topv(col.posX(), col.posY(), col.posZ())); + cascade.dcav0topv(col.posX(), col.posY(), col.posZ()), + strangeTofBachelor, + strangeTofPosDau, + strangeTofNegDau); } } if constexpr (modes::isEqual(cascadeType, modes::Cascade::kOmega)) { @@ -728,7 +753,10 @@ class CascadeBuilder cascade.v0cosPA(col.posX(), col.posY(), col.posZ()), cascade.dcaV0daughters(), cascade.v0radius(), - cascade.dcav0topv(col.posX(), col.posY(), col.posZ())); + cascade.dcav0topv(col.posX(), col.posY(), col.posZ()), + strangeTofBachelor, + strangeTofPosDau, + strangeTofNegDau); } } } diff --git a/PWGCF/Femto/Core/cascadeHistManager.h b/PWGCF/Femto/Core/cascadeHistManager.h index 346716f138e..2f0f88405ac 100644 --- a/PWGCF/Femto/Core/cascadeHistManager.h +++ b/PWGCF/Femto/Core/cascadeHistManager.h @@ -58,6 +58,9 @@ enum CascadeHist { kLambdaDauDca, kLambdaTransRadius, kLambdaDcaToPv, + kStrangeTofBachelor, + kStrangeTofPosDau, + kStrangeTofNegDau, // 2d qa kPtVsEta, kPtVsPhi, @@ -67,6 +70,9 @@ enum CascadeHist { kPtVsMassOmega, kPtVsMassLambda, kMassXiVsMassOmega, + kStrangeTofVsTofBachelor, + kStrangeTofVsTofPosDau, + kStrangeTofVsTofNegDau, // mc kOrigin, kPdg, @@ -122,6 +128,7 @@ struct ConfCascadeQaBinning : o2::framework::ConfigurableGroup { o2::framework::ConfigurableAxis lambdaDauDca{"lambdaDauDca", {{150, 0, 1.0}}, "DCA of lambda daughters at lambda decay vertex"}; o2::framework::ConfigurableAxis lambdaTransRadius{"lambdaTransRadius", {{100, 0, 100}}, "DCA of lambda daughters at lambda decay vertex"}; o2::framework::ConfigurableAxis lambdaDcaToPv{"lambdaDcaToPv", {{100, 0, 200}}, "DCA of lambda daughter from primary vertex"}; + o2::framework::ConfigurableAxis strangeTof{"strangeTof", {{500, -5, 5}}, "Strangeness TOF vs TOF Nsigma for bachelor/daughters"}; }; constexpr const char PrefixXiQaBinning[] = "XiQaBinning"; @@ -149,6 +156,9 @@ constexpr std::array, kCascadeHistLast> HistT {kLambdaDauDca, o2::framework::HistType::kTH1F, "hLambdaDauDca", "Daughter DCA at #Lambda decay vertex ; DCA_{#Lambda dau decay vertex} (cm); Entries"}, {kLambdaTransRadius, o2::framework::HistType::kTH1F, "hLambdaTransRadius", "Transverse radius of daughter #Lambda ; r_{xy,#Lambda dau} (cm); Entries"}, {kLambdaDcaToPv, o2::framework::HistType::kTH1F, "hLambdaDcaToPv", "DCA to primary vertex of daughter #Lambda ; DCA_{#Lambda} (cm); Entries"}, + {kStrangeTofBachelor, o2::framework::HistType::kTH1F, "hStrangeTofBachelor", "Strange TOF of bachelor ; n#sigma_{TOF, strange}; Entries"}, + {kStrangeTofPosDau, o2::framework::HistType::kTH1F, "hStrangeTofPosDau", "Strange TOF of positive Daughter ; n#sigma_{TOF, strange}; Entries"}, + {kStrangeTofNegDau, o2::framework::HistType::kTH1F, "hStrangeTofNegDau", "Strange TOF of negative Daughter ; n#sigma_{TOF, strange}; 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"}, @@ -157,6 +167,9 @@ constexpr std::array, kCascadeHistLast> HistT {kPtVsMassOmega, o2::framework::HistType::kTH2F, "hPtVsMassOmega", "p_{T} vs mass #Omega; p_{T} (GeV/#it{c}); m_{#LambdaK} (GeV/#it{c}^{2})"}, {kPtVsMassLambda, o2::framework::HistType::kTH2F, "hPtVsMassLambda", "p_{T} vs mass daughter #Lambda; p_{T} (GeV/#it{c}); m_{#Lambda dau} (GeV/#it{c}^{2})"}, {kMassXiVsMassOmega, o2::framework::HistType::kTH2F, "hMassXiVsMassOmega", "mass #Xi vs mass #Omega; m_{#Lambda#pi} (GeV/#it{c}^{2}); m_{#LambdaK} (GeV/#it{c}^{2})"}, + {kStrangeTofVsTofBachelor, o2::framework::HistType::kTH2F, "hStrangeTofVsTofBachelor", "TOF_{Strange} vs TOF_{Tracking} of bachelor; n#sigma_{TOF, strange}; n#sigma_{TOF, tracking}"}, + {kStrangeTofVsTofPosDau, o2::framework::HistType::kTH2F, "hStrangeTofVsTofPosDau", "TOF_{Strange} vs TOF_{Tracking} of positive Daughter; n#sigma_{TOF, strange}; n#sigma_{TOF, tracking}"}, + {kStrangeTofVsTofNegDau, o2::framework::HistType::kTH2F, "hStrangeTofVsTofNegDau", "TOF_{Strange} vs TOF_{Tracking} of negative Daughter; n#sigma_{TOF, strange}; n#sigma_{TOF, tracking}"}, {kOrigin, o2::framework::HistType::kTH1F, "hOrigin", "Status Codes (=Origin); Status Code; Entries"}, {kPdg, o2::framework::HistType::kTH1F, "hPdg", "PDG Codes of reconstructed v0; PDG Code; Entries"}, {kPdgMother, o2::framework::HistType::kTH1F, "hPdgMother", "PDG Codes of mother of reconstructed v0; PDG Code; Entries"}, @@ -194,25 +207,31 @@ constexpr std::array, kCascadeHistLast> HistT {kPdgPartonicMother, {(conf).pdgCodes}}, // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define CASCADE_HIST_QA_MAP(confAnalysis, confQa) \ - {kCosPa, {(confQa).cosPa}}, \ - {kDecayDauDca, {(confQa).dauDcaAtDecay}}, \ - {kTransRadius, {(confQa).transRadius}}, \ - {kLambdaMass, {(confQa).lambdaMass}}, \ - {kLambdaCosPa, {(confQa).lambdaCosPa}}, \ - {kLambdaDauDca, {(confQa).lambdaDauDca}}, \ - {kLambdaTransRadius, {(confQa).lambdaTransRadius}}, \ - {kLambdaDcaToPv, {(confQa).lambdaDcaToPv}}, \ - {kPtVsEta, {(confAnalysis).pt, (confAnalysis).eta}}, \ - {kPtVsPhi, {(confAnalysis).pt, (confAnalysis).phi}}, \ - {kPhiVsEta, {(confAnalysis).phi, (confAnalysis).eta}}, \ - {kPtVsCosPa, {(confAnalysis).pt, (confQa).cosPa}}, \ - {kMassXi, {(confQa).massXi}}, \ - {kMassOmega, {(confQa).massOmega}}, \ - {kPtVsMassXi, {(confAnalysis).pt, (confQa).massXi}}, \ - {kPtVsMassOmega, {(confAnalysis).pt, (confQa).massOmega}}, \ - {kPtVsMassLambda, {(confAnalysis).pt, (confQa).lambdaMass}}, \ - {kMassXiVsMassOmega, {(confQa).massXi, (confQa).massOmega}}, +#define CASCADE_HIST_QA_MAP(confAnalysis, confQa) \ + {kCosPa, {(confQa).cosPa}}, \ + {kDecayDauDca, {(confQa).dauDcaAtDecay}}, \ + {kTransRadius, {(confQa).transRadius}}, \ + {kLambdaMass, {(confQa).lambdaMass}}, \ + {kLambdaCosPa, {(confQa).lambdaCosPa}}, \ + {kLambdaDauDca, {(confQa).lambdaDauDca}}, \ + {kLambdaTransRadius, {(confQa).lambdaTransRadius}}, \ + {kLambdaDcaToPv, {(confQa).lambdaDcaToPv}}, \ + {kStrangeTofBachelor, {(confQa).strangeTof}}, \ + {kStrangeTofPosDau, {(confQa).strangeTof}}, \ + {kStrangeTofNegDau, {(confQa).strangeTof}}, \ + {kPtVsEta, {(confAnalysis).pt, (confAnalysis).eta}}, \ + {kPtVsPhi, {(confAnalysis).pt, (confAnalysis).phi}}, \ + {kPhiVsEta, {(confAnalysis).phi, (confAnalysis).eta}}, \ + {kPtVsCosPa, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kMassXi, {(confQa).massXi}}, \ + {kMassOmega, {(confQa).massOmega}}, \ + {kPtVsMassXi, {(confAnalysis).pt, (confQa).massXi}}, \ + {kPtVsMassOmega, {(confAnalysis).pt, (confQa).massOmega}}, \ + {kPtVsMassLambda, {(confAnalysis).pt, (confQa).lambdaMass}}, \ + {kMassXiVsMassOmega, {(confQa).massXi, (confQa).massOmega}}, \ + {kStrangeTofVsTofBachelor, {(confQa).strangeTof, (confQa).strangeTof}}, \ + {kStrangeTofVsTofPosDau, {(confQa).strangeTof, (confQa).strangeTof}}, \ + {kStrangeTofVsTofNegDau, {(confQa).strangeTof, (confQa).strangeTof}}, // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define CASCADE_HIST_MC_QA_MAP(confAnalysis, confQa) \ @@ -431,7 +450,7 @@ class CascadeHistManager fillAnalysis(cascadeCandidate); } if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { - fillQa(cascadeCandidate); + fillQa(cascadeCandidate, bachelor, posDaughter, negDaughter); } } @@ -449,7 +468,7 @@ class CascadeHistManager this->fillAnalysis(cascadeCandidate); } if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { - this->fillQa(cascadeCandidate); + this->fillQa(cascadeCandidate, bachelor, negDaughter, posDaughter); } if constexpr (modes::isFlagSet(mode, modes::Mode::kMc)) { this->template fillMc(cascadeCandidate, col, mcParticles, mcMothers, mcPartonicMothers); @@ -496,6 +515,9 @@ class CascadeHistManager mHistogramRegistry->add(qaDir + getHistNameV2(kLambdaDcaToPv, HistTable), getHistDesc(kLambdaDcaToPv, HistTable), getHistType(kLambdaDcaToPv, HistTable), {cascadeSpecs.at(kLambdaDcaToPv)}); mHistogramRegistry->add(qaDir + getHistNameV2(kMassXi, HistTable), getHistDesc(kMassXi, HistTable), getHistType(kMassXi, HistTable), {cascadeSpecs.at(kMassXi)}); mHistogramRegistry->add(qaDir + getHistNameV2(kMassOmega, HistTable), getHistDesc(kMassOmega, HistTable), getHistType(kMassOmega, HistTable), {cascadeSpecs.at(kMassOmega)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kStrangeTofBachelor, HistTable), getHistDesc(kStrangeTofBachelor, HistTable), getHistType(kStrangeTofBachelor, HistTable), {cascadeSpecs.at(kStrangeTofBachelor)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kStrangeTofPosDau, HistTable), getHistDesc(kStrangeTofPosDau, HistTable), getHistType(kStrangeTofPosDau, HistTable), {cascadeSpecs.at(kStrangeTofPosDau)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kStrangeTofNegDau, HistTable), getHistDesc(kStrangeTofNegDau, HistTable), getHistType(kStrangeTofNegDau, HistTable), {cascadeSpecs.at(kStrangeTofNegDau)}); if (mPlot2d) { mHistogramRegistry->add(qaDir + getHistNameV2(kPtVsEta, HistTable), getHistDesc(kPtVsEta, HistTable), getHistType(kPtVsEta, HistTable), {cascadeSpecs.at(kPtVsEta)}); @@ -507,6 +529,9 @@ class CascadeHistManager mHistogramRegistry->add(qaDir + getHistNameV2(kPtVsMassOmega, HistTable), getHistDesc(kPtVsMassOmega, HistTable), getHistType(kPtVsMassOmega, HistTable), {cascadeSpecs.at(kPtVsMassOmega)}); mHistogramRegistry->add(qaDir + getHistNameV2(kPtVsMassLambda, HistTable), getHistDesc(kPtVsMassLambda, HistTable), getHistType(kPtVsMassLambda, HistTable), {cascadeSpecs.at(kPtVsMassLambda)}); mHistogramRegistry->add(qaDir + getHistNameV2(kMassXiVsMassOmega, HistTable), getHistDesc(kMassXiVsMassOmega, HistTable), getHistType(kMassXiVsMassOmega, HistTable), {cascadeSpecs.at(kMassXiVsMassOmega)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kStrangeTofVsTofBachelor, HistTable), getHistDesc(kStrangeTofVsTofBachelor, HistTable), getHistType(kStrangeTofVsTofBachelor, HistTable), {cascadeSpecs.at(kStrangeTofVsTofBachelor)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kStrangeTofVsTofPosDau, HistTable), getHistDesc(kStrangeTofVsTofPosDau, HistTable), getHistType(kStrangeTofVsTofPosDau, HistTable), {cascadeSpecs.at(kStrangeTofVsTofPosDau)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kStrangeTofVsTofNegDau, HistTable), getHistDesc(kStrangeTofVsTofNegDau, HistTable), getHistType(kStrangeTofVsTofNegDau, HistTable), {cascadeSpecs.at(kStrangeTofVsTofNegDau)}); } } @@ -562,19 +587,33 @@ class CascadeHistManager mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(AnalysisDir) + HIST(getHistName(kPtVsMass, HistTable)), cascadeCandidate.pt(), cascadeCandidate.mass()); } - template - void fillQa(T const& cascadeCandidate) + template + void fillQa(T1 const& cascadeCandidate, T2 const& bachelor, T3 const& posDau, T4 const& negDau) { float massXi = 0.f; float massOmega = 0.f; + float tofBachelor = 0.f; + float tofPosDau = 0.f; + float tofNegDau = 0.f; if constexpr (modes::isEqual(cascade, modes::Cascade::kXi)) { massXi = cascadeCandidate.mass(); massOmega = cascadeCandidate.massOmega(); + tofBachelor = bachelor.tofNSigmaPi(); } if constexpr (modes::isEqual(cascade, modes::Cascade::kOmega)) { massXi = cascadeCandidate.massXi(); massOmega = cascadeCandidate.mass(); + tofBachelor = bachelor.tofNSigmaKa(); } + + if (cascadeCandidate.sign() > 0) { + tofPosDau = posDau.tofNSigmaPr(); + tofNegDau = negDau.tofNSigmaPi(); + } else { + tofPosDau = posDau.tofNSigmaPi(); + tofNegDau = negDau.tofNSigmaPr(); + } + mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(QaDir) + HIST(getHistName(kCosPa, HistTable)), cascadeCandidate.cascadeCosPa()); mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(QaDir) + HIST(getHistName(kDecayDauDca, HistTable)), cascadeCandidate.cascadeDauDca()); mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(QaDir) + HIST(getHistName(kTransRadius, HistTable)), cascadeCandidate.cascadeTransRadius()); @@ -585,6 +624,9 @@ class CascadeHistManager mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(QaDir) + HIST(getHistName(kLambdaDcaToPv, HistTable)), cascadeCandidate.lambdaDcaToPv()); mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(QaDir) + HIST(getHistName(kMassXi, HistTable)), massXi); mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(QaDir) + HIST(getHistName(kMassOmega, HistTable)), massOmega); + mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(QaDir) + HIST(getHistName(kStrangeTofBachelor, HistTable)), cascadeCandidate.strangeTofBachelor()); + mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(QaDir) + HIST(getHistName(kStrangeTofPosDau, HistTable)), cascadeCandidate.strangeTofPosDau()); + mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(QaDir) + HIST(getHistName(kStrangeTofNegDau, HistTable)), cascadeCandidate.strangeTofNegDau()); if (mPlot2d) { mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(QaDir) + HIST(getHistName(kPtVsEta, HistTable)), cascadeCandidate.pt(), cascadeCandidate.eta()); @@ -595,6 +637,9 @@ class CascadeHistManager mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(QaDir) + HIST(getHistName(kPtVsMassOmega, HistTable)), cascadeCandidate.pt(), massOmega); mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(QaDir) + HIST(getHistName(kPtVsMassLambda, HistTable)), cascadeCandidate.pt(), cascadeCandidate.lambdaMass()); mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(QaDir) + HIST(getHistName(kMassXiVsMassOmega, HistTable)), massXi, massOmega); + mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(QaDir) + HIST(getHistName(kStrangeTofVsTofBachelor, HistTable)), cascadeCandidate.strangeTofBachelor(), tofBachelor); + mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(QaDir) + HIST(getHistName(kStrangeTofVsTofPosDau, HistTable)), cascadeCandidate.strangeTofPosDau(), tofPosDau); + mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(QaDir) + HIST(getHistName(kStrangeTofVsTofNegDau, HistTable)), cascadeCandidate.strangeTofNegDau(), tofNegDau); } } diff --git a/PWGCF/Femto/Core/collisionBuilder.h b/PWGCF/Femto/Core/collisionBuilder.h index 3f6f94a1b32..e65714f754a 100644 --- a/PWGCF/Femto/Core/collisionBuilder.h +++ b/PWGCF/Femto/Core/collisionBuilder.h @@ -25,6 +25,7 @@ #include "Common/CCDB/EventSelectionParams.h" #include "Common/CCDB/RCTSelectionFlags.h" +#include "Common/Core/RecoDecay.h" #include "Common/Core/Zorro.h" #include @@ -33,6 +34,10 @@ #include #include +#include + +#include + #include #include #include @@ -80,6 +85,8 @@ struct ConfCollisionBits : o2::framework::ConfigurableGroup { o2::framework::Configurable> sphericityMin{"sphericityMin", {}, "Minimum sphericity"}; o2::framework::Configurable> sphericityMax{"sphericityMax", {}, "Maximum sphericity"}; o2::framework::Configurable> triggers{"triggers", {}, "List of all triggers to be used"}; + o2::framework::Configurable qvecDetector{"qvecDetector", 0, "Detector used to estimate the Q-vector: 0 -> FT0C, 1 -> FT0A"}; + o2::framework::Configurable qvecHarmonic{"qvecHarmonic", 2, "Harmonic n of the Q-vector and event plane angle Psi_n: 1 -> direct, 2 -> elliptic, 3 -> triangular"}; }; struct ConfCcdb : o2::framework::ConfigurableGroup { @@ -240,6 +247,10 @@ class CollisionSelection : public baseselection::BaseSelection(config.qvecDetector.value); + mQvecHarmonic = static_cast(config.qvecHarmonic.value); + this->addSelection(kSel8, collisionSelectionNames.at(kSel8), config.sel8.value); this->addSelection(kNoSameBunchPileUp, collisionSelectionNames.at(kNoSameBunchPileUp), config.noSameBunchPileup.value); this->addSelection(kIsVertexItsTpc, collisionSelectionNames.at(kIsVertexItsTpc), config.isVertexItsTpc.value); @@ -345,6 +356,35 @@ class CollisionSelection : public baseselection::BaseSelection + void setQvector(T const& col) + { + switch (mQvecDetector) { + case modes::QvecDetector::kFT0C: + mQvec = std::hypot(col.qvecFT0CReVec()[0], col.qvecFT0CImVec()[0]) * std::sqrt(col.sumAmplFT0C()); + break; + case modes::QvecDetector::kFT0A: + mQvec = std::hypot(col.qvecFT0AReVec()[0], col.qvecFT0AImVec()[0]) * std::sqrt(col.sumAmplFT0A()); + break; + } + } + [[nodiscard]] float getQvector() const { return mQvec; } + + template + void setEventPlane(T const& col) + { + float harmonic = static_cast(mQvecHarmonic); + switch (mQvecDetector) { + case modes::QvecDetector::kFT0C: + mEventPlane = RecoDecay::constrainAngle((std::atan2(col.qvecFT0CImVec()[0], col.qvecFT0CReVec()[0])) / harmonic, 0, harmonic); // constrain between 0 and 2pi/harmonic + break; + case modes::QvecDetector::kFT0A: + mEventPlane = RecoDecay::constrainAngle((std::atan2(col.qvecFT0AImVec()[0], col.qvecFT0AReVec()[0])) / harmonic, 0, harmonic); // constrain between 0 and 2pi/harmonic + break; + } + } + [[nodiscard]] float getEventPlane() const { return mEventPlane; } + /// \brief Evaluate all pre-filters (kinematics, quality, RCT flags) for a collision candidate, /// filling one filter-histogram bin per bound plus the "All analyzed"/"All passed" summary bins. template @@ -415,6 +455,7 @@ class CollisionSelection : public baseselection::BaseSelectionevaluateObservable(kIsGoodZvtxFt0VsPv, static_cast(col.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV))); this->evaluateObservable(kNoCollInTimeRangeNarrow, static_cast(col.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow))); this->evaluateObservable(kNoCollInTimeRangeStrict, static_cast(col.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStrict))); + this->evaluateObservable(kNoCollInTimeRangeStandard, static_cast(col.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard))); this->evaluateObservable(kNoCollInRofStrict, static_cast(col.selection_bit(o2::aod::evsel::kNoCollInRofStrict))); this->evaluateObservable(kNoCollInRofStandard, static_cast(col.selection_bit(o2::aod::evsel::kNoCollInRofStandard))); this->evaluateObservable(kNoHighMultCollInPrevRof, static_cast(col.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof))); @@ -487,6 +528,11 @@ class CollisionSelection : public baseselection::BaseSelection producedSphericities; o2::framework::Produces producedMultiplicityEstimators; o2::framework::Produces producedCentralityEstimators; - o2::framework::Produces producedQns; + o2::framework::Produces producedShapes; }; struct ConfCollisionTables : o2::framework::ConfigurableGroup { @@ -518,7 +564,7 @@ struct ConfCollisionTables : o2::framework::ConfigurableGroup { o2::framework::Configurable produceSphericities{"produceSphericities", -1, "Produce Sphericity (-1: auto; 0 off; 1 on)"}; o2::framework::Configurable produceMults{"produceMults", -1, "Produce Multiplicities (-1: auto; 0 off; 1 on)"}; o2::framework::Configurable produceCents{"produceCents", -1, "Produce Centralities (-1: auto; 0 off; 1 on)"}; - o2::framework::Configurable produceQns{"produceQns", -1, "Produce Qn (-1: auto; 0 off; 1 on)"}; + o2::framework::Configurable produceShapes{"produceShapes", -1, "Produce Event shape variables (-1: auto; 0 off; 1 on)"}; }; template @@ -544,7 +590,7 @@ class CollisionBuilder mProducedSphericities = utils::enableTable("FColSphericities_001", confTable.produceSphericities.value, initContext); mProducedMultiplicities = utils::enableTable("FColMults_001", confTable.produceMults.value, initContext); mProducedCentralities = utils::enableTable("FColCents_001", confTable.produceCents.value, initContext); - mProduceQns = utils::enableTable("FColQnBins_001", confTable.produceQns.value, initContext); + mProducedShapes = utils::enableTable("FColShapes_001", confTable.produceShapes.value, initContext); if (mProducedCollisions && mProducedLiteCollisions) { LOG(fatal) << "FCols and FLiteCols are mutually exclusive -- enable only one. " @@ -552,7 +598,9 @@ class CollisionBuilder << "use the dedicated converter task to reconstruct FCols from FLiteCols downstream."; } - if (mProducedCollisions || mProducedLiteCollisions || mProducedCollisionMasks || mProducedPositions || mProducedSphericities || mProducedMultiplicities || mProducedCentralities) { + if (mProducedCollisions || mProducedLiteCollisions || mProducedCollisionMasks || + mProducedPositions || mProducedSphericities || mProducedMultiplicities || + mProducedCentralities) { mFillAnyTable = true; } else { LOG(info) << "No tables configured, Selection object will not be configured..."; @@ -566,7 +614,7 @@ class CollisionBuilder } template - void initCollision(T1& bc, T2& col, T3& tracks, T4& ccdb, T5& histRegistry) + void initCollision(T1 const& bc, T2 const& col, T3 const& tracks, T4& ccdb, T5& histRegistry) { if (mRunNumber != bc.runNumber()) { mRunNumber = bc.runNumber(); @@ -591,6 +639,11 @@ class CollisionBuilder mCollisionSelection.template setMultiplicity(col); mCollisionSelection.template setCentrality(col); + if constexpr (utils::HasQvectors) { + mCollisionSelection.template setQvector(col); + mCollisionSelection.template setEventPlane(col); + } + std::vector triggerDecisions = mCollisionSelection.getTriggerDecisions(bc.globalBC()); mCollisionSelection.applySelections(col, triggerDecisions); @@ -671,18 +724,18 @@ class CollisionBuilder col.ft0cOccupancyInTimeRange()); } - // TODO: enable later for better QA - // if (mProducedCentralities) { - // collisionProducts.producedCentralityEstimators( - // col.centFT0A(), - // col.centFT0C()); - // } - // PbPb specific columns - // if constexpr (modes::isFlagSet(system, modes::System::kPbPb)) { - // if (mProduceQns) { - // collisionProducts.producedQns(utils::qn(col)); - // } - // } + if (mProducedCentralities) { + collisionProducts.producedCentralityEstimators( + col.centFT0A(), + col.centFT0C(), + col.centFT0M()); + } + + if (mProducedShapes) { + collisionProducts.producedShapes( + mCollisionSelection.getQvector(), + mCollisionSelection.getEventPlane()); + } mCollisionAlreadyFilled = true; } @@ -726,7 +779,7 @@ class CollisionBuilder bool mProducedSphericities = false; bool mProducedMultiplicities = false; bool mProducedCentralities = false; - bool mProduceQns = false; + bool mProducedShapes = false; }; struct CollisionBuilderDerivedToDerivedProducts : o2::framework::ProducesGroup { diff --git a/PWGCF/Femto/Core/collisionHistManager.h b/PWGCF/Femto/Core/collisionHistManager.h index 338da0ac63c..87d4507021d 100644 --- a/PWGCF/Femto/Core/collisionHistManager.h +++ b/PWGCF/Femto/Core/collisionHistManager.h @@ -16,14 +16,17 @@ #ifndef PWGCF_FEMTO_CORE_COLLISIONHISTMANAGER_H_ #define PWGCF_FEMTO_CORE_COLLISIONHISTMANAGER_H_ +#include "PWGCF/Femto/Core/femtoUtils.h" #include "PWGCF/Femto/Core/histManager.h" #include "PWGCF/Femto/Core/modes.h" +#include #include #include #include #include +#include #include #include #include @@ -48,6 +51,10 @@ enum ColHist { kCentVsMult, kCentVsSphericity, kMultVsSphericity, + kFT0AvsFT0C, + // event shape + kQvector, + kEventPlaneAngle, // mc kTruePosZ, // pure mc-truth, no reco collision (kMc without kReco) kTrueCent, // pure mc-truth, no reco collision (kMc without kReco) @@ -80,6 +87,10 @@ constexpr std::array, kColHistLast> HistTable = { {kCentVsMult, o2::framework::HistType::kTH2F, "hCentVsMult", "Centrality vs Multiplicity; Centrality (%); Multiplicity"}, {kMultVsSphericity, o2::framework::HistType::kTH2F, "hMultVsSphericity", "Multiplicity vs Sphericity; Multiplicity; Sphericity"}, {kCentVsSphericity, o2::framework::HistType::kTH2F, "hCentVsSphericity", "Centrality vs Sphericity; Centrality (%); Sphericity"}, + {kFT0AvsFT0C, o2::framework::HistType::kTH2F, "hFT0AvsFT0C", "FT0A centrality vs FT0C centrality; Centrality_{FT0A} (%); Centrality_{FT0C}"}, + // event shape + {kQvector, o2::framework::HistType::kTH1F, "hQvector", "Q-vector; Q-vector; Entries"}, + {kEventPlaneAngle, o2::framework::HistType::kTH1F, "hEventPlaneAngle", "Event Plane angle; #Psi_{n}; Entries"}, // mc {kTruePosZ, o2::framework::HistType::kTH1F, "hTruePosZ", "True vertex Z (mc-truth collision); V_{Z,True} (cm); Entries"}, {kTrueCent, o2::framework::HistType::kTH1F, "hTrueCent", "True centrality (mc-truth collision); Centrality_{True} (%); Entries"}, @@ -94,7 +105,9 @@ constexpr std::array, kColHistLast> HistTable = { {kPosZ, {(conf).vtxZ}}, \ {kMult, {(conf).mult}}, \ {kCent, {(conf).cent}}, \ - {kMagField, {(conf).magField}}, + {kMagField, {(conf).magField}}, \ + {kQvector, {(conf).qvector}}, \ + {kEventPlaneAngle, {(conf).eventPlaneAngle}}, // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define COL_HIST_QA_MAP(confAnalysis, confQa) \ @@ -107,7 +120,8 @@ constexpr std::array, kColHistLast> HistTable = { {kPoszVsCent, {(confAnalysis).vtxZ, (confAnalysis).cent}}, \ {kCentVsMult, {(confAnalysis).cent, (confAnalysis).mult}}, \ {kMultVsSphericity, {(confAnalysis).mult, (confQa).sphericity}}, \ - {kCentVsSphericity, {confBinningAnalysis.cent, (confQa).sphericity}}, + {kCentVsSphericity, {(confAnalysis).cent, (confQa).sphericity}}, \ + {kFT0AvsFT0C, {(confAnalysis).cent, (confAnalysis).cent}}, // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define COL_HIST_MC_MAP(conf) \ @@ -164,6 +178,9 @@ struct ConfCollisionBinning : o2::framework::ConfigurableGroup { o2::framework::ConfigurableAxis mult{"mult", {200, 0, 200}, "Multiplicity binning"}; o2::framework::ConfigurableAxis cent{"cent", {100, 0.0f, 100.0f}, "Centrality (multiplicity percentile) binning"}; o2::framework::ConfigurableAxis magField{"magField", {11, -5.5, 5.5}, "Magnetic field binning"}; + o2::framework::Configurable plotEventShape{"plotEventShape", false, "Activate histograms for event shape (qvector, event plane angle)"}; + o2::framework::ConfigurableAxis qvector{"qvector", {100, 0.0f, 100.0f}, "Q-vector binning"}; + o2::framework::ConfigurableAxis eventPlaneAngle{"eventPlaneAngle", {720, 0, 1.f * o2::constants::math::PI}, "Event plane angle binning"}; }; struct ConfCollisionQaBinning : o2::framework::ConfigurableGroup { @@ -184,9 +201,10 @@ class CollisionHistManager template void init(o2::framework::HistogramRegistry* registry, std::map> const& Specs, - T const& /*ConfCollisionBinning*/) + T const& ConfCollisionBinning) { mHistogramRegistry = registry; + mPlotEventShape = ConfCollisionBinning.plotEventShape.value; if constexpr (isFlagSet(mode, modes::Mode::kReco)) { initAnalysis(Specs); } @@ -257,6 +275,11 @@ class CollisionHistManager mHistogramRegistry->add(analysisDir + getHistNameV2(kMult, HistTable), getHistDesc(kMult, HistTable), getHistType(kMult, HistTable), {Specs.at(kMult)}); mHistogramRegistry->add(analysisDir + getHistNameV2(kCent, HistTable), getHistDesc(kCent, HistTable), getHistType(kCent, HistTable), {Specs.at(kCent)}); mHistogramRegistry->add(analysisDir + getHistNameV2(kMagField, HistTable), getHistDesc(kMagField, HistTable), getHistType(kMagField, HistTable), {Specs.at(kMagField)}); + + if (mPlotEventShape) { + mHistogramRegistry->add(analysisDir + getHistNameV2(kQvector, HistTable), getHistDesc(kQvector, HistTable), getHistType(kQvector, HistTable), {Specs.at(kQvector)}); + mHistogramRegistry->add(analysisDir + getHistNameV2(kEventPlaneAngle, HistTable), getHistDesc(kEventPlaneAngle, HistTable), getHistType(kEventPlaneAngle, HistTable), {Specs.at(kEventPlaneAngle)}); + } } void initQa(std::map> const& Specs) @@ -273,6 +296,7 @@ class CollisionHistManager mHistogramRegistry->add(qaDir + getHistNameV2(kCentVsMult, HistTable), getHistDesc(kCentVsMult, HistTable), getHistType(kCentVsMult, HistTable), {Specs.at(kCentVsMult)}); mHistogramRegistry->add(qaDir + getHistNameV2(kMultVsSphericity, HistTable), getHistDesc(kMultVsSphericity, HistTable), getHistType(kMultVsSphericity, HistTable), {Specs.at(kMultVsSphericity)}); mHistogramRegistry->add(qaDir + getHistNameV2(kCentVsSphericity, HistTable), getHistDesc(kCentVsSphericity, HistTable), getHistType(kCentVsSphericity, HistTable), {Specs.at(kCentVsSphericity)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kFT0AvsFT0C, HistTable), getHistDesc(kFT0AvsFT0C, HistTable), getHistType(kFT0AvsFT0C, HistTable), {Specs.at(kFT0AvsFT0C)}); } } @@ -301,6 +325,13 @@ class CollisionHistManager mHistogramRegistry->fill(HIST(AnalysisDir) + HIST(getHistName(kMult, HistTable)), col.mult()); mHistogramRegistry->fill(HIST(AnalysisDir) + HIST(getHistName(kCent, HistTable)), col.cent()); mHistogramRegistry->fill(HIST(AnalysisDir) + HIST(getHistName(kMagField, HistTable)), col.magField()); + + if (mPlotEventShape) { + if constexpr (utils::HasEventShape) { + mHistogramRegistry->fill(HIST(AnalysisDir) + HIST(getHistName(kQvector, HistTable)), col.qvec()); + mHistogramRegistry->fill(HIST(AnalysisDir) + HIST(getHistName(kEventPlaneAngle, HistTable)), col.eventPlaneAngle()); + } + } } template @@ -317,6 +348,7 @@ class CollisionHistManager mHistogramRegistry->fill(HIST(QaDir) + HIST(getHistName(kCentVsMult, HistTable)), col.cent(), col.mult()); mHistogramRegistry->fill(HIST(QaDir) + HIST(getHistName(kMultVsSphericity, HistTable)), col.mult(), col.sphericity()); mHistogramRegistry->fill(HIST(QaDir) + HIST(getHistName(kCentVsSphericity, HistTable)), col.cent(), col.sphericity()); + mHistogramRegistry->fill(HIST(QaDir) + HIST(getHistName(kFT0AvsFT0C, HistTable)), col.centFT0A(), col.centFT0C()); } } @@ -343,6 +375,7 @@ class CollisionHistManager } o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; + bool mPlotEventShape = false; bool mPlot2d = false; }; } // namespace o2::analysis::femto::colhistmanager diff --git a/PWGCF/Femto/Core/dataTypes.h b/PWGCF/Femto/Core/dataTypes.h index 6f3d2aa863a..e61a528dd5c 100644 --- a/PWGCF/Femto/Core/dataTypes.h +++ b/PWGCF/Femto/Core/dataTypes.h @@ -63,6 +63,10 @@ using TransverseMassType = uint16_t; using CharmHadronMaskType = uint32_t; using CharmHadronType = uint16_t; +// datatypes for event shape enums +using QvecDetectorType = uint8_t; +using QvecHarmonicType = uint8_t; + } // namespace o2::analysis::femto::datatypes #endif // PWGCF_FEMTO_CORE_DATATYPES_H_ diff --git a/PWGCF/Femto/Core/femtoUtils.h b/PWGCF/Femto/Core/femtoUtils.h index 6182f91f2fd..50b2e030ccb 100644 --- a/PWGCF/Femto/Core/femtoUtils.h +++ b/PWGCF/Femto/Core/femtoUtils.h @@ -130,11 +130,20 @@ inline double getPdgMass(int pdgCode) } template -float qn(T const& col) -{ - float qn = std::sqrt(col.qvecFT0CReVec()[0] * col.qvecFT0CReVec()[0] + col.qvecFT0CImVec()[0] * col.qvecFT0CImVec()[0]) * std::sqrt(col.sumAmplFT0C()); - return qn; -} +concept HasQvectors = requires(T col) { + col.qvecFT0CReVec(); + col.qvecFT0CImVec(); + col.sumAmplFT0C(); + col.qvecFT0AReVec(); + col.qvecFT0AImVec(); + col.sumAmplFT0A(); +}; + +template +concept HasEventShape = requires(T col) { + col.qvec(); + col.eventPlaneAngle(); +}; /// Recalculate pT for Kinks (Sigmas) using kinematic constraints inline float calcPtnew(float pxMother, float pyMother, float pzMother, float pxDaughter, float pyDaughter, float pzDaughter) diff --git a/PWGCF/Femto/Core/modes.h b/PWGCF/Femto/Core/modes.h index fdcab607c38..8398aa56488 100644 --- a/PWGCF/Femto/Core/modes.h +++ b/PWGCF/Femto/Core/modes.h @@ -178,5 +178,16 @@ enum class CharmHadron : o2::analysis::femto::datatypes::CharmHadronType { kLc }; +enum class QvecDetector : o2::analysis::femto::datatypes::QvecDetectorType { + kFT0C = 0, + kFT0A = 1 +}; + +enum class QvecHarmonic : o2::analysis::femto::datatypes::QvecHarmonicType { + kN1 = 1, + kN2 = 2, + kN3 = 3 +}; + }; // namespace o2::analysis::femto::modes #endif // PWGCF_FEMTO_CORE_MODES_H_ diff --git a/PWGCF/Femto/Core/v0Builder.h b/PWGCF/Femto/Core/v0Builder.h index 2acd743bf7c..8fcdb65bbdb 100644 --- a/PWGCF/Femto/Core/v0Builder.h +++ b/PWGCF/Femto/Core/v0Builder.h @@ -51,8 +51,8 @@ struct ConfV0Filters : o2::framework::ConfigurableGroup { o2::framework::Configurable massMinLambda{"massMinLambda", 1.f, "Minimum mass for Lambda hypothesis"}; o2::framework::Configurable massMaxLambda{"massMaxLambda", 1.2f, "Maximum mass for Lambda hypothesis"}; o2::framework::Configurable rejectHypothesisK0short{"rejectHypothesisK0short", true, "Rejection of K0short hypothesis for Lambda candidates"}; - o2::framework::Configurable rejectMassMinK0short{"rejectMassMinK0short", 0.48f, "Minimum mass to rejection K0short hypothesis for Lambda candidates"}; - o2::framework::Configurable rejectMassMaxK0short{"rejectMassMaxK0short", 0.5f, "Maximum mass to rejection K0short hypothesis for Lambda candidates"}; + o2::framework::Configurable rejectMassMinK0short{"rejectMassMinK0short", 0.475f, "Minimum mass to rejection K0short hypothesis for Lambda candidates"}; + o2::framework::Configurable rejectMassMaxK0short{"rejectMassMaxK0short", 0.515f, "Maximum mass to rejection K0short hypothesis for Lambda candidates"}; o2::framework::Configurable massMinK0short{"massMinK0short", 0.45f, "Minimum mass for K0Short hypothesis"}; o2::framework::Configurable massMaxK0short{"massMaxK0short", 0.53f, "Maximum mass for K0Short hypothesis"}; o2::framework::Configurable rejectHypothesisLambda{"rejectHypothesisLambda", true, "Rejection of Lambda hypothesis for K0short candidates"}; @@ -71,7 +71,9 @@ struct ConfV0Filters : o2::framework::ConfigurableGroup { o2::framework::Configurable> decayVtxMax{"decayVtxMax", {100.f}, "Maximum distance in x,y,z of the decay vertex from primary vertex (cm)"}; \ o2::framework::Configurable> dauAbsEtaMax{"dauAbsEtaMax", {0.8f}, "Maximum |eta| for daughter tracks"}; \ o2::framework::Configurable> dauAbsDcaxyMin{"dauAbsDcaxyMin", {0.05f}, "Minimum DCAxy of the daughters from primary vertex (cm)"}; \ - o2::framework::Configurable> dauTpcClustersMin{"dauTpcClustersMin", {80.f}, "Minimum number of TPC clusters for daughter tracks"}; + o2::framework::Configurable> dauTpcClustersMin{"dauTpcClustersMin", {80.f}, "Minimum number of TPC clusters for daughter tracks"}; \ + o2::framework::Configurable requireTof{"requireTof", false, "If true, TOF PID is a minimal selection. If false, TOF PID is an optional"}; \ + o2::framework::Configurable keepTracksWithoutTof{"keepTracksWithoutTof", true, "If true, the bit mask for the TOF selection will be ture for all limits if the daugher track has no TOF"}; // derived selection bits for lambda struct ConfLambdaBits : o2::framework::ConfigurableGroup { @@ -85,8 +87,6 @@ struct ConfLambdaBits : o2::framework::ConfigurableGroup { o2::framework::Configurable> posDauTofProton{"posDauTofProton", {}, "Maximum |nsigma_Proton| TOF for positive daughter tracks"}; o2::framework::Configurable> negDauTofPion{"negDauTofPion", {}, "Maximum |nsigma_Pion| TOF for negative daughter tracks"}; o2::framework::Configurable> negDauTofProton{"negDauTofProton", {}, "Maximum |nsigma_Proton| TOF for negative daughter tracks"}; - o2::framework::Configurable requireTof{"requireTof", false, "If true, TOF PID is a mandatory selection"}; - o2::framework::Configurable keepTracksWithoutTof{"keepTracksWithoutTof", true, "If true, candidates whose daughters have no TOF signal are kept"}; }; // derived selection bits for K0Short @@ -97,8 +97,6 @@ struct ConfK0shortBits : o2::framework::ConfigurableGroup { o2::framework::Configurable> negDauTpcPion{"negDauTpcPion", {5.f}, "Maximum |nsimga_Pion| TPC for negative daughter tracks"}; o2::framework::Configurable> posDauTofPion{"posDauTofPion", {}, "Maximum |nsigma_Pion| TOF for positive daughter tracks"}; o2::framework::Configurable> negDauTofPion{"negDauTofPion", {}, "Maximum |nsigma_Pion| TOF for negative daughter tracks"}; - o2::framework::Configurable requireTof{"requireTof", false, "If true, TOF PID is a mandatory selection"}; - o2::framework::Configurable keepTracksWithoutTof{"keepTracksWithoutTof", true, "If true, candidates whose daughters have no TOF signal are kept"}; }; #undef V0_DEFAULT_BITS @@ -335,32 +333,49 @@ class V0Selection : public baseselection::BaseSelection(); auto negDaughter = v0candidate.template negTrack_as(); - std::array etaAbsDaughters = {std::fabs(posDaughter.eta()), std::fabs(negDaughter.eta())}; + std::array etaAbsDaughters = {std::fabs(v0candidate.positiveeta()), std::fabs(v0candidate.negativeeta())}; this->evaluateObservable(kDauAbsEtaMax, *std::max_element(etaAbsDaughters.begin(), etaAbsDaughters.end())); - std::array dcaxyAbsDaughters = {std::fabs(posDaughter.dcaXY()), std::fabs(negDaughter.dcaXY())}; + std::array dcaxyAbsDaughters = {std::fabs(v0candidate.dcapostopv()), std::fabs(v0candidate.dcanegtopv())}; this->evaluateObservable(kDauAbsDcaxyMin, *std::min_element(dcaxyAbsDaughters.begin(), dcaxyAbsDaughters.end())); std::array clustersDaughters = {1.f * posDaughter.tpcNClsFound(), 1.f * negDaughter.tpcNClsFound()}; this->evaluateObservable(kDauTpcClsMin, *std::min_element(clustersDaughters.begin(), clustersDaughters.end())); - this->evaluateObservable(kPosDaughTpcPion, posDaughter.tpcNSigmaPi()); - this->evaluateObservable(kPosDaughTpcProton, posDaughter.tpcNSigmaPr()); - this->evaluateObservable(kNegDaughTpcPion, negDaughter.tpcNSigmaPi()); - this->evaluateObservable(kNegDaughTpcProton, negDaughter.tpcNSigmaPr()); - if (posDaughter.hasTOF()) { - this->evaluateObservable(kPosDaughTofPion, posDaughter.tofNSigmaPi()); - this->evaluateObservable(kPosDaughTofProton, posDaughter.tofNSigmaPr()); - } else if (mKeepTracksWithoutTof) { - this->evaluateObservable(kPosDaughTofPion, 0); - this->evaluateObservable(kPosDaughTofProton, 0); - } - if (negDaughter.hasTOF()) { - this->evaluateObservable(kNegDaughTofPion, negDaughter.tofNSigmaPi()); - this->evaluateObservable(kNegDaughTofProton, negDaughter.tofNSigmaPr()); - } else if (mKeepTracksWithoutTof) { - this->evaluateObservable(kNegDaughTofPion, 0); - this->evaluateObservable(kNegDaughTofProton, 0); + // PID of the daughters under the mass hypothesis of this v0 type + // TPC nSigma comes from the daughter track, TOF nSigma from the strangeness-tagged v0 candidate + // if the daughter has no TOF signal, feed 0 so the bit passes any limit (opt-in via keepTracksWithoutTof) + auto evaluateDaughterPid = [this](V0Sels tpcBit, float tpcNSigma, + V0Sels tofBit, float tofNSigma, bool hasTof) { + this->evaluateObservable(tpcBit, tpcNSigma); + if (hasTof) { + this->evaluateObservable(tofBit, tofNSigma); + } else if (mKeepTracksWithoutTof) { + this->evaluateObservable(tofBit, 0.f); + } + }; + + const bool posHasTof = v0candidate.positiveHasTOF(); + const bool negHasTof = v0candidate.negativeHasTOF(); + + if constexpr (modes::isEqual(v0Type, modes::V0::kLambda)) { + // Lambda -> p pi- + evaluateDaughterPid(kPosDaughTpcProton, posDaughter.tpcNSigmaPr(), + kPosDaughTofProton, v0candidate.tofNSigmaLaPr(), posHasTof); + evaluateDaughterPid(kNegDaughTpcPion, negDaughter.tpcNSigmaPi(), + kNegDaughTofPion, v0candidate.tofNSigmaLaPi(), negHasTof); + } else if constexpr (modes::isEqual(v0Type, modes::V0::kAntiLambda)) { + // AntiLambda -> pbar pi+ + evaluateDaughterPid(kPosDaughTpcPion, posDaughter.tpcNSigmaPi(), + kPosDaughTofPion, v0candidate.tofNSigmaALaPi(), posHasTof); + evaluateDaughterPid(kNegDaughTpcProton, negDaughter.tpcNSigmaPr(), + kNegDaughTofProton, v0candidate.tofNSigmaALaPr(), negHasTof); + } else if constexpr (modes::isEqual(v0Type, modes::V0::kK0short)) { + // K0short -> pi+ pi- + evaluateDaughterPid(kPosDaughTpcPion, posDaughter.tpcNSigmaPi(), + kPosDaughTofPion, v0candidate.tofNSigmaK0PiPlus(), posHasTof); + evaluateDaughterPid(kNegDaughTpcPion, negDaughter.tpcNSigmaPi(), + kNegDaughTofPion, v0candidate.tofNSigmaK0PiMinus(), negHasTof); } this->assembleBitmask(); @@ -649,12 +664,18 @@ class V0Builder { float mass = 0; float massAnti = 0; + float strangeTofPosDau = 0; + float strangeTofNegDau = 0; if (sign > 0.f) { mass = v0.mLambda(); massAnti = v0.mAntiLambda(); + strangeTofPosDau = v0.tofNSigmaLaPr(); + strangeTofNegDau = v0.tofNSigmaLaPi(); } else { mass = v0.mAntiLambda(); massAnti = v0.mLambda(); + strangeTofPosDau = v0.tofNSigmaALaPi(); + strangeTofNegDau = v0.tofNSigmaALaPr(); } if (mProduceLambdas) { v0Products.producedLambdas(collisionBuilder.collisionIndex(), @@ -683,6 +704,8 @@ class V0Builder v0.mK0Short(), v0.v0cosPA(), v0.dcaV0daughters(), + strangeTofPosDau, + strangeTofNegDau, v0.v0radius(), v0.x(), v0.y(), @@ -720,6 +743,8 @@ class V0Builder v0.mAntiLambda(), v0.v0cosPA(), v0.dcaV0daughters(), + v0.tofNSigmaK0PiPlus(), + v0.tofNSigmaK0PiMinus(), v0.v0radius(), v0.x(), v0.y(), diff --git a/PWGCF/Femto/Core/v0HistManager.h b/PWGCF/Femto/Core/v0HistManager.h index 62199688116..598d2766d6f 100644 --- a/PWGCF/Femto/Core/v0HistManager.h +++ b/PWGCF/Femto/Core/v0HistManager.h @@ -53,6 +53,8 @@ enum V0Hist { kMassK0short, kCosPa, kDecayDauDca, + kStrangeTofPosDau, + kStrangeTofNegDau, kDecayVtxX, kDecayVtxY, kDecayVtxZ, @@ -69,6 +71,8 @@ enum V0Hist { kLambdaMassVsAntiLambdaMass, kK0shortMassVsLambdaMass, kK0shortMassVsAntiLambdaMass, + kStrangeTofVsTofPosDau, + kStrangeTofVsTofNegDau, // mc kOrigin, kPdg, @@ -137,6 +141,7 @@ struct ConfV0QaBinning : o2::framework::ConfigurableGroup { o2::framework::ConfigurableAxis massLambda{"massLambda", {{200, 1, 1.2}}, "mass for antiparticle hypothesis"}; o2::framework::ConfigurableAxis massAntiLambda{"massAntiLambda", {{100, 1, 1.2}}, "mass for antiparticle hypothesis"}; o2::framework::ConfigurableAxis massK0short{"massK0short", {{200, 0.45, 0.55}}, "Mass for k0short hypothesis"}; + o2::framework::ConfigurableAxis strangeTof{"strangeTof", {{500, -5, 5}}, "Strangeness TOF vs TOF Nsigma for daughters"}; }; constexpr const char PrefixLambdaQaBinning1[] = "LambdaQaBinning1"; @@ -159,6 +164,8 @@ constexpr std::array, kV0HistLast> HistTable = { {kMassK0short, o2::framework::HistType::kTH1F, "hMassK0short", "K^{0}_{s} mass; m_{#pi^{+}#pi^{-}} (GeV/#it{c}^{2}); Entries"}, {kCosPa, o2::framework::HistType::kTH1F, "hCosPa", "Cosine of pointing angle; cos(#alpha); Entries"}, {kDecayDauDca, o2::framework::HistType::kTH1F, "hDauDca", "Daughter DCA at decay vertex ; DCA_{Decay vertex} (cm); Entries"}, + {kStrangeTofPosDau, o2::framework::HistType::kTH1F, "hStrangeTofPosDau", "Strange TOF of positive Daughter ; n#sigma_{TOF, strange}; Entries"}, + {kStrangeTofNegDau, o2::framework::HistType::kTH1F, "hStrangeTofNegDau", "Strange TOF of negative Daughter ; n#sigma+{TOF, strange}; 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"}, @@ -174,6 +181,8 @@ constexpr std::array, kV0HistLast> HistTable = { {kK0shortMassVsLambdaMass, o2::framework::HistType::kTH2F, "hK0shortMassVsLambdaMass", " K^{0}_{S} mass vs #Lambda mass; m_{#pi^{+}#pi^{-}} (GeV/#it{c}^{2}); m_{p#pi^{-}} (GeV/#it{c}^{2})"}, {kK0shortMassVsAntiLambdaMass, o2::framework::HistType::kTH2F, "hK0shortMassVsAntiLambdaMass", "K^{0}_{S} mass vs #bar{#Lambda} mass; m_{#pi^{+}#pi^{-}} (GeV/#it{c}^{2}); m_{#bar{p}#pi^{+}} (GeV/#it{c}^{2})"}, {kLambdaMassVsAntiLambdaMass, o2::framework::HistType::kTH2F, "hLambdaMassVsAntiLambdaMass", "#Lambda mass vs #bar{#Lambda}; m_{p#pi^{-}} (GeV/#it{c}^{2}); m_{#bar{p}#pi^{+}} (GeV/#it{c}^{2})"}, + {kStrangeTofVsTofPosDau, o2::framework::HistType::kTH2F, "hStrangeTofVsTofPosDau", "TOF_{Strange} vs TOF_{Tracking} of positive Daughter; n#sigma_{TOF, strange}; n#sigma_{TOF, tracking}"}, + {kStrangeTofVsTofNegDau, o2::framework::HistType::kTH2F, "hStrangeTofVsTofNegDau", "TOF_{Strange} vs TOF_{Tracking} of negative Daughter; n#sigma_{TOF, strange}; n#sigma_{TOF, tracking}"}, {kOrigin, o2::framework::HistType::kTH1F, "hOrigin", "Status Codes (=Origin); Status Code; Entries"}, {kPdg, o2::framework::HistType::kTH1F, "hPdg", "PDG Codes of reconstructed v0; PDG Code; Entries"}, {kPdgMother, o2::framework::HistType::kTH1F, "hPdgMother", "PDG Codes of mother of reconstructed v0; PDG Code; Entries"}, @@ -211,27 +220,31 @@ constexpr std::array, kV0HistLast> HistTable = { {kPdgPartonicMother, {(conf).pdgCodes}}, // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define V0_HIST_QA_MAP(confAnalysis, confQa) \ - {kCosPa, {(confQa).cosPa}}, \ - {kDecayDauDca, {(confQa).dauDcaAtDecay}}, \ - {kDecayVtxX, {(confQa).decayVertex}}, \ - {kDecayVtxY, {(confQa).decayVertex}}, \ - {kDecayVtxZ, {(confQa).decayVertex}}, \ - {kDecayVtx, {(confQa).decayVertex}}, \ - {kTransRadius, {(confQa).transRadius}}, \ - {kPtVsEta, {(confAnalysis).pt, (confAnalysis).eta}}, \ - {kPtVsPhi, {(confAnalysis).pt, (confAnalysis).phi}}, \ - {kPhiVsEta, {(confAnalysis).phi, (confAnalysis).eta}}, \ - {kPtVsCosPa, {(confAnalysis).pt, (confQa).cosPa}}, \ - {kMassLambda, {(confQa).massLambda}}, \ - {kMassAntiLambda, {(confQa).massAntiLambda}}, \ - {kMassK0short, {(confQa).massK0short}}, \ - {kPtVsLambdaMass, {(confAnalysis).pt, (confQa).massLambda}}, \ - {kPtVsAntiLambdaMass, {(confAnalysis).pt, (confQa).massAntiLambda}}, \ - {kPtVsK0shortMass, {(confAnalysis).pt, (confQa).massK0short}}, \ - {kLambdaMassVsAntiLambdaMass, {(confQa).massLambda, (confQa).massAntiLambda}}, \ - {kK0shortMassVsLambdaMass, {(confQa).massK0short, (confQa).massLambda}}, \ - {kK0shortMassVsAntiLambdaMass, {(confQa).massK0short, (confQa).massAntiLambda}}, +#define V0_HIST_QA_MAP(confAnalysis, confQa) \ + {kCosPa, {(confQa).cosPa}}, \ + {kDecayDauDca, {(confQa).dauDcaAtDecay}}, \ + {kStrangeTofPosDau, {(confQa).strangeTof}}, \ + {kStrangeTofNegDau, {(confQa).strangeTof}}, \ + {kDecayVtxX, {(confQa).decayVertex}}, \ + {kDecayVtxY, {(confQa).decayVertex}}, \ + {kDecayVtxZ, {(confQa).decayVertex}}, \ + {kDecayVtx, {(confQa).decayVertex}}, \ + {kTransRadius, {(confQa).transRadius}}, \ + {kPtVsEta, {(confAnalysis).pt, (confAnalysis).eta}}, \ + {kPtVsPhi, {(confAnalysis).pt, (confAnalysis).phi}}, \ + {kPhiVsEta, {(confAnalysis).phi, (confAnalysis).eta}}, \ + {kPtVsCosPa, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kMassLambda, {(confQa).massLambda}}, \ + {kMassAntiLambda, {(confQa).massAntiLambda}}, \ + {kMassK0short, {(confQa).massK0short}}, \ + {kPtVsLambdaMass, {(confAnalysis).pt, (confQa).massLambda}}, \ + {kPtVsAntiLambdaMass, {(confAnalysis).pt, (confQa).massAntiLambda}}, \ + {kPtVsK0shortMass, {(confAnalysis).pt, (confQa).massK0short}}, \ + {kLambdaMassVsAntiLambdaMass, {(confQa).massLambda, (confQa).massAntiLambda}}, \ + {kK0shortMassVsLambdaMass, {(confQa).massK0short, (confQa).massLambda}}, \ + {kK0shortMassVsAntiLambdaMass, {(confQa).massK0short, (confQa).massAntiLambda}}, \ + {kStrangeTofVsTofPosDau, {(confQa).strangeTof, (confQa).strangeTof}}, \ + {kStrangeTofVsTofNegDau, {(confQa).strangeTof, (confQa).strangeTof}}, // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define V0_HIST_MC_QA_MAP(confAnalysis, confQa) \ @@ -416,7 +429,7 @@ class V0HistManager this->fillAnalysis(v0candidate); } if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { - this->fillQa(v0candidate); + this->fillQa(v0candidate, posDaughter, negDaughter); } } @@ -431,7 +444,7 @@ class V0HistManager this->fillAnalysis(v0candidate); } if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { - this->fillQa(v0candidate); + this->fillQa(v0candidate, posDaughter, negDaughter); } if constexpr (modes::isFlagSet(mode, modes::Mode::kMc)) { this->template fillMc(v0candidate, col, mcParticles, mcMothers, mcPartonicMothers); @@ -471,6 +484,8 @@ class V0HistManager mHistogramRegistry->add(qaDir + getHistNameV2(kCosPa, HistTable), getHistDesc(kCosPa, HistTable), getHistType(kCosPa, HistTable), {V0Specs.at(kCosPa)}); mHistogramRegistry->add(qaDir + getHistNameV2(kDecayDauDca, HistTable), getHistDesc(kDecayDauDca, HistTable), getHistType(kDecayDauDca, HistTable), {V0Specs.at(kDecayDauDca)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kStrangeTofPosDau, HistTable), getHistDesc(kStrangeTofPosDau, HistTable), getHistType(kStrangeTofPosDau, HistTable), {V0Specs.at(kStrangeTofPosDau)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kStrangeTofNegDau, HistTable), getHistDesc(kStrangeTofNegDau, HistTable), getHistType(kStrangeTofNegDau, HistTable), {V0Specs.at(kStrangeTofNegDau)}); mHistogramRegistry->add(qaDir + getHistNameV2(kDecayVtxX, HistTable), getHistDesc(kDecayVtxX, HistTable), getHistType(kDecayVtxX, HistTable), {V0Specs.at(kDecayVtxX)}); mHistogramRegistry->add(qaDir + getHistNameV2(kDecayVtxY, HistTable), getHistDesc(kDecayVtxY, HistTable), getHistType(kDecayVtxY, HistTable), {V0Specs.at(kDecayVtxY)}); mHistogramRegistry->add(qaDir + getHistNameV2(kDecayVtxZ, HistTable), getHistDesc(kDecayVtxZ, HistTable), getHistType(kDecayVtxZ, HistTable), {V0Specs.at(kDecayVtxZ)}); @@ -492,6 +507,8 @@ class V0HistManager mHistogramRegistry->add(qaDir + getHistNameV2(kLambdaMassVsAntiLambdaMass, HistTable), getHistDesc(kLambdaMassVsAntiLambdaMass, HistTable), getHistType(kLambdaMassVsAntiLambdaMass, HistTable), {V0Specs.at(kLambdaMassVsAntiLambdaMass)}); mHistogramRegistry->add(qaDir + getHistNameV2(kK0shortMassVsLambdaMass, HistTable), getHistDesc(kK0shortMassVsLambdaMass, HistTable), getHistType(kK0shortMassVsLambdaMass, HistTable), {V0Specs.at(kK0shortMassVsLambdaMass)}); mHistogramRegistry->add(qaDir + getHistNameV2(kK0shortMassVsAntiLambdaMass, HistTable), getHistDesc(kK0shortMassVsAntiLambdaMass, HistTable), getHistType(kK0shortMassVsAntiLambdaMass, HistTable), {V0Specs.at(kK0shortMassVsAntiLambdaMass)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kStrangeTofVsTofPosDau, HistTable), getHistDesc(kStrangeTofVsTofPosDau, HistTable), getHistType(kStrangeTofVsTofPosDau, HistTable), {V0Specs.at(kStrangeTofVsTofPosDau)}); + mHistogramRegistry->add(qaDir + getHistNameV2(kStrangeTofVsTofNegDau, HistTable), getHistDesc(kStrangeTofVsTofNegDau, HistTable), getHistType(kStrangeTofVsTofNegDau, HistTable), {V0Specs.at(kStrangeTofVsTofNegDau)}); } } @@ -553,11 +570,13 @@ class V0HistManager } } - template - void fillQa(T const& v0candidate) + template + void fillQa(T1 const& v0candidate, T2 const& posDau, T3 const& negDau) { mHistogramRegistry->fill(HIST(v0Prefix) + HIST(QaDir) + HIST(getHistName(kCosPa, HistTable)), v0candidate.cosPa()); mHistogramRegistry->fill(HIST(v0Prefix) + HIST(QaDir) + HIST(getHistName(kDecayDauDca, HistTable)), v0candidate.dauDca()); + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(QaDir) + HIST(getHistName(kStrangeTofPosDau, HistTable)), v0candidate.strangeTofPosDau()); + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(QaDir) + HIST(getHistName(kStrangeTofNegDau, HistTable)), v0candidate.strangeTofNegDau()); mHistogramRegistry->fill(HIST(v0Prefix) + HIST(QaDir) + HIST(getHistName(kDecayVtxX, HistTable)), v0candidate.decayVtxX()); mHistogramRegistry->fill(HIST(v0Prefix) + HIST(QaDir) + HIST(getHistName(kDecayVtxY, HistTable)), v0candidate.decayVtxY()); mHistogramRegistry->fill(HIST(v0Prefix) + HIST(QaDir) + HIST(getHistName(kDecayVtxZ, HistTable)), v0candidate.decayVtxZ()); @@ -567,21 +586,29 @@ class V0HistManager float massLambda = 0; float massAntiLambda = 0; float massK0short = 0; + float tofPosDau = 0; + float tofNegDau = 0; if constexpr (modes::isEqual(v0, modes::V0::kLambda) || modes::isEqual(v0, modes::V0::kAntiLambda)) { massK0short = v0candidate.massK0short(); if (v0candidate.sign() > 0) { massLambda = v0candidate.mass(); massAntiLambda = v0candidate.massAnti(); + tofPosDau = posDau.tofNSigmaPr(); + tofNegDau = negDau.tofNSigmaPi(); } else { massLambda = v0candidate.massAnti(); massAntiLambda = v0candidate.mass(); + tofPosDau = posDau.tofNSigmaPi(); + tofNegDau = negDau.tofNSigmaPr(); } } if constexpr (modes::isEqual(v0, modes::V0::kK0short)) { massK0short = v0candidate.mass(); massLambda = v0candidate.massLambda(); massAntiLambda = v0candidate.massAntiLambda(); + tofPosDau = posDau.tofNSigmaPi(); + tofNegDau = posDau.tofNSigmaPi(); } mHistogramRegistry->fill(HIST(v0Prefix) + HIST(QaDir) + HIST(getHistName(kMassLambda, HistTable)), massLambda); @@ -600,6 +627,8 @@ class V0HistManager mHistogramRegistry->fill(HIST(v0Prefix) + HIST(QaDir) + HIST(getHistName(kLambdaMassVsAntiLambdaMass, HistTable)), massLambda, massAntiLambda); mHistogramRegistry->fill(HIST(v0Prefix) + HIST(QaDir) + HIST(getHistName(kK0shortMassVsLambdaMass, HistTable)), massK0short, massLambda); mHistogramRegistry->fill(HIST(v0Prefix) + HIST(QaDir) + HIST(getHistName(kK0shortMassVsAntiLambdaMass, HistTable)), massK0short, massAntiLambda); + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(QaDir) + HIST(getHistName(kStrangeTofVsTofPosDau, HistTable)), v0candidate.strangeTofPosDau(), tofPosDau); + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(QaDir) + HIST(getHistName(kStrangeTofVsTofNegDau, HistTable)), v0candidate.strangeTofNegDau(), tofNegDau); } } diff --git a/PWGCF/Femto/DataModel/FemtoTables.h b/PWGCF/Femto/DataModel/FemtoTables.h index f071e914de7..000e9430469 100644 --- a/PWGCF/Femto/DataModel/FemtoTables.h +++ b/PWGCF/Femto/DataModel/FemtoTables.h @@ -37,14 +37,15 @@ namespace femtocollisions DECLARE_SOA_COLUMN(Mask, mask, o2::analysis::femto::datatypes::CollisionMaskType); //! Bitmask for collision selections DECLARE_SOA_COLUMN(CollisionTag, collisionTag, o2::analysis::femto::datatypes::CollisionTagType); //! Bitmask for collision selections -DECLARE_SOA_COLUMN(PosX, posX, float); //! x coordinate of vertex -DECLARE_SOA_COLUMN(PosY, posY, float); //! y coordinate of vertex -DECLARE_SOA_COLUMN(PosZ, posZ, float); //! z coordinate of vertex -DECLARE_SOA_COLUMN(Mult, mult, float); //! Multiplicity estimator set by producer -DECLARE_SOA_COLUMN(Cent, cent, float); //! Centrality (~= multiplicity percentile) estimator set by producer -DECLARE_SOA_COLUMN(MagField, magField, int8_t); //! Magnetic field in kG (5 kG at normal configuration and 2kG in low B field configuration) -DECLARE_SOA_COLUMN(Sphericity, sphericity, float); //! Sphericity of the event -DECLARE_SOA_COLUMN(Qn, qn, float); //! qn bins for dividing eventsfemtab +DECLARE_SOA_COLUMN(PosX, posX, float); //! x coordinate of vertex +DECLARE_SOA_COLUMN(PosY, posY, float); //! y coordinate of vertex +DECLARE_SOA_COLUMN(PosZ, posZ, float); //! z coordinate of vertex +DECLARE_SOA_COLUMN(Mult, mult, float); //! Multiplicity estimator set by producer +DECLARE_SOA_COLUMN(Cent, cent, float); //! Centrality (~= multiplicity percentile) estimator set by producer +DECLARE_SOA_COLUMN(MagField, magField, int8_t); //! Magnetic field in kG (5 kG at normal configuration and 2kG in low B field configuration) +DECLARE_SOA_COLUMN(Sphericity, sphericity, float); //! Sphericity of the event +DECLARE_SOA_COLUMN(Qvec, qvec, float); //! qvector +DECLARE_SOA_COLUMN(EventPlaneAngle, eventPlaneAngle, float); //! event plane angle (for corresponding q vector) namespace lite { @@ -120,9 +121,10 @@ DECLARE_SOA_TABLE_STAGED_VERSIONED(FColSphericities_001, "FCOLSPHERICITY", 1, // using FColSphericities = FColSphericities_001; // table for qn values -DECLARE_SOA_TABLE_STAGED_VERSIONED(FColQns_001, "FCOLQN", 1, //! qn vector - femtocollisions::Qn); -using FColQns = FColQns_001; +DECLARE_SOA_TABLE_STAGED_VERSIONED(FColShapes_001, "FCOLSHAPE", 1, //! event shape + femtocollisions::Qvec, + femtocollisions::EventPlaneAngle); +using FColShapes = FColShapes_001; // table for primary vertex location DECLARE_SOA_TABLE_STAGED_VERSIONED(FColPos_001, "FCOLPOS", 1, //! full vertex position @@ -142,7 +144,8 @@ using FColMults = FColMults_001; // table for different centrality (multiplicity percentile) estimators DECLARE_SOA_TABLE_STAGED_VERSIONED(FColCents_001, "FCOLCENT", 1, //! centralities cent::CentFT0A, //! centrality from FT0A - cent::CentFT0C); //! centrality from FT0C + cent::CentFT0C, //! centrality from FT0C + cent::CentFT0M); //! centrality from FT0M using FColCents = FColCents_001; namespace femtobase @@ -557,17 +560,19 @@ DECLARE_SOA_COLUMN(Mask, mask, o2::analysis::femto::datatypes::V0MaskType001); / } // columns for debug information -DECLARE_SOA_COLUMN(MassAnti, massAnti, float); //! mass of particle using antiparticle hypothesis (for Lambda/AntiLambda extra table) -DECLARE_SOA_COLUMN(MassLambda, massLambda, float); //! Mass of Lambda (for k0short table) -DECLARE_SOA_COLUMN(MassAntiLambda, massAntiLambda, float); //! Mass of AntiLambda (for k0short table) -DECLARE_SOA_COLUMN(MassK0short, massK0short, float); //! Mass of K0short (for lambda/antitlambda table) -DECLARE_SOA_COLUMN(CosPa, cosPa, float); //! Lambda daughter DCA at decay vertex -DECLARE_SOA_COLUMN(DauDca, dauDca, float); //! Lambda daughter DCA at decay vertex -DECLARE_SOA_COLUMN(TransRadius, transRadius, float); //! Lambda transvers radius -DECLARE_SOA_COLUMN(DecayVtxX, decayVtxX, float); //! x coordinate of Lambda decay vertex -DECLARE_SOA_COLUMN(DecayVtxY, decayVtxY, float); //! y coordinate of Lambda decay vertex -DECLARE_SOA_COLUMN(DecayVtxZ, decayVtxZ, float); //! z coordinate of Lambda decay vertex -DECLARE_SOA_DYNAMIC_COLUMN(DecayVtx, decayVtx, //! distance of decay vertex from nominal interaction point +DECLARE_SOA_COLUMN(MassAnti, massAnti, float); //! mass of particle using antiparticle hypothesis (for Lambda/AntiLambda extra table) +DECLARE_SOA_COLUMN(MassLambda, massLambda, float); //! Mass of Lambda (for k0short table) +DECLARE_SOA_COLUMN(MassAntiLambda, massAntiLambda, float); //! Mass of AntiLambda (for k0short table) +DECLARE_SOA_COLUMN(MassK0short, massK0short, float); //! Mass of K0short (for lambda/antitlambda table) +DECLARE_SOA_COLUMN(CosPa, cosPa, float); //! Lambda daughter DCA at decay vertex +DECLARE_SOA_COLUMN(DauDca, dauDca, float); //! Lambda daughter DCA at decay vertex +DECLARE_SOA_COLUMN(StrangeTofPosDau, strangeTofPosDau, float); //! TOF Strangeness for positive daughter +DECLARE_SOA_COLUMN(StrangeTofNegDau, strangeTofNegDau, float); //! TOF Strangeness for negative daughter +DECLARE_SOA_COLUMN(TransRadius, transRadius, float); //! Lambda transvers radius +DECLARE_SOA_COLUMN(DecayVtxX, decayVtxX, float); //! x coordinate of Lambda decay vertex +DECLARE_SOA_COLUMN(DecayVtxY, decayVtxY, float); //! y coordinate of Lambda decay vertex +DECLARE_SOA_COLUMN(DecayVtxZ, decayVtxZ, float); //! z coordinate of Lambda decay vertex +DECLARE_SOA_DYNAMIC_COLUMN(DecayVtx, decayVtx, //! distance of decay vertex from nominal interaction point [](float vtxX, float vtxY, float vtxZ) -> float { return std::hypot(vtxX, vtxY, vtxZ); }); @@ -668,6 +673,8 @@ DECLARE_SOA_TABLE_STAGED_VERSIONED(FLambdaExtras_001, "FLAMBDAEXTRA", 1, //! lam femtov0s::MassK0short, femtov0s::CosPa, femtov0s::DauDca, + femtov0s::StrangeTofPosDau, + femtov0s::StrangeTofNegDau, femtov0s::TransRadius, femtov0s::DecayVtxX, femtov0s::DecayVtxY, @@ -725,6 +732,8 @@ DECLARE_SOA_TABLE_STAGED_VERSIONED(FK0shortExtras_001, "FK0SHORTEXTRA", 1, //! k femtov0s::MassAntiLambda, femtov0s::CosPa, femtov0s::DauDca, + femtov0s::StrangeTofPosDau, + femtov0s::StrangeTofNegDau, femtov0s::TransRadius, femtov0s::DecayVtxX, femtov0s::DecayVtxY, @@ -921,6 +930,7 @@ DECLARE_SOA_COLUMN(LambdaCosPa, lambdaCosPa, float); //! cosine of DECLARE_SOA_COLUMN(LambdaDauDca, lambdaDauDca, float); //! Lambda daughter DCA at decay vertex DECLARE_SOA_COLUMN(LambdaTransRadius, lambdaTransRadius, float); //! Lambda transvers radius DECLARE_SOA_COLUMN(LambdaDcaToPv, lambdaDcaToPv, float); //! Lambda transvers radius +DECLARE_SOA_COLUMN(StrangeTofBachelor, strangeTofBachelor, float); //! Lambda transvers radius // id columns for bachelor // following same style as strangeness tables were we do not store the id of the lambda, but its daughters @@ -1021,7 +1031,10 @@ DECLARE_SOA_TABLE_STAGED_VERSIONED(FXiExtras_001, "FXIEXTRA", 1, //! xi extra in femtocascades::LambdaCosPa, femtocascades::LambdaDauDca, femtocascades::LambdaTransRadius, - femtocascades::LambdaDcaToPv); + femtocascades::LambdaDcaToPv, + femtocascades::StrangeTofBachelor, + femtov0s::StrangeTofPosDau, + femtov0s::StrangeTofNegDau); using FXiExtras = FXiExtras_001; DECLARE_SOA_TABLE_STAGED_VERSIONED(FOmegas_001, "FOMEGA", 1, //! femto omegas @@ -1083,7 +1096,10 @@ DECLARE_SOA_TABLE_STAGED_VERSIONED(FOmegaExtras_001, "FOMEGAEXTRA", 1, //! omega femtocascades::LambdaCosPa, femtocascades::LambdaDauDca, femtocascades::LambdaTransRadius, - femtocascades::LambdaDcaToPv); + femtocascades::LambdaDcaToPv, + femtocascades::StrangeTofBachelor, + femtov0s::StrangeTofPosDau, + femtov0s::StrangeTofNegDau); using FOmegaExtras = FOmegaExtras_001; namespace femtocharmhadrons diff --git a/PWGCF/Femto/TableProducer/femtoProducer.cxx b/PWGCF/Femto/TableProducer/femtoProducer.cxx index f85e3bfa67d..e28b6ea656a 100644 --- a/PWGCF/Femto/TableProducer/femtoProducer.cxx +++ b/PWGCF/Femto/TableProducer/femtoProducer.cxx @@ -24,6 +24,7 @@ #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGLF/DataModel/LFKinkDecayTables.h" +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" #include "PWGLF/DataModel/LFStrangenessTables.h" #include "PWGLF/DataModel/mcCentrality.h" @@ -59,11 +60,13 @@ using namespace o2::analysis::femto; namespace o2::analysis::femto::rawinputs { -using Run3PpCollisions = o2::soa::Join; +using Run3PpCollisions = o2::soa::Join; using Run3PpMcRecoCollisions = o2::soa::Join; using Run3PpMcGenCollisions = o2::soa::Join; -using Run3PbPbCollisions = o2::soa::Join; +using Run3PbPbCollisions = o2::soa::Join; +using Run3PbPbCollisionsWithEventShape = o2::soa::Join; + using Run3PbPbMcRecoCollisions = o2::soa::Join; using Run3PbPbMcGenCollisions = o2::soa::Join; @@ -74,13 +77,13 @@ using Run3FullPidTracks = o2::aod::pidTOFbeta, o2::aod::pidTOFmass>; using Run3McRecoTracks = soa::Join; -using Run3Vzeros = o2::aod::V0Datas; -using Run3RecoVzeros = o2::soa::Join; +using Run3Vzeros = o2::soa::Join; +using Run3RecoVzeros = o2::soa::Join; using Run3D0s = soa::Join; using Run3RecoD0s = soa::Join; -using Run3Cascades = o2::aod::CascDatas; +using Run3Cascades = o2::soa::Join; using Run3RecoCascades = o2::soa::Join; using Run3Kinks = o2::aod::KinkCands; @@ -273,6 +276,35 @@ struct FemtoProducer { } } + // ---- guard: exactly one process function --------------------------------- + const int nProcesses = + static_cast(doprocessTracksRun3pp) + + static_cast(doprocessTracksRun3PbPb) + + static_cast(doprocessTracksRun3PbPbWithEventShape) + + static_cast(doprocessTracksV0sRun3pp) + + static_cast(doprocessTracksV0sRun3PbPb) + + static_cast(doprocessTracksV0sCascadesRun3pp) + + static_cast(doprocessTracksV0sCascadesRun3PbPb) + + static_cast(doprocessTracksKinksRun3pp) + + static_cast(doprocessTracksV0sCascadesKinksRun3pp) + + static_cast(doprocessTracksD0sRun3pp) + + static_cast(doprocessTracksD0sRun3PbPb) + + static_cast(doprocessTracksRun3ppMc) + + static_cast(doprocessTracksRun3PbPbMc) + + static_cast(doprocessTracksV0sRun3ppMc) + + static_cast(doprocessTracksV0sRun3PbPbMc) + + static_cast(doprocessTracksV0sCascadesRun3ppMc) + + static_cast(doprocessTracksV0sCascadesRun3PbPbMc) + + static_cast(doprocessTracksKinksRun3ppMc) + + static_cast(doprocessTracksV0sKinksRun3ppMc) + + static_cast(doprocessTracksD0sRun3ppMc) + + static_cast(doprocessTracksD0sRun3PbPbMc) + + static_cast(doprocessMcOnly); + + if (nProcesses != 1) { + LOG(fatal) << "Exactly one process function must be enabled, found " << nProcesses << ". Breaking..."; + } + hRegistry.print(); } @@ -422,6 +454,19 @@ struct FemtoProducer { } PROCESS_SWITCH(FemtoProducer, processTracksRun3PbPb, "Provide tracks in PbPb collisions", false); + void processTracksRun3PbPbWithEventShape(rawinputs::Run3PbPbCollisionsWithEventShape::iterator const& col, + o2::aod::BCsWithTimestamps const& bcs, + rawinputs::Run3FullPidTracks const& tracks) + { + if (!processCollisions(col, bcs, tracks)) { + return; + } + auto tracksWithItsPid = o2::soa::Attach(tracks); + processTracks(col, tracksWithItsPid); + } + PROCESS_SWITCH(FemtoProducer, processTracksRun3PbPbWithEventShape, "Provide tracks in PbPb collisions with event shape information", false); + void processTracksV0sRun3pp(rawinputs::Run3PpCollisions::iterator const& col, o2::aod::BCsWithTimestamps const& bcs, rawinputs::Run3FullPidTracks const& tracks, diff --git a/PWGCF/Femto/Tasks/femtoCascadeQa.cxx b/PWGCF/Femto/Tasks/femtoCascadeQa.cxx index e7b9eeaa842..63daed2c1a5 100644 --- a/PWGCF/Femto/Tasks/femtoCascadeQa.cxx +++ b/PWGCF/Femto/Tasks/femtoCascadeQa.cxx @@ -41,7 +41,7 @@ using namespace o2::analysis::femto; struct FemtoCascadeQa { - using FemtoCollisions = o2::soa::Join; + using FemtoCollisions = o2::soa::Join; using FilteredFemtoCollisions = o2::soa::Filtered; using FilteredFemtoCollision = FilteredFemtoCollisions::iterator; diff --git a/PWGCF/Femto/Tasks/femtoD0Qa.cxx b/PWGCF/Femto/Tasks/femtoD0Qa.cxx index c1222f52a80..94ee74b0b4a 100644 --- a/PWGCF/Femto/Tasks/femtoD0Qa.cxx +++ b/PWGCF/Femto/Tasks/femtoD0Qa.cxx @@ -41,7 +41,7 @@ using namespace o2::analysis::femto; struct FemtoD0Qa { // setup collisions - using FemtoCollisions = o2::soa::Join; + using FemtoCollisions = o2::soa::Join; using FilteredFemtoCollisions = o2::soa::Filtered; using FilteredFemtoCollision = FilteredFemtoCollisions::iterator; diff --git a/PWGCF/Femto/Tasks/femtoKinkQa.cxx b/PWGCF/Femto/Tasks/femtoKinkQa.cxx index 88c56762db3..f1b456def84 100644 --- a/PWGCF/Femto/Tasks/femtoKinkQa.cxx +++ b/PWGCF/Femto/Tasks/femtoKinkQa.cxx @@ -43,7 +43,7 @@ using namespace o2::analysis::femto; struct FemtoKinkQa { // setup tables - using FemtoCollisions = o2::soa::Join; + using FemtoCollisions = o2::soa::Join; using FilteredFemtoCollisions = o2::soa::Filtered; using FilteredFemtoCollision = FilteredFemtoCollisions::iterator; diff --git a/PWGCF/Femto/Tasks/femtoTrackQa.cxx b/PWGCF/Femto/Tasks/femtoTrackQa.cxx index bdd7de9580a..5a5f081e954 100644 --- a/PWGCF/Femto/Tasks/femtoTrackQa.cxx +++ b/PWGCF/Femto/Tasks/femtoTrackQa.cxx @@ -41,10 +41,14 @@ using namespace o2::analysis::femto; struct FemtoTrackQa { // setup tables - using FemtoCollisions = o2::soa::Join; + using FemtoCollisions = o2::soa::Join; using FilteredFemtoCollisions = o2::soa::Filtered; using FilteredFemtoCollision = FilteredFemtoCollisions::iterator; + using FemtoCollisionsWithEventShape = o2::soa::Join; + using FilteredFemtoCollisionsWithEventShape = o2::soa::Filtered; + using FilteredFemtoCollisionWithEventShape = FilteredFemtoCollisionsWithEventShape::iterator; + using FemtoCollisionsWithLabel = o2::soa::Join; using FilteredFemtoCollisionsWithLabel = o2::soa::Filtered; using FilteredFemtoCollisionWithLabel = FilteredFemtoCollisionsWithLabel::iterator; @@ -83,10 +87,10 @@ struct FemtoTrackQa { void init(o2::framework::InitContext&) { - if ((static_cast(doprocessData) + static_cast(doprocessMc)) > 1) { + if ((static_cast(doprocessData) + static_cast(doprocessMc) + static_cast(doprocessDataWithEventShape)) > 1) { LOG(fatal) << "More than 1 process function is activated. Breaking..."; } - bool processDataFlag = doprocessData; + bool processDataFlag = doprocessData || doprocessDataWithEventShape; trackCleaner.init(confTrackCleaner); std::map> colHistSpec; @@ -134,6 +138,19 @@ struct FemtoTrackQa { } } PROCESS_SWITCH(FemtoTrackQa, processMc, "Track QA in Monte Carlo", false); + + void processDataWithEventShape(FilteredFemtoCollisionWithEventShape const& col, FemtoTracks const& tracks) + { + auto trackSlice = trackPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + if (trackSlice.size() == 0) { + return; + } + colHistManager.fill(col); + for (auto const& track : trackSlice) { + trackHistManager.fill(track, tracks); + } + }; + PROCESS_SWITCH(FemtoTrackQa, processDataWithEventShape, "Track QA in Data with event shape information", false); }; o2::framework::WorkflowSpec diff --git a/PWGCF/Femto/Tasks/femtoTwotrackresonanceQa.cxx b/PWGCF/Femto/Tasks/femtoTwotrackresonanceQa.cxx index 7e22720b6c6..fbb62a1003f 100644 --- a/PWGCF/Femto/Tasks/femtoTwotrackresonanceQa.cxx +++ b/PWGCF/Femto/Tasks/femtoTwotrackresonanceQa.cxx @@ -40,7 +40,7 @@ using namespace o2::analysis::femto; struct FemtoTwotrackresonanceQa { // setup tables - using FemtoCollisions = o2::soa::Join; + using FemtoCollisions = o2::soa::Join; using FemtoCollision = FemtoCollisions::iterator; using FilteredFemtoCollisions = o2::soa::Filtered; diff --git a/PWGCF/Femto/Tasks/femtoV0Qa.cxx b/PWGCF/Femto/Tasks/femtoV0Qa.cxx index ceba51e509d..18e6a485e99 100644 --- a/PWGCF/Femto/Tasks/femtoV0Qa.cxx +++ b/PWGCF/Femto/Tasks/femtoV0Qa.cxx @@ -42,7 +42,7 @@ using namespace o2::analysis::femto; struct FemtoV0Qa { // setup tables - using FemtoCollisions = o2::soa::Join; + using FemtoCollisions = o2::soa::Join; using FilteredFemtoCollisions = o2::soa::Filtered; using FilteredFemtoCollision = FilteredFemtoCollisions::iterator;