From 8d5bb9b3a253861e8edb360e599afd954d1473ab Mon Sep 17 00:00:00 2001 From: Fabrizio Grosa Date: Fri, 28 Nov 2025 17:24:35 +0100 Subject: [PATCH 01/10] Refactory of charm reso derived data creator to improve compilation time --- PWGHF/D2H/Core/DataCreationCharmReso.h | 1543 ++++++++++ PWGHF/D2H/TableProducer/CMakeLists.txt | 14 +- .../dataCreatorCharmResoReduced.cxx | 2721 ----------------- .../dataCreatorCharmResoToD0Reduced.cxx | 777 +++++ .../dataCreatorCharmResoToDplusReduced.cxx | 771 +++++ .../dataCreatorCharmResoToDstarReduced.cxx | 773 +++++ 6 files changed, 3876 insertions(+), 2723 deletions(-) create mode 100644 PWGHF/D2H/Core/DataCreationCharmReso.h delete mode 100644 PWGHF/D2H/TableProducer/dataCreatorCharmResoReduced.cxx create mode 100644 PWGHF/D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx create mode 100644 PWGHF/D2H/TableProducer/dataCreatorCharmResoToDplusReduced.cxx create mode 100644 PWGHF/D2H/TableProducer/dataCreatorCharmResoToDstarReduced.cxx diff --git a/PWGHF/D2H/Core/DataCreationCharmReso.h b/PWGHF/D2H/Core/DataCreationCharmReso.h new file mode 100644 index 00000000000..afb12678053 --- /dev/null +++ b/PWGHF/D2H/Core/DataCreationCharmReso.h @@ -0,0 +1,1543 @@ +// Copyright 2019-2020 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 utilsCharmReso.h +/// \brief utility functions for charm-hadron resonance derived data creators +/// +/// \author Luca Aglietta , UniTO Turin +/// \author Fabrizio Grosa , CERN + +#ifndef PWGHF_D2H_CORE_DATACREATIONCHARMRESO_H_ +#define PWGHF_D2H_CORE_DATACREATIONCHARMRESO_H_ + +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/DecayChannels.h" +#include "PWGHF/Utils/utilsMcMatching.h" +#include "PWGHF/Utils/utilsEvSelHf.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/Core/trackUtilities.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace o2::analysis { + namespace hf_charm_reso { + + // event types + enum Event : uint8_t { + Processed = 0, + NoDV0Selected, + DV0Selected, + kNEvent + }; + + enum BachelorType : uint8_t { + K0s = 0, + Lambda, + AntiLambda, + Track + }; + + enum DType : uint8_t { + Dplus = 1, + Dstar, + D0 + }; + + enum PairingType : uint8_t { + V0Only, + TrackOnly, + V0AndTrack + }; + + enum D0Sel : uint8_t { + SelectedD0 = 0, + SelectedD0Bar + }; + + // Helper structs to pass D and V0 informations + + struct candidateV0 { + std::array pos; + std::array mom; + std::array momPos; + std::array momNeg; + float pT; + float cosPA; + float dcaV0ToPv; + float dcaDau; + float alpha; + float eta; + float radius; + float mK0Short; + float mLambda; + uint8_t v0Type; + }; + + struct varContainer { + float invMassD; + float ptD; + float invMassD0; + float invMassD0Bar; + float invMassReso; + float ptReso; + int8_t signD; + std::array pVectorProng0; + std::array pVectorProng1; + std::array pVectorProng2; + }; + + /// Basic track quality selections for V0 daughters + /// \param Tr is a track + /// \param dDaughtersIds are the IDs of the D meson daughter tracks + /// \param cfgV0Cuts are the cuts to be applied to the V0 + /// \param rejectPairsWithCommonDaughter is a flag to activate rejection of pairs sharing a daughter track + template + bool selectV0Daughter(Tr const& track, const std::array& dDaughtersIds, const Cuts& cfgV0Cuts, bool rejectPairsWithCommonDaughter) + { + // acceptance selection + if (std::abs(track.eta()) > cfgV0Cuts.etaMaxDau.value) { + return false; + } + // Tpc Refit + if (!(track.hasTPC())) { + return false; + } + // track quality selection + if (track.itsNCls() < cfgV0Cuts.trackNclusItsCut.value || + track.tpcNClsFound() < cfgV0Cuts.trackNCrossedRowsTpc.value || + track.tpcNClsCrossedRows() < cfgV0Cuts.trackNCrossedRowsTpc.value || + track.tpcNClsCrossedRows() < cfgV0Cuts.trackFracMaxindableTpcCls.value * track.tpcNClsFindable() || + track.tpcNClsShared() > cfgV0Cuts.trackNsharedClusTpc.value) { + return false; + } + // rejection of tracks that share a daughter with the D meson + if (rejectPairsWithCommonDaughter && std::find(dDaughtersIds.begin(), dDaughtersIds.end(), track.globalIndex()) != dDaughtersIds.end()) { + return false; + } + return true; + } + + /// Utility to find which v0 daughter carries the largest fraction of the mother longitudinal momentum + /// \param momV0 is the momentum of the V0 + /// \param momDau0 is the momentum of first daughter + /// \param momDau1 is the momentum of second daughter + /// \return alphaAP + float alphaAP(std::array const& momV0, std::array const& momDau0, std::array const& momDau1) + { + float const momTot = std::sqrt(std::pow(momV0[0], 2.) + std::pow(momV0[1], 2.) + std::pow(momV0[2], 2.)); + float const lQlPos = (momDau0[0] * momV0[0] + momDau0[1] * momV0[1] + momDau0[2] * momV0[2]) / momTot; + float const lQlNeg = (momDau1[0] * momV0[0] + momDau1[1] * momV0[1] + momDau1[2] * momV0[2]) / momTot; + return (lQlPos - lQlNeg) / (lQlPos + lQlNeg); + } + + /// Utility to find DCA of V0 to Primary vertex + /// \param x is the x-coordinate + /// \param y is the y-coordinate + /// \param z is the z-coordinate + /// \param px is the x-component of the momentum + /// \param py is the y-component of the momentum + /// \param pz is the z-component of the momentum + /// \param pvX is the x-coordinate of the PV + /// \param pvY is the y-coordinate of the PV + /// \param pvZ is the z-coordinate of the PV + /// \return the DCA + float calculateDCAStraightToPV(float x, float y, float z, float px, float py, float pz, float pvX, float pvY, float pvZ) + { + return std::sqrt((std::pow((pvY - y) * pz - (pvZ - z) * py, 2) + std::pow((pvX - x) * pz - (pvZ - z) * px, 2) + std::pow((pvX - x) * py - (pvY - y) * px, 2)) / (px * px + py * py + pz * pz)); + } + + /// Basic selection of V0 candidates + /// \param collision is the current collision + /// \param dauTracks are the v0 daughter tracks + /// \param dDaughtersIds are the IDs of the D meson daughter tracks + /// \param fitter is the DCAFitter object + /// \param cfgV0Cuts are the cuts to be applied to the V0 + /// \param v0 is the V0 candidate + /// \param rejectPairsWithCommonDaughter is a flag to activate rejection of pairs sharing a daughter track + /// \return a bitmap with mass hypotesis if passes all cuts + template + bool buildAndSelectV0(const Coll& collision, const std::array& dDaughtersIds, const std::array& dauTracks, const Cuts& cfgV0Cuts, o2::vertexing::DCAFitterN<2>& fitter, candidateV0& v0, bool rejectPairsWithCommonDaughter) + { + const auto& trackPos = dauTracks[0]; + const auto& trackNeg = dauTracks[1]; + // single-tracks selection + if (!selectV0Daughter(trackPos, dDaughtersIds, cfgV0Cuts, rejectPairsWithCommonDaughter) || !selectV0Daughter(trackNeg, dDaughtersIds, cfgV0Cuts, rejectPairsWithCommonDaughter)) { + return false; + } + // daughters DCA to V0's collision primary vertex + std::array dcaInfo{}; + auto trackPosPar = getTrackPar(trackPos); + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackPosPar, 2.f, fitter.getMatCorrType(), &dcaInfo); + auto trackPosDcaXY = dcaInfo[0]; + auto trackNegPar = getTrackPar(trackNeg); + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackNegPar, 2.f, fitter.getMatCorrType(), &dcaInfo); + auto trackNegDcaXY = dcaInfo[0]; + if (std::fabs(trackPosDcaXY) < cfgV0Cuts.dcaMaxDauToPv.value || std::fabs(trackNegDcaXY) < cfgV0Cuts.dcaMaxDauToPv.value) { + return false; + } + // vertex reconstruction + auto trackPosCov = getTrackParCov(trackPos); + auto trackNegCov = getTrackParCov(trackNeg); + int nCand = 0; + try { + nCand = fitter.process(trackPosCov, trackNegCov); + } catch (...) { + return false; + } + if (nCand == 0) { + return false; + } + // compute candidate momentum from tracks propagated to decay vertex + auto& trackPosProp = fitter.getTrack(0); + auto& trackNegProp = fitter.getTrack(1); + trackPosProp.getPxPyPzGlo(v0.momPos); + trackNegProp.getPxPyPzGlo(v0.momNeg); + + v0.mom = RecoDecay::pVec(v0.momPos, v0.momNeg); + + v0.pT = std::hypot(v0.mom[0], v0.mom[1]); + // topological selections: + // v0 eta + v0.eta = RecoDecay::eta(v0.mom); + if (std::abs(v0.eta) > cfgV0Cuts.etaMax.value) { + return false; + } + // daughters DCA + v0.dcaDau = std::sqrt(fitter.getChi2AtPCACandidate()); + if (v0.dcaDau > cfgV0Cuts.dcaDau.value) { + return false; + } + // v0 radius + const auto& vtx = fitter.getPCACandidate(); + v0.radius = std::hypot(vtx[0], vtx[1]); + if (v0.radius < cfgV0Cuts.radiusMin.value) { + return false; + } + std::copy(vtx.begin(), vtx.end(), v0.pos.begin()); + + // v0 DCA to primary vertex + v0.dcaV0ToPv = calculateDCAStraightToPV( + vtx[0], vtx[1], vtx[2], + v0.momPos[0] + v0.momNeg[0], + v0.momPos[1] + v0.momNeg[1], + v0.momPos[2] + v0.momNeg[2], + collision.posX(), collision.posY(), collision.posZ()); + if (std::abs(v0.dcaV0ToPv) > cfgV0Cuts.dcaPv.value) { + return false; + } + // v0 cosine of pointing angle + std::array const primVtx = {collision.posX(), collision.posY(), collision.posZ()}; + v0.cosPA = RecoDecay::cpa(primVtx, vtx, v0.mom); + if (v0.cosPA < cfgV0Cuts.cosPa.value) { + return false; + } + // distinguish between K0s, and Lambda hypotesys + v0.v0Type = {BIT(BachelorType::K0s) | BIT(BachelorType::Lambda) | BIT(BachelorType::AntiLambda)}; + // for lambda hypotesys define if its lambda or anti-lambda + v0.alpha = alphaAP(v0.mom, v0.momPos, v0.momNeg); + bool const matter = v0.alpha > 0; + CLRBIT(v0.v0Type, matter ? BachelorType::AntiLambda : BachelorType::Lambda); + auto massPos = matter ? o2::constants::physics::MassProton : o2::constants::physics::MassPionCharged; + auto massNeg = matter ? o2::constants::physics::MassPionCharged : o2::constants::physics::MassProton; + // mass hypotesis + v0.mLambda = RecoDecay::m(std::array{v0.momPos, v0.momNeg}, std::array{massPos, massNeg}); + v0.mK0Short = RecoDecay::m(std::array{v0.momPos, v0.momNeg}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged}); + if (std::fabs(v0.mK0Short - o2::constants::physics::MassK0) > cfgV0Cuts.deltaMassK0s.value) { + CLRBIT(v0.v0Type, BachelorType::K0s); + } + if (std::fabs(v0.mLambda - o2::constants::physics::MassLambda0) > cfgV0Cuts.deltaMassLambda.value) { + CLRBIT(v0.v0Type, BachelorType::Lambda); + CLRBIT(v0.v0Type, BachelorType::AntiLambda); + } + // PID + if (TESTBIT(v0.v0Type, BachelorType::K0s)) { + if ((trackPos.hasTPC() && std::fabs(trackPos.tpcNSigmaPi()) > cfgV0Cuts.nSigmaTpc.value) || + (trackNeg.hasTPC() && std::fabs(trackNeg.tpcNSigmaPi()) > cfgV0Cuts.nSigmaTpc.value)) { + CLRBIT(v0.v0Type, BachelorType::K0s); + } + } + if (TESTBIT(v0.v0Type, BachelorType::Lambda)) { + if ((trackPos.hasTPC() && std::fabs(trackPos.tpcNSigmaPr()) > cfgV0Cuts.nSigmaTpc.value) || + (trackPos.hasTOF() && std::fabs(trackPos.tofNSigmaPr()) > cfgV0Cuts.nSigmaTofPr.value) || + (trackNeg.hasTPC() && std::fabs(trackNeg.tpcNSigmaPi()) > cfgV0Cuts.nSigmaTpc.value)) { + CLRBIT(v0.v0Type, BachelorType::Lambda); + } + } + if (TESTBIT(v0.v0Type, BachelorType::AntiLambda)) { + if ((trackPos.hasTPC() && std::fabs(trackPos.tpcNSigmaPi()) > cfgV0Cuts.nSigmaTpc.value) || + (trackNeg.hasTPC() && std::fabs(trackNeg.tpcNSigmaPr()) > cfgV0Cuts.nSigmaTpc.value) || + (trackNeg.hasTOF() && std::fabs(trackNeg.tofNSigmaPr()) > cfgV0Cuts.nSigmaTofPr.value)) { + CLRBIT(v0.v0Type, BachelorType::AntiLambda); + } + } + if (v0.v0Type == 0) { + return false; + } + return true; + } + + /// Basic selection of tracks + /// \param track is the track + /// \param dDaughtersIds are the IDs of the D meson daughter tracks + /// \param cfgV0Cuts are the cuts to be applied to the track + /// \param rejectPairsWithCommonDaughter is a flag to activate rejection of pairs sharing a daughter track + /// \return true if passes all cuts + template + bool isTrackSelected(const Tr& track, const std::array& dDaughtersIds, const Cuts& cfgSingleTrackCuts, bool rejectPairsWithCommonDaughter) + { + if (rejectPairsWithCommonDaughter && std::find(dDaughtersIds.begin(), dDaughtersIds.end(), track.globalIndex()) != dDaughtersIds.end()) { + return false; + } + switch (cfgSingleTrackCuts.setTrackSelections.value) { + case 1: + if (!track.isGlobalTrackWoDCA()) { + return false; + } + break; + case 2: + if (!track.isGlobalTrack()) { + return false; + } + break; + case 3: + if (!track.isQualityTrackITS()) { + return false; + } + break; + } + if (track.pt() < cfgSingleTrackCuts.minPt.value) { + return false; + } + if (std::abs(track.eta()) > cfgSingleTrackCuts.maxEta.value) { + return false; + } + if (!track.hasTPC()) { + return false; + } + bool const isPion = std::abs(track.tpcNSigmaPi()) < cfgSingleTrackCuts.maxNsigmaTpcPi.value; + bool const isKaon = std::abs(track.tpcNSigmaKa()) < cfgSingleTrackCuts.maxNsigmaTpcKa.value; + bool const isProton = std::abs(track.tpcNSigmaPr()) < cfgSingleTrackCuts.maxNsigmaTpcPr.value; + return (isPion || isKaon || isProton); // we keep the track if is it compatible with at least one of the PID hypotheses selected + } + + /// Matching of V0 candidates to MC truth + /// \param particlesMc is the table of MC particles + /// \param arrDaughtersV0 is the array of V0 daughter tracks + /// \return the MC matching flag for the V0 + template + int8_t getMatchingFlagV0(PParticles const& particlesMc, const std::array& arrDaughtersV0) + { + int8_t signV0{0}; + int indexRec{-1}; + int flagV0{0}; + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersV0, kK0, std::array{+kPiPlus, -kPiPlus}, true, &signV0, 2); + if (indexRec > -1) { + flagV0 = hf_decay::hf_cand_reso::PartialMatchMc::K0Matched; + } else { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersV0, kLambda0, std::array{+kProton, -kPiPlus}, true, &signV0, 2); + if (indexRec > -1) { + flagV0 = signV0 * hf_decay::hf_cand_reso::PartialMatchMc::LambdaMatched; + } + } + return flagV0; // Placeholder, should return the actual flag based on matching logic + } + + /// Matching of V0 candidates to MC truth + /// \param bachTrack is the track + /// \return the MC matching flag for the track + template + int8_t getMatchingFlagTrack(Tr const& bachTrack) + { + auto particle = bachTrack.mcParticle(); + auto pdgCode = std::abs(particle.pdgCode()); + if (pdgCode == kPiPlus) { + return hf_decay::hf_cand_reso::PartialMatchMc::PionMatched; + } + if (pdgCode == kKPlus) { + return hf_decay::hf_cand_reso::PartialMatchMc::KaonMatched; + } + if (pdgCode == kProton) { + return hf_decay::hf_cand_reso::PartialMatchMc::ProtonMatched; + } + return 0; + } + + /// Matching of V0 candidates to MC truth + /// \param particlesMc is the table of MC particles + /// \param indexRec is the index of the MC particle associated to the reconstructed canditate + /// \param pdg is the O2DatabasePDG service + /// \return the generated invariant mass + template + float computeInvMassGen(PParticles const& particlesMc, int indexRec, o2::framework::Service const& pdg) + { + if (indexRec < 0) { + return -1.f; + } + auto particleReso = particlesMc.iteratorAt(indexRec); + auto dau1 = particlesMc.iteratorAt(particleReso.daughtersIds().front()); + auto dau2 = particlesMc.iteratorAt(particleReso.daughtersIds().back()); + std::array, 2> pArr = {{{dau1.px(), dau1.py(), dau1.pz()}, {dau2.px(), dau2.py(), dau2.pz()}}}; + std::array mArr = {static_cast(pdg->Mass(dau1.pdgCode())), static_cast(pdg->Mass(dau2.pdgCode()))}; + return static_cast(RecoDecay::m(pArr, mArr)); + } + + /// Function for filling MC reco information of DV0 candidates in the tables + /// \tparam dType is the D meson type (Dstar, Dplus or D0) + /// \param particlesMc is the table with MC particles + /// \param candCharmBach is the D meson candidate + /// \param bachelorV0 is the V0 candidate + /// \param tracks is the table with tracks + /// \param indexHfCandCharm is the index of the charm-hadron bachelor in the reduced table + /// \param indexCandV0TrBach is the index of the v0 bachelor in the reduced table + /// \param pdg is the O2DatabasePDG service + /// \param registry is the histogram registry + /// \param rowMcRecReduced is the table to be filled + template + void fillMcRecoInfoDV0(PParticles const& particlesMc, + CCand const& candCharmBach, + BBachV0 const& bachelorV0, + Tr const& tracks, + int64_t& indexHfCandCharm, + int64_t& indexCandV0Bach, + o2::framework::Service const& pdg, + o2::framework::HistogramRegistry& registry, + Table& rowMcRecReduced) + { + std::vector vecDaughtersReso{}; + int8_t sign{0}, nKinkedTracks{0}, origin{0}, flagCharmBach{0}, flagCharmBachInterm{0}, flagV0{0}, flagReso{0}; + int indexRec{-1}, debugMcRec{0}; + float ptGen{-1.f}, invMassGen{-1.f}; + if constexpr (DType == DType::Dstar) { + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prongPiId())); + // Check if D* is matched + flagCharmBach = candCharmBach.flagMcMatchRec(); + if (flagCharmBach != 0) { + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::DstarMatched); + origin = candCharmBach.originMcRec(); + } + // Check if D0 is matched + flagCharmBachInterm = candCharmBach.flagMcMatchRecD0(); + if (flagCharmBachInterm != 0) { + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::D0Matched); + } + // Check if V0 is matched + vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.posTrackId())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.negTrackId())); + flagV0 = getMatchingFlagV0(particlesMc, std::array{vecDaughtersReso[3], vecDaughtersReso[4]}); + if (flagV0 != 0) { + SETBIT(debugMcRec, std::abs(flagV0)); + } + // If both D* and K0s are matched, try to match resonance + if (flagCharmBach != 0 && flagV0 == hf_decay::hf_cand_reso::PartialMatchMc::K0Matched) { + std::array const pdgCodesDaughters = {+kPiPlus, -kKPlus, +kPiPlus, +kPiPlus, -kPiPlus}; + auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], vecDaughtersReso[3], vecDaughtersReso[4]}; + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarK0s) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; + break; + } + } + } else if (flagCharmBachInterm != 0 && flagV0 == hf_decay::hf_cand_reso::PartialMatchMc::K0Matched) { + std::array const pdgCodesDaughters = {+kPiPlus, -kKPlus, +kPiPlus, -kPiPlus}; + auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[3], vecDaughtersReso[4]}; + // Peaking background of D0K0s <- Ds* with spurious soft pion + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarK0s) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::ResoPartlyMatched); + break; + } + } + } + // No physical channel expected in D*Lambda + if (indexRec > -1) { + auto particleReso = particlesMc.iteratorAt(indexRec); + ptGen = particleReso.pt(); + invMassGen = computeInvMassGen(particlesMc, indexRec, pdg); + } + rowMcRecReduced(indexHfCandCharm, indexCandV0Bach, + flagReso, flagCharmBach, + flagCharmBachInterm, debugMcRec, + origin, ptGen, invMassGen, + nKinkedTracks); + } else if constexpr (DType == DType::Dplus) { + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong2Id())); + // Check if D+ is matched + flagCharmBach = candCharmBach.flagMcMatchRec(); + flagCharmBachInterm = candCharmBach.flagMcDecayChanRec(); + if (flagCharmBach != 0) { + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::DplusMatched); + origin = candCharmBach.originMcRec(); + } + // Check if V0 is matched + vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.posTrackId())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.negTrackId())); + flagV0 = getMatchingFlagV0(particlesMc, std::array{vecDaughtersReso[3], vecDaughtersReso[4]}); + if (flagV0 != 0) { + SETBIT(debugMcRec, std::abs(flagV0)); + } + // If both D+ and K0s are matched, try to match resonance + if (hf_decay::hf_cand_3prong::daughtersDplusMain.contains(static_cast(std::abs(flagCharmBach))) && flagV0 == hf_decay::hf_cand_reso::PartialMatchMc::K0Matched) { + auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], vecDaughtersReso[3], vecDaughtersReso[4]}; + auto pdgCodesDplusDaughters = hf_decay::hf_cand_3prong::daughtersDplusMain.at(static_cast(std::abs(flagCharmBach))); + auto pdgCodesDaughters = std::array{pdgCodesDplusDaughters[0], pdgCodesDplusDaughters[1], pdgCodesDplusDaughters[2], +kPiPlus, -kPiPlus}; + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusK0s) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; + break; + } + } + // Partial matching of Dsj -> D*K0s -> (D+ pi0) (K0s) with missing neutral + if (indexRec < 0) { + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarK0s) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::ResoPartlyMatched); + break; + } + } + } + + } else if (hf_decay::hf_cand_3prong::daughtersDplusMain.contains(static_cast(std::abs(flagCharmBach))) && std::abs(flagV0) == hf_decay::hf_cand_reso::PartialMatchMc::LambdaMatched) { + // Peaking background of D+Lambda <- Ds* with spurious soft pion + auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], vecDaughtersReso[3], vecDaughtersReso[4]}; + auto pdgCodesDplusDaughters = hf_decay::hf_cand_3prong::daughtersDplusMain.at(static_cast(std::abs(flagCharmBach))); + auto pdgCodesDaughters = std::array{pdgCodesDplusDaughters[0], pdgCodesDplusDaughters[1], pdgCodesDplusDaughters[2], +kProton, -kPiPlus}; + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusLambda) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; + break; + } + } + } + if (indexRec > -1) { + auto particleReso = particlesMc.iteratorAt(indexRec); + ptGen = particleReso.pt(); + invMassGen = computeInvMassGen(particlesMc, indexRec, pdg); + } + rowMcRecReduced(indexHfCandCharm, indexCandV0Bach, + flagReso, flagCharmBach, + flagCharmBachInterm, debugMcRec, + origin, ptGen, invMassGen, + nKinkedTracks); + } else if constexpr (DType == DType::D0) { + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); + // Check if D0 is matched + flagCharmBach = candCharmBach.flagMcMatchRec(); + flagCharmBachInterm = candCharmBach.flagMcDecayChanRec(); + if (flagCharmBach != 0) { + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::D0Matched); + origin = candCharmBach.originMcRec(); + } + // Check if V0 is matched + vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.posTrackId())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.negTrackId())); + flagV0 = getMatchingFlagV0(particlesMc, std::array{vecDaughtersReso[2], vecDaughtersReso[3]}); + if (flagV0 != 0) { + SETBIT(debugMcRec, std::abs(flagV0)); + } + // No physical channel expected in D0 K0s + // If both D0 and Lambda are matched, try to match resonance + if (hf_decay::hf_cand_2prong::daughtersD0Main.contains(static_cast(std::abs(flagCharmBach))) && std::abs(flagV0) == hf_decay::hf_cand_reso::PartialMatchMc::LambdaMatched) { + auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], vecDaughtersReso[3]}; + auto pdgCodesDzeroDaughters = hf_decay::hf_cand_2prong::daughtersD0Main.at(static_cast(std::abs(flagCharmBach))); + auto pdgCodesDaughters = std::array{pdgCodesDzeroDaughters[0], pdgCodesDzeroDaughters[1], +kProton, -kPiPlus}; + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Lambda) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; + break; + } + } + } + if (indexRec > -1) { + auto particleReso = particlesMc.iteratorAt(indexRec); + ptGen = particleReso.pt(); + invMassGen = computeInvMassGen(particlesMc, indexRec, pdg); + } + rowMcRecReduced(indexHfCandCharm, indexCandV0Bach, + flagReso, flagCharmBach, + flagCharmBachInterm, debugMcRec, + origin, ptGen, invMassGen, + nKinkedTracks); + } + registry.fill(HIST("hMCRecDebug"), debugMcRec); + if (indexRec > -1) { + registry.fill(HIST("hMCRecCounter"), flagReso); + registry.fill(HIST("hMCRecOrigin"), origin); + registry.fill(HIST("hMCRecMassGen"), invMassGen); + } + if (flagCharmBach != 0) { + registry.fill(HIST("hMCRecCharmDau"), flagCharmBach); + } + } + + // Function for filling MC reco information of D Track candidates in the tables + /// \tparam dType is the D meson type (Dstar, Dplus or D0) + /// \param particlesMc is the table with MC particles + /// \param candCharmBach is the D meson candidate + /// \param bachelorTrack is the bachelor track + /// \param tracks is the table with tracks + /// \param indexHfCandCharm is the index of the charm-hadron bachelor in the reduced table + /// \param indexCandTrBach is the index of the v0 bachelor in the reduced table + /// \param pdg is the O2DatabasePDG service + /// \param registry is the histogram registry + /// \param rowMcRecReduced is the table to be filled + template + void fillMcRecoInfoDTrack(PParticles const& particlesMc, + CCand const& candCharmBach, + BBachTr const& bachelorTrack, + Tr const& tracks, + const int64_t indexHfCandCharm, + const int64_t indexCandTrBach, + o2::framework::Service const& pdg, + o2::framework::HistogramRegistry& registry, + Table& rowMcRecReduced) + { + std::vector vecDaughtersReso{}; + int8_t sign{0}, nKinkedTracks{0}, origin{0}, flagCharmBach{0}, flagCharmBachInterm{0}, flagTrack{0}, flagReso{0}; + int indexRec{-1}; + uint16_t debugMcRec{0}; + float ptGen{-1.f}, invMassGen{-1.f}; + if constexpr (DType == DType::Dstar) { + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prongPiId())); + // Check if D* is matched + flagCharmBach = candCharmBach.flagMcMatchRec(); + if (flagCharmBach != 0) { + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::DstarMatched); + origin = candCharmBach.originMcRec(); + } + // Check if D0 is matched + flagCharmBachInterm = candCharmBach.flagMcMatchRecD0(); + if (flagCharmBachInterm != 0) { + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::D0Matched); + } + // Check if Track is matched + flagTrack = getMatchingFlagTrack(bachelorTrack); + if (flagTrack != 0) { + SETBIT(debugMcRec, flagTrack); + } + // If both D* and Track are matched, try to match resonance + if (flagCharmBach != 0 && flagTrack == hf_decay::hf_cand_reso::PartialMatchMc::PionMatched) { + auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], bachelorTrack}; + auto pdgCodesDaughters = std::array{+kPiPlus, -kKPlus, +kPiPlus, -kPiPlus}; + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarPi) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; + break; + } + } + } + // No channels in D*K+ or D*Pr + if (indexRec > -1) { + auto particleReso = particlesMc.iteratorAt(indexRec); + ptGen = particleReso.pt(); + invMassGen = computeInvMassGen(particlesMc, indexRec, pdg); + } + rowMcRecReduced(indexHfCandCharm, indexCandTrBach, + flagReso, flagCharmBach, + flagCharmBachInterm, debugMcRec, + origin, ptGen, invMassGen, + nKinkedTracks); + } else if constexpr (DType == DType::Dplus) { + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong2Id())); + // Check if D+ is matched + flagCharmBach = candCharmBach.flagMcMatchRec(); + flagCharmBachInterm = candCharmBach.flagMcDecayChanRec(); + if (flagCharmBach != 0) { + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::DplusMatched); + origin = candCharmBach.originMcRec(); + } + // Check if Track is matched + flagTrack = getMatchingFlagTrack(bachelorTrack); + if (flagTrack != 0) { + SETBIT(debugMcRec, flagTrack); + } + // If both D+ and Track are matched, try to match resonance + if (hf_decay::hf_cand_3prong::daughtersDplusMain.contains(static_cast(std::abs(flagCharmBach))) && flagTrack == hf_decay::hf_cand_reso::PartialMatchMc::PionMatched) { + auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], bachelorTrack}; + auto pdgCodesDplusDaughters = hf_decay::hf_cand_3prong::daughtersDplusMain.at(static_cast(std::abs(flagCharmBach))); + auto pdgCodesDaughters = std::array{pdgCodesDplusDaughters[0], pdgCodesDplusDaughters[1], pdgCodesDplusDaughters[2], -kPiPlus}; + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusPi) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; + break; + } + } + // Partial matching of Dj -> D*Pi -> (D+ pi0) (pi) with missing neutral + if (indexRec < 0) { + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarPi) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::ResoPartlyMatched); + break; + } + } + } + } + // No channels in D+K+ or D+Pr + if (indexRec > -1) { + auto particleReso = particlesMc.iteratorAt(indexRec); + ptGen = particleReso.pt(); + invMassGen = computeInvMassGen(particlesMc, indexRec, pdg); + } + rowMcRecReduced(indexHfCandCharm, indexCandTrBach, + flagReso, flagCharmBach, + flagCharmBachInterm, debugMcRec, + origin, ptGen, invMassGen, + nKinkedTracks); + } else if constexpr (DType == DType::D0) { + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); + // Check if D0 is matched + flagCharmBach = candCharmBach.flagMcMatchRec(); + flagCharmBachInterm = candCharmBach.flagMcDecayChanRec(); + if (flagCharmBach != 0) { + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::D0Matched); + origin = candCharmBach.originMcRec(); + } + flagTrack = getMatchingFlagTrack(bachelorTrack); + if (flagTrack != 0) { + SETBIT(debugMcRec, flagTrack); + } + if (hf_decay::hf_cand_2prong::daughtersD0Main.contains(static_cast(std::abs(flagCharmBach))) && flagTrack == hf_decay::hf_cand_reso::PartialMatchMc::PionMatched) { + auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], bachelorTrack}; + auto pdgCodesDzeroDaughters = hf_decay::hf_cand_2prong::daughtersD0Main.at(static_cast(std::abs(flagCharmBach))); + auto pdgCodesDaughters = std::array{pdgCodesDzeroDaughters[0], pdgCodesDzeroDaughters[1], +kPiPlus}; + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Pi) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; + break; + } + } + // Partial matching of Dj -> D*Pi -> (D0 pi) (pi) with missing pion + if (indexRec < 0) { + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarPi) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::ResoPartlyMatched); + break; + } + } + } + } else if (hf_decay::hf_cand_2prong::daughtersD0Main.contains(static_cast(std::abs(flagCharmBach))) && flagTrack == hf_decay::hf_cand_reso::PartialMatchMc::KaonMatched) { + auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], bachelorTrack}; + auto pdgCodesDzeroDaughters = hf_decay::hf_cand_2prong::daughtersD0Main.at(static_cast(std::abs(flagCharmBach))); + auto pdgCodesDaughters = std::array{pdgCodesDzeroDaughters[0], pdgCodesDzeroDaughters[1], +kKPlus}; + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Kplus) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; + break; + } + } + } + if (indexRec > -1) { + auto particleReso = particlesMc.iteratorAt(indexRec); + ptGen = particleReso.pt(); + invMassGen = computeInvMassGen(particlesMc, indexRec, pdg); + } + rowMcRecReduced(indexHfCandCharm, indexCandTrBach, + flagReso, flagCharmBach, + flagCharmBachInterm, debugMcRec, + origin, ptGen, invMassGen, + nKinkedTracks); + } + registry.fill(HIST("hMCRecDebug"), debugMcRec); + if (indexRec > -1) { + registry.fill(HIST("hMCRecCounter"), flagReso); + registry.fill(HIST("hMCRecOrigin"), origin); + registry.fill(HIST("hMCRecMassGen"), invMassGen); + } + if (flagCharmBach != 0) { + registry.fill(HIST("hMCRecCharmDau"), flagCharmBach); + } + } // fillMcRecoInfoDTrack + + // Function for derived data creation + /// \tparam dType is the D meson type (Dstar, Dplus or D0) + /// \param collision is the current collision + /// \param candsD are the D meson candidates in the current collision + /// \param bachelorV0s are the V0 candidates in the current collision + /// \param bachelorTrks are the track ids in the current collision + /// \param tracks is the track table + /// \param tracksIU is the trackIU table + /// \param particlesMc is the MC particle table + /// \param hfRejMap is the event rejection map from the HF event selection util + /// \param pdg is the O2DatabasePDG service + /// \param registry is the histogram registry + /// \param matCorr is the material correction type to be used in the track propagation + /// \param fitter is the DCAFitter object + /// \param rejectPairsWithCommonDaughter is a flag to activate rejection of pairs sharing a daughter track + /// \param rowCollisionReduced is the collision reduced table to be filled + /// \param rowCandDmesReduced is the D-meson reduced table to be filled + /// \param rowCandV0Reduced is the V0 reduced table to be filled + /// \param rowTrkReduced is the track reduced table to be filled + /// \param rowMcRecV0Reduced is the MC reco D-V0 reduced table to be filled + /// \param rowMcRecTrkReduced is the MC reco D-track reduced table to be filled + /// \param rowCandDmesMlReduced is the ML reduced table to be filled + template + void runDataCreation(Coll const& collision, + CCands const& candsD, + BBachV0s const& bachelorV0s, + BBachTracks const& bachelorTrks, + Tr const& tracks, + TrIU const& tracksIU, + PParticles const& particlesMc, + o2::hf_evsel::HfCollisionRejectionMask hfRejMap, + const float bz, + o2::framework::Service const& pdg, + o2::framework::HistogramRegistry& registry, + o2::base::Propagator::MatCorrType const& matCorr, + o2::vertexing::DCAFitterN<2>& fitter, + DmesCuts const& cfgDmesCuts, + TrkCuts const& cfgSingleTrackCuts, + V0Cuts const& cfgV0Cuts, + QaConfig const& cfgQaPlots, + bool rejectPairsWithCommonDaughter, + TableCollRed& rowCollisionReduced, + TableCandDRed& rowCandDmesReduced, + TableCandV0Red& rowCandV0Reduced, + TableTrkRed& rowTrkReduced, + TableMcRecV0Red& rowMcRecV0Reduced, + TableMcRecTrkRed& rowMcRecTrkReduced, + TableCandDMlRed& rowCandDmesMlReduced) + { + int const indexHfReducedCollision = rowCollisionReduced.lastIndex() + 1; + // std::map where the key is the V0.globalIndex() and + // the value is the V0 index in the table of the selected v0s + std::map selectedV0s; + std::map selectedTracks; + bool fillHfReducedCollision = false; + constexpr bool DoTracks = PairingType == PairingType::TrackOnly || PairingType == PairingType::V0AndTrack; + constexpr bool DoV0s = PairingType == PairingType::V0Only || PairingType == PairingType::V0AndTrack; + // loop on D candidates + for (const auto& candD : candsD) { + // initialize variables depending on D meson type + bool fillHfCandD = false; + std::array secondaryVertexD{}; + std::array prongIdsD{}; + std::array bdtScores = {-1.f, -1.f, -1.f, -1.f, -1.f, -1.f}; + std::vector> charmHadDauTracks{}; + varContainer varUtils; + varUtils.ptD = candD.pt(); + if constexpr (DType == DType::Dstar) { + varUtils.signD = candD.signSoftPi(); + if (varUtils.signD > 0) { + varUtils.invMassD = candD.invMassDstar(); + varUtils.invMassD0 = candD.invMassD0(); + } else { + varUtils.invMassD = candD.invMassAntiDstar(); + varUtils.invMassD0 = candD.invMassD0Bar(); + } + secondaryVertexD[0] = candD.xSecondaryVertexD0(); + secondaryVertexD[1] = candD.ySecondaryVertexD0(); + secondaryVertexD[2] = candD.zSecondaryVertexD0(); + prongIdsD[0] = candD.prong0Id(); + prongIdsD[1] = candD.prong1Id(); + prongIdsD[2] = candD.prongPiId(); + varUtils.pVectorProng0 = candD.pVectorProng0(); + varUtils.pVectorProng1 = candD.pVectorProng1(); + varUtils.pVectorProng2 = candD.pVecSoftPi(); + charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong0Id())); + charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong1Id())); + if constexpr (WithMl) { + std::copy(candD.mlProbDstarToD0Pi().begin(), candD.mlProbDstarToD0Pi().end(), bdtScores.begin()); + } + registry.fill(HIST("hMassVsPtDstarAll"), varUtils.ptD, varUtils.invMassD - varUtils.invMassD0); + } else if constexpr (DType == DType::Dplus) { + auto prong0 = tracksIU.rawIteratorAt(candD.prong0Id()); + varUtils.invMassD = HfHelper::invMassDplusToPiKPi(candD); + secondaryVertexD[0] = candD.xSecondaryVertex(); + secondaryVertexD[1] = candD.ySecondaryVertex(); + secondaryVertexD[2] = candD.zSecondaryVertex(); + prongIdsD[0] = candD.prong0Id(); + prongIdsD[1] = candD.prong1Id(); + prongIdsD[2] = candD.prong2Id(); + varUtils.signD = prong0.sign(); + varUtils.pVectorProng0 = candD.pVectorProng0(); + varUtils.pVectorProng1 = candD.pVectorProng1(); + varUtils.pVectorProng2 = candD.pVectorProng2(); + charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong0Id())); + charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong1Id())); + charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong2Id())); + if constexpr (WithMl) { + std::copy(candD.mlProbDplusToPiKPi().begin(), candD.mlProbDplusToPiKPi().end(), bdtScores.begin()); + } + registry.fill(HIST("hMassVsPtDplusAll"), varUtils.ptD, varUtils.invMassD); + } else if constexpr (DType == DType::D0) { + varUtils.invMassD0 = HfHelper::invMassD0ToPiK(candD); + varUtils.invMassD0Bar = HfHelper::invMassD0barToKPi(candD); + secondaryVertexD[0] = candD.xSecondaryVertex(); + secondaryVertexD[1] = candD.ySecondaryVertex(); + secondaryVertexD[2] = candD.zSecondaryVertex(); + prongIdsD[0] = candD.prong0Id(); + prongIdsD[1] = candD.prong1Id(); + prongIdsD[2] = -1; // D0 does not have a third prong + charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong0Id())); + charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong1Id())); + varUtils.pVectorProng0 = candD.pVectorProng0(); + varUtils.pVectorProng1 = candD.pVectorProng1(); + varUtils.pVectorProng2 = {0.f, 0.f, 0.f}; // D0 does not have a third prong + if constexpr (WithMl) { + std::copy(candD.mlProbD0().begin(), candD.mlProbD0().end(), bdtScores.begin()); + std::copy(candD.mlProbD0bar().begin(), candD.mlProbD0bar().end(), bdtScores.begin() + 3); + } + if (candD.isSelD0() >= cfgDmesCuts.selectionFlagD0.value) { + registry.fill(HIST("hMassVsPtD0All"), varUtils.ptD, varUtils.invMassD0); + } + if (candD.isSelD0bar() >= cfgDmesCuts.selectionFlagD0Bar.value) { + registry.fill(HIST("hMassVsPtD0BarAll"), varUtils.ptD, varUtils.invMassD0Bar); + } + } // end of dType switch + + // Get single track variables + float chi2TpcDauMax = -1.f; + int nItsClsDauMin = 8, nTpcCrossRowsDauMin = 200; + float chi2TpcSoftPi = -1.f; + int nItsClsSoftPi = 8, nTpcCrossRowsSoftPi = 200; + for (const auto& charmHadTrack : charmHadDauTracks) { + if (charmHadTrack.itsNCls() < nItsClsDauMin) { + nItsClsDauMin = charmHadTrack.itsNCls(); + } + if (charmHadTrack.tpcNClsCrossedRows() < nTpcCrossRowsDauMin) { + nTpcCrossRowsDauMin = charmHadTrack.tpcNClsCrossedRows(); + } + if (charmHadTrack.tpcChi2NCl() > chi2TpcDauMax) { + chi2TpcDauMax = charmHadTrack.tpcChi2NCl(); + } + } + if constexpr (DType == DType::Dstar) { + auto softPi = tracksIU.rawIteratorAt(candD.prongPiId()); + nItsClsSoftPi = softPi.itsNCls(); + nTpcCrossRowsSoftPi = softPi.tpcNClsCrossedRows(); + chi2TpcSoftPi = softPi.tpcChi2NCl(); + charmHadDauTracks.push_back(softPi); + } + // Loop on the bachelor V0s + if constexpr (DoV0s) { + for (const auto& v0 : bachelorV0s) { + auto trackPos = tracksIU.rawIteratorAt(v0.posTrackId()); + auto trackNeg = tracksIU.rawIteratorAt(v0.negTrackId()); + // Apply selsection + auto v0DauTracks = std::array{trackPos, trackNeg}; + candidateV0 candV0; + if (!buildAndSelectV0(collision, prongIdsD, v0DauTracks, cfgV0Cuts, fitter, candV0, rejectPairsWithCommonDaughter)) { + continue; + } + // Get single track variables + float chi2TpcDauV0Max = -1.f; + int nItsClsDauV0Min = 8, nTpcCrossRowsDauV0Min = 200; + for (const auto& v0Track : v0DauTracks) { + if (v0Track.itsNCls() < nItsClsDauV0Min) { + nItsClsDauV0Min = v0Track.itsNCls(); + } + if (v0Track.tpcNClsCrossedRows() < nTpcCrossRowsDauV0Min) { + nTpcCrossRowsDauV0Min = v0Track.tpcNClsCrossedRows(); + } + if (v0Track.tpcChi2NCl() > chi2TpcDauV0Max) { + chi2TpcDauV0Max = v0Track.tpcChi2NCl(); + } + } + // propagate V0 to primary vertex (if enabled) + if (cfgV0Cuts.propagateV0toPV.value) { + std::array const pVecV0Orig = {candV0.mom[0], candV0.mom[1], candV0.mom[2]}; + std::array dcaInfo{}; + auto trackParK0 = o2::track::TrackPar(candV0.pos, pVecV0Orig, 0, true); + trackParK0.setPID(o2::track::PID::K0); + trackParK0.setAbsCharge(0); + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParK0, 2.f, matCorr, &dcaInfo); + getPxPyPz(trackParK0, candV0.mom); + } + // compute resonance invariant mass and filling of QA histograms + if (TESTBIT(candV0.v0Type, BachelorType::K0s)) { + registry.fill(HIST("hMassVsPtK0s"), candV0.pT, candV0.mK0Short); + if constexpr (DType == DType::Dstar) { + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom)); + if (varUtils.signD > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassK0}); + } else { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassK0}); + } + if (!cfgQaPlots.applyCutsForQaHistograms.value || + (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin.value && + varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax.value && + candV0.mK0Short > cfgQaPlots.cutMassK0sMin.value && + candV0.mK0Short < cfgQaPlots.cutMassK0sMax.value)) { + registry.fill(HIST("hMassDstarK0s"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } else if constexpr (DType == DType::Dplus) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassK0}); + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + (varUtils.invMassD > cfgQaPlots.cutMassDMin.value && + varUtils.invMassD < cfgQaPlots.cutMassDMax.value && + candV0.mK0Short > cfgQaPlots.cutMassK0sMin.value && + candV0.mK0Short < cfgQaPlots.cutMassK0sMax.value)) { + registry.fill(HIST("hMassDplusK0s"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } // end of dType switch + } // matched with K0s + bool const isLambda = TESTBIT(candV0.v0Type, BachelorType::Lambda); + bool const isAntiLambda = TESTBIT(candV0.v0Type, BachelorType::AntiLambda); + if (isLambda || isAntiLambda) { + registry.fill(HIST("hMassVsPtLambda"), candV0.pT, candV0.mLambda); + if constexpr (DType == DType::Dstar) { + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom)); + if (varUtils.signD > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassLambda}); + } else { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassLambda}); + } + if (!cfgQaPlots.applyCutsForQaHistograms.value || + (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin.value && + varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax.value && + candV0.mLambda > cfgQaPlots.cutMassLambdaMin.value && + candV0.mLambda < cfgQaPlots.cutMassLambdaMax.value)) { + registry.fill(HIST("hMassDstarLambda"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } else if constexpr (DType == DType::Dplus) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassLambda}); + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + (varUtils.invMassD > cfgQaPlots.cutMassDMin.value && + varUtils.invMassD < cfgQaPlots.cutMassDMax.value && + candV0.mLambda > cfgQaPlots.cutMassLambdaMin.value && + candV0.mLambda < cfgQaPlots.cutMassLambdaMax.value)) { + registry.fill(HIST("hMassDplusLambda"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } else if constexpr (DType == DType::D0) { + if (isLambda) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassLambda}); + } else { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassLambda}); + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, candV0.mom)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + (((varUtils.invMassD0 > cfgQaPlots.cutMassDMin.value && varUtils.invMassD0 < cfgQaPlots.cutMassDMax.value) || + (varUtils.invMassD0Bar > cfgQaPlots.cutMassDMin.value && varUtils.invMassD0Bar < cfgQaPlots.cutMassDMax.value)) && + candV0.mLambda > cfgQaPlots.cutMassLambdaMin.value && + candV0.mLambda < cfgQaPlots.cutMassLambdaMax.value)) { + if (isLambda) { + registry.fill(HIST("hMassD0Lambda"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0); + } else { + registry.fill(HIST("hMassD0Lambda"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0Bar); + } + } + } // end of dType switch + } // matched with Lambda or AntiLambda + // fill V0 table + // if information on V0 already stored, go to next V0 + if (!selectedV0s.count(v0.globalIndex())) { + rowCandV0Reduced(trackPos.globalIndex(), trackNeg.globalIndex(), + indexHfReducedCollision, + candV0.pos[0], candV0.pos[1], candV0.pos[2], + candV0.momPos[0], candV0.momPos[1], candV0.momPos[2], + candV0.momNeg[0], candV0.momNeg[1], candV0.momNeg[2], + candV0.cosPA, + candV0.dcaV0ToPv, + nItsClsDauV0Min, nTpcCrossRowsDauV0Min, chi2TpcDauV0Max, + candV0.v0Type); + selectedV0s[v0.globalIndex()] = rowCandV0Reduced.lastIndex(); + } + fillHfCandD = true; + // Optional filling of MC Rec table, for now only implemented for Ds1->D*K0s and Ds2*->D+K0s + if constexpr (DoMc) { + auto indexHfCandCharm = rowCandDmesReduced.lastIndex() + 1; + fillMcRecoInfoDV0(particlesMc, candD, v0, tracksIU, indexHfCandCharm, selectedV0s[v0.globalIndex()], pdg, registry, rowMcRecV0Reduced); + } + } // end of loop on V0 candidates + } // end of do V0s + // Loop on the bachelor tracks + if constexpr (DoTracks) { + for (const auto& trackIndex : bachelorTrks) { + auto track = tracks.rawIteratorAt(trackIndex.trackId()); + if (!isTrackSelected(track, prongIdsD, cfgSingleTrackCuts, rejectPairsWithCommonDaughter)) { + continue; + } + // if the track has been reassociated, re-propagate it to PV (minor difference) + auto trackParCovTrack = getTrackParCov(track); + std::array dcaTrack{track.dcaXY(), track.dcaZ()}; + std::array pVecTrack = track.pVector(); + if (track.collisionId() != collision.globalIndex()) { + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParCovTrack, 2.f, matCorr, &dcaTrack); + getPxPyPz(trackParCovTrack, pVecTrack); + } + registry.fill(HIST("hdEdxVsP"), track.p(), track.tpcSignal()); + // compute invariant mass and filling of QA histograms + if constexpr (DType == DType::Dstar) { + // D* pi + if (std::abs(track.tpcNSigmaPi()) < cfgSingleTrackCuts.maxNsigmaTpcPi.value) { + if (varUtils.signD > 0 && track.sign() < 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged}); + } else if (varUtils.signD < 0 && track.sign() > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged}); + } else { + varUtils.invMassReso = -1.f; // invalid case + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin.value && + varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax.value)) { + registry.fill(HIST("hMassDstarPi"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } + if (std::abs(track.tpcNSigmaKa()) < cfgSingleTrackCuts.maxNsigmaTpcKa.value) { + if (varUtils.signD > 0 && track.sign() < 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus}); + } else if (varUtils.signD < 0 && track.sign() > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus}); + } else { + varUtils.invMassReso = -1.f; // invalid case + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin.value && + varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax.value)) { + registry.fill(HIST("hMassDstarK"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } + // D* p + if (std::abs(track.tpcNSigmaPr()) < cfgSingleTrackCuts.maxNsigmaTpcPr.value) { + if (varUtils.signD > 0 && track.sign() > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton}); + } else if (varUtils.signD < 0 && track.sign() < 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton}); + } else { + varUtils.invMassReso = -1.f; // invalid case + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin.value && + varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax.value)) { + registry.fill(HIST("hMassDstarProton"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } + } else if constexpr (DType == DType::Dplus) { + // D+ pi + if (std::abs(track.tpcNSigmaPi()) < cfgSingleTrackCuts.maxNsigmaTpcPi.value) { + if (varUtils.signD * track.sign() < 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged}); + } else { + varUtils.invMassReso = -1.f; // invalid case + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + (varUtils.invMassD > cfgQaPlots.cutMassDMin.value && + varUtils.invMassD < cfgQaPlots.cutMassDMax.value)) { + registry.fill(HIST("hMassDplusPi"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } + // D+ K + if (std::abs(track.tpcNSigmaKa()) < cfgSingleTrackCuts.maxNsigmaTpcKa.value) { + if (varUtils.signD * track.sign() < 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus}); + } else { + varUtils.invMassReso = -1.f; // invalid case + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + (varUtils.invMassD > cfgQaPlots.cutMassDMin.value && + varUtils.invMassD < cfgQaPlots.cutMassDMax.value)) { + registry.fill(HIST("hMassDplusK"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } + // D+ pr + if (std::abs(track.tpcNSigmaPr()) < cfgSingleTrackCuts.maxNsigmaTpcPr.value) { + if (varUtils.signD * track.sign() < 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton}); + } else { + varUtils.invMassReso = -1.f; // invalid case + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + (varUtils.invMassD > cfgQaPlots.cutMassDMin.value && + varUtils.invMassD < cfgQaPlots.cutMassDMax.value)) { + registry.fill(HIST("hMassDplusProton"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } + } else if constexpr (DType == DType::D0) { + // D0 pi + if (std::abs(track.tpcNSigmaPi()) < cfgSingleTrackCuts.maxNsigmaTpcPi.value) { + if (track.sign() > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged}); + } else { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged}); + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + ((varUtils.invMassD0 > cfgQaPlots.cutMassDMin.value && + varUtils.invMassD0 < cfgQaPlots.cutMassDMax.value) || + (varUtils.invMassD0Bar > cfgQaPlots.cutMassDMin.value && + varUtils.invMassD0Bar < cfgQaPlots.cutMassDMax.value))) { + if (track.sign() > 0) { + registry.fill(HIST("hMassD0Pi"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0); + } else { + registry.fill(HIST("hMassD0Pi"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0Bar); + } + } + } + // D0 K + if (std::abs(track.tpcNSigmaKa()) < cfgSingleTrackCuts.maxNsigmaTpcKa.value) { + if (track.sign() > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassKPlus}); + } else { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassKPlus}); + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + ((varUtils.invMassD0 > cfgQaPlots.cutMassDMin.value && + varUtils.invMassD0 < cfgQaPlots.cutMassDMax.value) || + (varUtils.invMassD0Bar > cfgQaPlots.cutMassDMin.value && + varUtils.invMassD0Bar < cfgQaPlots.cutMassDMax.value))) { + if (track.sign() > 0) { + registry.fill(HIST("hMassD0K"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0); + } else { + registry.fill(HIST("hMassD0K"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0Bar); + } + } + } + // D0 p + if (std::abs(track.tpcNSigmaPr()) < cfgSingleTrackCuts.maxNsigmaTpcPr.value) { + if (track.sign() > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassProton}); + } else { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassProton}); + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + ((varUtils.invMassD0 > cfgQaPlots.cutMassDMin.value && + varUtils.invMassD0 < cfgQaPlots.cutMassDMax.value) || + (varUtils.invMassD0Bar > cfgQaPlots.cutMassDMin.value && + varUtils.invMassD0Bar < cfgQaPlots.cutMassDMax.value))) { + if (track.sign() > 0) { + registry.fill(HIST("hMassD0Proton"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0); + } else { + registry.fill(HIST("hMassD0Proton"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0Bar); + } + } + } + } // end of DType switch + // fill track table + if (!selectedTracks.count(track.globalIndex())) { + rowTrkReduced(track.globalIndex(), + indexHfReducedCollision, + track.px(), track.py(), track.pz(), track.sign(), + track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr(), + track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr(), + track.hasTOF(), track.hasTPC(), track.itsNCls(), track.tpcNClsCrossedRows(), track.tpcChi2NCl()); + selectedTracks[track.globalIndex()] = rowTrkReduced.lastIndex(); + } + fillHfCandD = true; + if constexpr (DoMc) { + auto indexHfCandCharm = rowCandDmesReduced.lastIndex() + 1; + fillMcRecoInfoDTrack(particlesMc, candD, track, tracks, indexHfCandCharm, selectedTracks[track.globalIndex()], pdg, registry, rowMcRecTrkReduced); + } + } // end of loop on bachelor tracks + } // end of do tracks + // fill D candidate table + if (fillHfCandD) { // fill candDplus table only once per D candidate, only if at least one V0 is found + if constexpr (DType == DType::Dplus) { + rowCandDmesReduced(prongIdsD[0], prongIdsD[1], prongIdsD[2], + indexHfReducedCollision, + secondaryVertexD[0], secondaryVertexD[1], secondaryVertexD[2], + candD.pxProng0(), candD.pyProng0(), candD.pzProng0(), + candD.pxProng1(), candD.pyProng1(), candD.pzProng1(), + varUtils.pVectorProng2[0], varUtils.pVectorProng2[1], varUtils.pVectorProng2[2], + nItsClsDauMin, nTpcCrossRowsDauMin, chi2TpcDauMax, varUtils.signD); + if constexpr (WithMl) { + rowCandDmesMlReduced(bdtScores[0], bdtScores[1], bdtScores[2], bdtScores[3], bdtScores[4], bdtScores[5]); + } + } else if constexpr (DType == DType::D0) { + uint8_t selFlagD0 = {BIT(D0Sel::SelectedD0) | BIT(D0Sel::SelectedD0Bar)}; + if (candD.isSelD0() < cfgDmesCuts.selectionFlagD0.value) { + CLRBIT(selFlagD0, D0Sel::SelectedD0); + } + if (candD.isSelD0bar() < cfgDmesCuts.selectionFlagD0Bar.value) { + CLRBIT(selFlagD0, D0Sel::SelectedD0Bar); + } + rowCandDmesReduced(prongIdsD[0], prongIdsD[1], + indexHfReducedCollision, + secondaryVertexD[0], secondaryVertexD[1], secondaryVertexD[2], + candD.pxProng0(), candD.pyProng0(), candD.pzProng0(), + candD.pxProng1(), candD.pyProng1(), candD.pzProng1(), + nItsClsDauMin, nTpcCrossRowsDauMin, chi2TpcDauMax, + selFlagD0); + if constexpr (WithMl) { + rowCandDmesMlReduced(bdtScores[0], bdtScores[1], bdtScores[2], bdtScores[3], bdtScores[4], bdtScores[5]); + } + } else if constexpr (DType == DType::Dstar) { + rowCandDmesReduced(prongIdsD[0], prongIdsD[1], prongIdsD[2], + indexHfReducedCollision, + secondaryVertexD[0], secondaryVertexD[1], secondaryVertexD[2], + candD.pxProng0(), candD.pyProng0(), candD.pzProng0(), + candD.pxProng1(), candD.pyProng1(), candD.pzProng1(), + varUtils.pVectorProng2[0], varUtils.pVectorProng2[1], varUtils.pVectorProng2[2], + nItsClsDauMin, nTpcCrossRowsDauMin, chi2TpcDauMax, + nItsClsSoftPi, nTpcCrossRowsSoftPi, chi2TpcSoftPi, + varUtils.signD); + if constexpr (WithMl) { + rowCandDmesMlReduced(bdtScores[0], bdtScores[1], bdtScores[2], bdtScores[3], bdtScores[4], bdtScores[5]); + } + } + fillHfReducedCollision = true; + if constexpr (DType == DType::Dstar) { + registry.fill(HIST("hMassVsPtDstarPaired"), candD.pt(), varUtils.invMassD - varUtils.invMassD0); + } else if constexpr (DType == DType::Dplus) { + registry.fill(HIST("hMassVsPtDplusPaired"), candD.pt(), varUtils.invMassD); + } else if constexpr (DType == DType::D0) { + if (candD.isSelD0() >= cfgDmesCuts.selectionFlagD0.value) { + registry.fill(HIST("hMassVsPtD0Paired"), varUtils.ptD, varUtils.invMassD0); + } + if (candD.isSelD0bar() >= cfgDmesCuts.selectionFlagD0Bar.value) { + registry.fill(HIST("hMassVsPtD0BarPaired"), varUtils.ptD, varUtils.invMassD0Bar); + } + } + } + } // candsD loop + registry.fill(HIST("hEvents"), 1 + Event::Processed); + if (!fillHfReducedCollision) { + registry.fill(HIST("hEvents"), 1 + Event::NoDV0Selected); + return; + } + registry.fill(HIST("hEvents"), 1 + Event::DV0Selected); + // fill collision table if it contains a DPi pair a minima + rowCollisionReduced(collision.posX(), collision.posY(), collision.posZ(), collision.numContrib(), hfRejMap, bz); + } // end of runDataCreation function + + + // Function for derived data creation + /// \tparam dType is the D meson type (Dstar, Dplus or D0) + /// \param mcParticles is the MC particle table + /// \param collInfos is the reco collision table with MC info + /// \param mcCollisions is the MC collision table + /// \param hfEvSelMc is the HF event selection util object from MC + /// \param rejectCollisionsWithBadEvSel is the flag to not store collisions rejected by event selection + /// \param registry is the histogram registry + /// \param pdg is the O2DatabasePDG service + /// \param rowHfResoMcGenReduced is the MC gen reduced table + template + void runMcGen(McParticles const& mcParticles, + McParticlesPerMcColl const& mcParticlesPerMcCollision, + CCs const& collInfos, + CollPerMcColl const& colPerMcCollision, + McCollisions const& mcCollisions, + o2::hf_evsel::HfEventSelectionMc& hfEvSelMc, + bool rejectCollisionsWithBadEvSel, + o2::framework::HistogramRegistry& registry, + o2::framework::Service const& pdg, + TableMcGenRed& rowHfResoMcGenReduced, + BCsInfo const&) + { + bool const doV0s = (PairingType == PairingType::V0Only || PairingType == PairingType::V0AndTrack); + bool const doTracks = (PairingType == PairingType::TrackOnly || PairingType == PairingType::V0AndTrack); + for (const auto& mcCollision : mcCollisions) { + // Slice the particles table to get the particles for the current MC collision + const auto mcParticlesPerMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, mcCollision.globalIndex()); + // Slice the collisions table to get the collision info for the current MC collision + float centrality{-1.f}; + o2::hf_evsel::HfCollisionRejectionMask rejectionMask{}; + int const nSplitColl = 0; + const auto collSlice = collInfos.sliceBy(colPerMcCollision, mcCollision.globalIndex()); + rejectionMask = hfEvSelMc.getHfMcCollisionRejectionMask(mcCollision, collSlice, centrality); + hfEvSelMc.fillHistograms(mcCollision, rejectionMask, nSplitColl); + if (rejectCollisionsWithBadEvSel && rejectionMask != 0) { + // at least one event selection not satisfied --> reject all gen particles from this collision + continue; + } + for (const auto& particle : mcParticlesPerMcColl) { + int8_t sign{0}; + int8_t flag{0}; + int8_t signD{0}; + int8_t signBach{0}; + int8_t origin{0}; + bool matchedReso{false}, matchedD{false}, matchedV0Tr{false}; + std::vector idxBhadMothers{}; + if constexpr (DType == DType::Dstar) { + if (doV0s) { + // D* K0s + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarK0s) { + matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kDStar), +kK0}, true, &sign, 1); + if (matchedReso) { + flag = sign * decayChannelFlag; + auto candV0MC = mcParticles.rawIteratorAt(particle.daughtersIds().back()); + matchedV0Tr = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candV0MC, kK0, std::array{+kPiPlus, -kPiPlus}, true, &signBach, 2); + break; + } + } + } + if (doTracks && !matchedReso) { + // D*+ pi- + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarPi) { + matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kDStar), -static_cast(kPiPlus)}, true, &sign, 1); + if (matchedReso) { + flag = sign * decayChannelFlag; + matchedV0Tr = true; + break; + } + } + } + if (matchedReso && matchedV0Tr) { + auto candDstarMC = mcParticles.rawIteratorAt(particle.daughtersIds().front()); + matchedD = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candDstarMC, o2::constants::physics::Pdg::kDStar, std::array{static_cast(o2::constants::physics::Pdg::kD0), +static_cast(kPiPlus)}, true, &signD, 1); + if (matchedD) { + auto candD0MC = mcParticles.rawIteratorAt(candDstarMC.daughtersIds().front()); + matchedD = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candD0MC, o2::constants::physics::Pdg::kD0, std::array{-kKPlus, +kPiPlus}, true, &signD, 2); + } + } + } else if constexpr (DType == DType::Dplus) { + if (doV0s) { + // D+ K0s + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusK0s) { + matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kDPlus), +kK0}, true, &sign, 1); + if (matchedReso) { + flag = sign * decayChannelFlag; + auto candV0MC = mcParticles.rawIteratorAt(particle.daughtersIds().back()); + matchedV0Tr = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candV0MC, kK0, std::array{+kPiPlus, -kPiPlus}, true, &signBach, 2); + break; + } + } + if (!matchedReso) { + // D+ lambda + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusLambda) { + matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kDPlus), +kLambda0}, true, &sign, 1); + if (matchedReso) { + flag = sign * decayChannelFlag; + auto candV0MC = mcParticles.rawIteratorAt(particle.daughtersIds().back()); + matchedV0Tr = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candV0MC, kLambda0, std::array{+kProton, -kPiPlus}, true, &signBach, 1); + break; + } + } + } + } + if (doTracks && !matchedReso) { + // D+ pi- + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusPi) { + matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kDPlus), -static_cast(kPiPlus)}, true, &sign, 1); + if (matchedReso) { + flag = sign * decayChannelFlag; + matchedV0Tr = true; + break; + } + } + } + if (matchedReso && matchedV0Tr) { + auto candDplusMC = mcParticles.rawIteratorAt(particle.daughtersIds().front()); + matchedD = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candDplusMC, o2::constants::physics::Pdg::kDPlus, std::array{+kPiPlus, -kKPlus, +kPiPlus}, true, &signD, 2); + } + } else if constexpr (DType == DType::D0) { + if (doV0s) { + // D0 Lambda + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Lambda) { + matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kD0), +kLambda0}, true, &sign, 1); + if (matchedReso) { + flag = sign * decayChannelFlag; + auto candV0MC = mcParticles.rawIteratorAt(particle.daughtersIds().back()); + matchedV0Tr = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candV0MC, kLambda0, std::array{+kProton, -kPiPlus}, true, &signBach, 1); + break; + } + } + } + if (doTracks && !matchedReso) { + // D0 pi+ + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Pi) { + matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kD0), +static_cast(kPiPlus)}, true, &sign, 1); + if (matchedReso) { + flag = sign * decayChannelFlag; + matchedV0Tr = true; + break; + } + } + // D0 K+ + if (!matchedReso) { + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Kplus) { + matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kD0), +static_cast(kKPlus)}, true, &sign, 1); + if (matchedReso) { + flag = sign * decayChannelFlag; + matchedV0Tr = true; + break; + } + } + } + } + if (matchedReso && matchedV0Tr) { + auto candD0MC = mcParticles.rawIteratorAt(particle.daughtersIds().front()); + matchedD = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candD0MC, o2::constants::physics::Pdg::kD0, std::array{-kKPlus, +kPiPlus}, true, &signD, 2); + } + } + if (matchedReso && matchedD && matchedV0Tr) { + origin = RecoDecay::getCharmHadronOrigin(mcParticlesPerMcColl, particle, false, &idxBhadMothers); + registry.fill(HIST("hMCGenOrigin"), origin); + auto ptParticle = particle.pt(); + auto invMassGen = computeInvMassGen(mcParticles, particle.globalIndex(), pdg); + auto yParticle = RecoDecay::y(particle.pVector(), invMassGen); + auto etaParticle = particle.eta(); + + std::array ptProngs{}; + std::array yProngs{}; + std::array etaProngs{}; + int counter = 0; + for (const auto& daught : particle.template daughters_as()) { + ptProngs[counter] = daught.pt(); + etaProngs[counter] = daught.eta(); + yProngs[counter] = RecoDecay::y(daught.pVector(), pdg->Mass(daught.pdgCode())); + counter++; + } + registry.fill(HIST("hMCGenCounter"), flag, ptParticle); + rowHfResoMcGenReduced(flag, origin, ptParticle, yParticle, etaParticle, + ptProngs[0], yProngs[0], etaProngs[0], + ptProngs[1], yProngs[1], etaProngs[1], + invMassGen, rejectionMask); + } + } + } + } + } // namespace hf_charm_reso +} // namespace o2::analysis + +#endif // PWGHF_D2H_CORE_DATACREATIONCHARMRESO_H_ diff --git a/PWGHF/D2H/TableProducer/CMakeLists.txt b/PWGHF/D2H/TableProducer/CMakeLists.txt index a60ab1d78ab..19a4a7ae123 100644 --- a/PWGHF/D2H/TableProducer/CMakeLists.txt +++ b/PWGHF/D2H/TableProducer/CMakeLists.txt @@ -70,8 +70,18 @@ o2physics_add_dpl_workflow(data-creator-charm-had-pi-reduced PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DCAFitter O2Physics::EventFilteringUtils COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(data-creator-charm-reso-reduced - SOURCES dataCreatorCharmResoReduced.cxx +o2physics_add_dpl_workflow(data-creator-charm-reso-to-dstar-reduced + SOURCES dataCreatorCharmResoToDstarReduced.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::EventFilteringUtils + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(data-creator-charm-reso-to-dplus-reduced + SOURCES dataCreatorCharmResoToDplusReduced.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::EventFilteringUtils + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(data-creator-charm-reso-to-d0-reduced + SOURCES dataCreatorCharmResoToD0Reduced.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::EventFilteringUtils COMPONENT_NAME Analysis) diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmResoReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmResoReduced.cxx deleted file mode 100644 index 588150dc44f..00000000000 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmResoReduced.cxx +++ /dev/null @@ -1,2721 +0,0 @@ -// Copyright 2019-2020 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 dataCreatorCharmResoReduced.cxx -/// \brief Creation of D-V0 pairs -/// -/// \author Luca Aglietta , UniTO Turin -/// \author Fabrizio Grosa , CERN - -#include "PWGHF/Core/CentralityEstimation.h" -#include "PWGHF/Core/DecayChannels.h" -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/D2H/DataModel/ReducedDataModel.h" -#include "PWGHF/D2H/Utils/utilsRedDataFormat.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/Utils/utilsBfieldCCDB.h" -#include "PWGHF/Utils/utilsEvSelHf.h" -#include "PWGHF/Utils/utilsMcMatching.h" - -#include "Common/Core/RecoDecay.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/CollisionAssociationTables.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/PIDResponseTOF.h" -#include "Common/DataModel/PIDResponseTPC.h" -#include "Common/DataModel/TrackSelectionTables.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace o2; -using namespace o2::analysis; -using namespace o2::aod; -using namespace o2::constants::physics; -using namespace o2::framework; -using namespace o2::framework::expressions; -// event types -enum Event : uint8_t { - Processed = 0, - NoDV0Selected, - DV0Selected, - kNEvent -}; - -enum BachelorType : uint8_t { - K0s = 0, - Lambda, - AntiLambda, - Track -}; - -enum DType : uint8_t { - Dplus = 1, - Dstar, - D0 -}; - -enum PairingType : uint8_t { - V0Only, - TrackOnly, - V0AndTrack -}; - -enum D0Sel : uint8_t { - SelectedD0 = 0, - SelectedD0Bar -}; - -/// Creation of D-V0 pairs -struct HfDataCreatorCharmResoReduced { - - // Produces AOD tables to store collision information - Produces hfReducedCollision; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h - Produces hfCollisionCounter; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h - // tracks, V0 and D candidates reduced tables - Produces hfCandV0; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h - Produces hfTrackNoParam; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h - Produces hfCandD3Pr; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h - Produces hfCandD2Pr; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h - Produces hfCandDstar; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h - // ML optional Tables - Produces hfCandD3PrMl; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h - Produces hfCandD2PrMl; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h - // MC Tables - Produces rowHfResoMcGenReduced; - Produces rowHf3PrV0McRecReduced; - Produces rowHfDstarV0McRecReduced; - Produces rowHf2PrV0McRecReduced; - Produces rowHf3PrTrkMcRecReduced; - Produces rowHfDstarTrkMcRecReduced; - Produces rowHf2PrTrkMcRecReduced; - - // selection D - struct : ConfigurableGroup { - std::string prefix = "dmesons"; - Configurable selectionFlagDplus{"selectionFlagDplus", 7, "Selection Flag for D"}; - Configurable selectionFlagDstarToD0Pi{"selectionFlagDstarToD0Pi", true, "Selection Flag for D* decay to D0 & Pi"}; - Configurable selectionFlagD0{"selectionFlagD0", 1, "Selection Flag for D0"}; - Configurable selectionFlagD0Bar{"selectionFlagD0Bar", 1, "Selection Flag for D0bar"}; - } cfgDmesCuts; - - // selection V0 - struct : ConfigurableGroup { - std::string prefix = "v0s"; - Configurable deltaMassK0s{"deltaMassK0s", 0.02, "delta mass cut for K0S"}; - Configurable deltaMassLambda{"deltaMassLambda", 0.01, "delta mass cut for Lambda"}; - Configurable etaMax{"etaMax", 0.8f, "maximum eta"}; - Configurable etaMaxDau{"etaMaxDau", 5.f, "maximum eta V0 daughters"}; - Configurable trackNclusItsCut{"trackNclusItsCut", 0, "Minimum number of ITS clusters for V0 daughter"}; - Configurable trackNCrossedRowsTpc{"trackNCrossedRowsTpc", 50, "Minimum TPC crossed rows"}; - Configurable trackNsharedClusTpc{"trackNsharedClusTpc", 1000, "Maximum number of shared TPC clusters for V0 daughter"}; - Configurable trackFracMaxindableTpcCls{"trackFracMaxindableTpcCls", 0.8f, "Maximum fraction of findable TPC clusters for V0 daughter"}; - Configurable dcaDau{"dcaDau", 1.f, "DCA V0 daughters"}; - Configurable dcaMaxDauToPv{"dcaMaxDauToPv", 0.1f, "Maximum daughter's DCA to PV"}; - Configurable dcaPv{"dcaPv", 1.f, "DCA V0 to PV"}; - Configurable cosPa{"cosPa", 0.99f, "V0 CosPA"}; - Configurable radiusMin{"radiusMin", 0.9f, "Minimum v0 radius accepted"}; - Configurable nSigmaTpc{"nSigmaTpc", 4.f, "Nsigmatpc"}; - Configurable nSigmaTofPr{"nSigmaTofPr", 4.f, "N sigma TOF for protons only"}; - } cfgV0Cuts; - - // selection single tracks - struct : ConfigurableGroup { - std::string prefix = "singleTracks"; - Configurable setTrackSelections{"setTrackSelections", 2, "flag to apply track selections: 0=none; 1=global track w/o DCA selection; 2=global track; 3=only ITS quality"}; - Configurable maxEta{"maxEta", 0.8, "maximum pseudorapidity for single tracks to be paired with D mesons"}; - Configurable minPt{"minPt", 0.1, "minimum pT for single tracks to be paired with D mesons"}; - Configurable maxNsigmaTpcPi{"maxNsigmaTpcPi", -1., "maximum pion NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; - Configurable maxNsigmaTpcKa{"maxNsigmaTpcKa", -1., "maximum kaon NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; - Configurable maxNsigmaTpcPr{"maxNsigmaTpcPr", 3., "maximum proton NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; - } cfgSingleTrackCuts; - - // QA histograms - struct : ConfigurableGroup { - std::string prefix = "qaPlots"; - Configurable applyCutsForQaHistograms{"applyCutsForQaHistograms", true, "flag to apply cuts to QA histograms"}; - Configurable cutMassDstarMin{"cutMassDstarMin", 0.143, "minimum mass for Dstar candidates"}; - Configurable cutMassDstarMax{"cutMassDstarMax", 0.155, "maximum mass for Dstar candidates"}; - Configurable cutMassDMin{"cutMassDMin", 1.83, "minimum mass for D0 and Dplus candidates"}; - Configurable cutMassDMax{"cutMassDMax", 1.92, "maximum mass for D0 and Dplus candidates"}; - Configurable cutMassK0sMin{"cutMassK0sMin", 0.485, "minimum mass for K0s candidates"}; - Configurable cutMassK0sMax{"cutMassK0sMax", 0.509, "maximum mass for K0s candidates"}; - Configurable cutMassLambdaMin{"cutMassLambdaMin", 1.11, "minimum mass for Lambda candidates"}; - Configurable cutMassLambdaMax{"cutMassLambdaMax", 1.12, "maximum mass for Lambda candidates"}; - } cfgQaPlots; - // other configurables - Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; - Configurable propagateV0toPV{"propagateV0toPV", false, "Enable or disable V0 propagation to V0"}; - Configurable doMcRecQa{"doMcRecQa", true, "Fill QA histograms for Mc matching"}; - Configurable rejectPairsWithCommonDaughter{"rejectPairsWithCommonDaughter", true, "flag to reject already at this stage the pairs that share a daughter track"}; - Configurable rejectCollisionsWithBadEvSel{"rejectCollisionsWithBadEvSel", true, "flag to reject collisions with bad event selection"}; - - o2::hf_evsel::HfEventSelection hfEvSel; - o2::hf_evsel::HfEventSelectionMc hfEvSelMc; - - // CCDB service - o2::ccdb::CcdbApi ccdbApi; - Service ccdb; - double bz{0.}; - int runNumber{0}; // needed to detect if the run changed and trigger update of calibrations etc. - - // material correction for track propagation - o2::base::MatLayerCylSet* lut{}; - o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; - - // O2DatabasePDG service - Service pdg; - - // vertex fitter - o2::vertexing::DCAFitterN<2> fitter; - - // Helper struct to pass V0 informations - struct { - std::array pos; - std::array mom; - std::array momPos; - std::array momNeg; - float pT; - float cosPA; - float dcaV0ToPv; - float dcaDau; - float alpha; - float eta; - float radius; - float mK0Short; - float mLambda; - uint8_t v0Type; - } candidateV0{}; - - struct { - float invMassD; - float ptD; - float invMassD0; - float invMassD0Bar; - float invMassReso; - float ptReso; - int8_t signD; - std::array pVectorProng0; - std::array pVectorProng1; - std::array pVectorProng2; - } varUtils{}; - - // Dplus - using CandsDplusFiltered = soa::Filtered>; - using CandsDplusFilteredWithMl = soa::Filtered>; - using CandsDplusFilteredWithMc = soa::Filtered>; - using CandsDplusFilteredWithMlAndMc = soa::Filtered>; - // Dstar - using CandsDstarFiltered = soa::Filtered>; - using CandsDstarFilteredWithMl = soa::Filtered>; - using CandsDstarFilteredWithMc = soa::Filtered>; - using CandsDstarFilteredWithMlAndMc = soa::Filtered>; - // D0 - using CandsD0Filtered = soa::Filtered>; - using CandsD0FilteredWithMl = soa::Filtered>; - using CandsD0FilteredWithMc = soa::Filtered>; - using CandsD0FilteredWithMlAndMc = soa::Filtered>; - // Tracks - using TracksWithPID = soa::Join; - using TracksWithPIDAndMC = soa::Join; - using TracksIUWithPID = soa::Join; - using TracksIUWithPIDAndMC = soa::Join; - // Collisions MC - using BCsInfo = soa::Join; - using McCollisionsNoCents = soa::Join; - - Filter filterSelectDplus = (aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= cfgDmesCuts.selectionFlagDplus); - Filter filterSelectedCandDstar = (aod::hf_sel_candidate_dstar::isSelDstarToD0Pi == cfgDmesCuts.selectionFlagDstarToD0Pi); - Filter filterSelectD0Candidates = (aod::hf_sel_candidate_d0::isSelD0 >= cfgDmesCuts.selectionFlagD0 || aod::hf_sel_candidate_d0::isSelD0bar >= cfgDmesCuts.selectionFlagD0Bar); - - Preslice candsDplusPerCollision = aod::hf_cand::collisionId; - Preslice candsDplusPerCollisionWithMl = aod::hf_cand::collisionId; - Preslice candsDstarPerCollision = aod::hf_cand::collisionId; - Preslice candsDstarPerCollisionWithMl = aod::hf_cand::collisionId; - Preslice candsD0PerCollision = aod::hf_cand::collisionId; - Preslice candsD0PerCollisionWithMl = aod::hf_cand::collisionId; - Preslice candsV0PerCollision = aod::v0::collisionId; - Preslice trackIndicesPerCollision = aod::track_association::collisionId; - Preslice mcParticlesPerMcCollision = aod::mcparticle::mcCollisionId; - PresliceUnsorted colPerMcCollision = aod::mccollisionlabel::mcCollisionId; - - HistogramRegistry registry{"registry"}; - - void init(InitContext& initContext) - { - // histograms - constexpr int kNBinsEvents = kNEvent; - std::string labels[kNBinsEvents]; - labels[Event::Processed] = "processed"; - labels[Event::NoDV0Selected] = "without DV0 pairs"; - labels[Event::DV0Selected] = "with DV0 pairs"; - static const AxisSpec axisEvents = {kNBinsEvents, 0.5, kNBinsEvents + 0.5, ""}; - registry.add("hEvents", "Events;;entries", HistType::kTH1D, {axisEvents}); - for (int iBin = 0; iBin < kNBinsEvents; iBin++) { - registry.get(HIST("hEvents"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); - } - - const AxisSpec axisPt{50, 0.f, 50.f, "#it{p}_{T} (GeV/#it{c})"}; - const AxisSpec axisP{100, 0.f, 10.f, "#it{p} (GeV/#it{c})"}; - const AxisSpec axisDeDx{500, 0.f, 1000.f, ""}; - const AxisSpec axisMassD0{200, 1.7f, 2.1f, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisMassDplus{200, 1.7f, 2.1f, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisMassDstar{200, 0.139f, 0.179f, "delta inv. mass (GeV/#it{c}^{2})"}; // o2-linter: disable=pdg/explicit-mass (false positive) - const AxisSpec axisMassLambda{100, 1.05f, 1.35f, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisMassKzero{100, 0.35f, 0.65f, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisDeltaMassToK{500, 0.49, 1.49, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisDeltaMassToPi{500, 0.13, 1.13, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisDeltaMassToPr{500, 0.93, 1.93, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisDeltaMassToLambda{500, 1.05, 2.05, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisMassDsj{400, 0.49f, 0.89f, ""}; // Ds1 and Ds2Star legacy - registry.add("hMassVsPtK0s", "K0^{s} candidates;#it{p}_{T} (GeV/#it{c});inv. mass (#pi^{#plus}#pi^{#minus}) (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassKzero}}); - registry.add("hMassVsPtLambda", "Lambda candidates;#it{p}_{T} (GeV/#it{c});inv. mass (p #pi^{#minus}) (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassLambda}}); - registry.add("hdEdxVsP", "Tracks;#it{p} (GeV/#it{c});d#it{E}/d#it{x};entries", {HistType::kTH2D, {axisP, axisDeDx}}); - - if (doprocessD0V0 || doprocessD0Track || doprocessD0V0AndTrack || doprocessD0V0WithMl || doprocessD0TrackWithMl || doprocessD0V0AndTrackWithMl || - doprocessD0V0MC || doprocessD0TrackMC || doprocessD0V0AndTrackMC || doprocessD0V0MCWithMl || doprocessD0TrackMCWithMl || doprocessD0V0AndTrackMCWithMl) { - registry.add("hMassVsPtD0All", "D0 candidates (all, regardless the pairing with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassD0}}); - registry.add("hMassVsPtD0BarAll", "D0bar candidates (all, regardless the pairing with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassD0}}); - registry.add("hMassVsPtD0Paired", "D0 candidates (paired with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassD0}}); - registry.add("hMassVsPtD0BarPaired", "D0 candidates (paired with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassD0}}); - registry.add("hMassD0Pi", "D0Pi candidates; m_{D^{0}#pi^{+}} - m_{D^{0}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPi}}); - registry.add("hMassD0K", "D0Kplus candidates; m_{D^{0}K^{+}} - m_{D^{0}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToK}}); - registry.add("hMassD0Proton", "D0Proton candidates; m_{D^{0}p} - m_{D^{0}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPr}}); - registry.add("hMassD0Lambda", "D0Lambda candidates; m_{D^{0}#Lambda} - m_{D^{0}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToLambda}}); - } - if (doprocessDstarV0 || doprocessDstarTrack || doprocessDstarV0AndTrack || doprocessDstarV0WithMl || doprocessDstarTrackWithMl || doprocessDstarV0AndTrackWithMl || - doprocessDstarV0MC || doprocessDstarTrackMC || doprocessDstarV0AndTrackMC || doprocessDstarV0MCWithMl || doprocessDstarTrackMCWithMl || doprocessDstarV0AndTrackMCWithMl) { - registry.add("hMassVsPtDstarAll", "Dstar candidates (all, regardless the pairing with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDstar}}); - registry.add("hMassVsPtDstarPaired", "Dstar candidates (paired with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDstar}}); - registry.add("hMassDstarPi", "DstarPi candidates; m_{D^{*+}#pi^{-}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPi}}); - registry.add("hMassDstarK", "DstarK candidates; m_{D^{*+}#pi^{-}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToK}}); - registry.add("hMassDstarProton", "DstarProton candidates; m_{D^{*}p} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPr}}); - registry.add("hMassDstarK0s", "DstarK0s candidates; m_{D^{*}K^{0}_{S}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToK}}); - registry.add("hMassDstarLambda", "DstarLambda candidates; m_{D^{*}#Lambda} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToLambda}}); - } - if (doprocessDplusV0 || doprocessDplusTrack || doprocessDplusV0AndTrack || doprocessDplusV0WithMl || doprocessDplusTrackWithMl || doprocessDplusV0AndTrackWithMl || - doprocessDplusV0MC || doprocessDplusTrackMC || doprocessDplusV0AndTrackMC || doprocessDplusV0MCWithMl || doprocessDplusTrackMCWithMl || doprocessDplusV0AndTrackMCWithMl) { - registry.add("hMassVsPtDplusAll", "Dplus candidates (all, regardless the pairing with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDplus}}); - registry.add("hMassVsPtDplusPaired", "Dplus candidates (paired with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDplus}}); - registry.add("hMassDplusK0s", "DplusK0s candidates; m_{D^{+}K^{0}_{S}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToK}}); - registry.add("hMassDplusPi", "DplusPi candidates; m_{D^{+}#pi^{-}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPi}}); - registry.add("hMassDplusK", "DplusK candidates; m_{D^{+}#pi^{-}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToK}}); - registry.add("hMassDplusProton", "DplusProton candidates; m_{D^{+}p} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPr}}); - registry.add("hMassDplusLambda", "DplusLambda candidates; m_{D^{+}#Lambda} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToLambda}}); - } - if (doprocessD0V0MC || doprocessD0TrackMC || doprocessD0V0AndTrackMC || doprocessD0V0MCWithMl || doprocessD0TrackMCWithMl || doprocessD0V0AndTrackMCWithMl || - doprocessDstarV0MC || doprocessDstarTrackMC || doprocessDstarV0AndTrackMC || doprocessDstarV0MCWithMl || doprocessDstarTrackMCWithMl || doprocessDstarV0AndTrackMCWithMl || - doprocessDplusV0MC || doprocessDplusTrackMC || doprocessDplusV0AndTrackMC || doprocessDplusV0MCWithMl || doprocessDplusTrackMCWithMl || doprocessDplusV0AndTrackMCWithMl) { - // MC Rec - int const nChannels = hf_decay::hf_cand_reso::DecayChannelMain::NChannelsMain; - registry.add("hMCRecCounter", "Number of Reconstructed MC Matched candidates per channel", {HistType::kTH1D, {{2 * nChannels + 1, -(nChannels + 0.5), nChannels + 0.5}}}); - registry.add("hMCRecDebug", "Debug of MC Reco", {HistType::kTH1D, {{551, -0.5, 550.5}}}); - registry.add("hMCRecOrigin", "Origin of Matched particles", {HistType::kTH1D, {{3, -0.5, 2.5}}}); - registry.add("hMCRecMassGen", "Generated inv. mass of resoncances", {HistType::kTH1D, {{2000, 1.8, 3.8}}}); - registry.add("hMCRecCharmDau", "Charm daughter flag", {HistType::kTH1D, {{57, -28.5, 28.5}}}); - // MC Gen - registry.add("hMCGenCounter", "Number of Generated particles; Decay Channel Flag; pT [GeV/c]", {HistType::kTH2D, {{17, -8.5, 8.5}, {100, 0, 50}}}); - registry.add("hMCGenOrigin", "Origin of Generated particles", {HistType::kTH1D, {{3, -0.5, 2.5}}}); - } - // Configure CCDB access - ccdb->setURL(ccdbUrl.value); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); - ccdbApi.init(ccdbUrl); - runNumber = 0; - lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get("GLO/Param/MatLUT")); - - // Configure DCA fitter - fitter.setPropagateToPCA(true); - fitter.setMaxR(200.); - fitter.setMinParamChange(1e-3); - fitter.setMinRelChi2Change(0.9); - fitter.setMaxDZIni(1e9); - fitter.setMaxDXYIni(4); - fitter.setMaxChi2(1e9); - fitter.setUseAbsDCA(true); - fitter.setWeightedFinalPCA(false); - - // init HF event selection helper - hfEvSel.init(registry); - - const auto& workflows = initContext.services().get(); - for (const DeviceSpec& device : workflows.devices) { - if (device.name == "hf-data-creator-charm-reso-reduced") { - // init HF event selection helper - hfEvSelMc.init(device, registry); - break; - } - } - } - - /// Basic track quality selections for V0 daughters - /// \param Tr is a track - /// \param dDaughtersIds are the IDs of the D meson daughter tracks - template - bool selectV0Daughter(Tr const& track, const std::array& dDaughtersIds) - { - // acceptance selection - if (std::abs(track.eta()) > cfgV0Cuts.etaMaxDau) { - return false; - } - // Tpc Refit - if (!(track.hasTPC())) { - return false; - } - // track quality selection - if (track.itsNCls() < cfgV0Cuts.trackNclusItsCut || - track.tpcNClsFound() < cfgV0Cuts.trackNCrossedRowsTpc || - track.tpcNClsCrossedRows() < cfgV0Cuts.trackNCrossedRowsTpc || - track.tpcNClsCrossedRows() < cfgV0Cuts.trackFracMaxindableTpcCls * track.tpcNClsFindable() || - track.tpcNClsShared() > cfgV0Cuts.trackNsharedClusTpc) { - return false; - } - // rejection of tracks that share a daughter with the D meson - if (rejectPairsWithCommonDaughter && std::find(dDaughtersIds.begin(), dDaughtersIds.end(), track.globalIndex()) != dDaughtersIds.end()) { - return false; - } - return true; - } - - // Utility to find which v0 daughter carries the largest fraction of the mother longitudinal momentum - float alphaAP(std::array const& momA, std::array const& momB, std::array const& momC) - { - float const momTot = std::sqrt(std::pow(momA[0], 2.) + std::pow(momA[1], 2.) + std::pow(momA[2], 2.)); - float const lQlPos = (momB[0] * momA[0] + momB[1] * momA[1] + momB[2] * momA[2]) / momTot; - float const lQlNeg = (momC[0] * momA[0] + momC[1] * momA[1] + momC[2] * momA[2]) / momTot; - return (lQlPos - lQlNeg) / (lQlPos + lQlNeg); - } - // Utility to find DCA of V0 to Primary vertex - float calculateDCAStraightToPV(float x, float y, float z, float px, float py, float pz, float pvX, float pvY, float pvZ) - { - return std::sqrt((std::pow((pvY - y) * pz - (pvZ - z) * py, 2) + std::pow((pvX - x) * pz - (pvZ - z) * px, 2) + std::pow((pvX - x) * py - (pvY - y) * px, 2)) / (px * px + py * py + pz * pz)); - } - /// Basic selection of V0 candidates - /// \param collision is the current collision - /// \param dauTracks are the v0 daughter tracks - /// \param dDaughtersIds are the IDs of the D meson daughter tracks - /// \return a bitmap with mass hypotesis if passes all cuts - template - bool buildAndSelectV0(const Coll& collision, const std::array& dDaughtersIds, const std::array& dauTracks) - { - const auto& trackPos = dauTracks[0]; - const auto& trackNeg = dauTracks[1]; - // single-tracks selection - if (!selectV0Daughter(trackPos, dDaughtersIds) || !selectV0Daughter(trackNeg, dDaughtersIds)) { - return false; - } - // daughters DCA to V0's collision primary vertex - std::array dcaInfo{}; - auto trackPosPar = getTrackPar(trackPos); - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackPosPar, 2.f, fitter.getMatCorrType(), &dcaInfo); - auto trackPosDcaXY = dcaInfo[0]; - auto trackNegPar = getTrackPar(trackNeg); - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackNegPar, 2.f, fitter.getMatCorrType(), &dcaInfo); - auto trackNegDcaXY = dcaInfo[0]; - if (std::fabs(trackPosDcaXY) < cfgV0Cuts.dcaMaxDauToPv || std::fabs(trackNegDcaXY) < cfgV0Cuts.dcaMaxDauToPv) { - return false; - } - // vertex reconstruction - auto trackPosCov = getTrackParCov(trackPos); - auto trackNegCov = getTrackParCov(trackNeg); - int nCand = 0; - try { - nCand = fitter.process(trackPosCov, trackNegCov); - } catch (...) { - return false; - } - if (nCand == 0) { - return false; - } - // compute candidate momentum from tracks propagated to decay vertex - auto& trackPosProp = fitter.getTrack(0); - auto& trackNegProp = fitter.getTrack(1); - trackPosProp.getPxPyPzGlo(candidateV0.momPos); - trackNegProp.getPxPyPzGlo(candidateV0.momNeg); - - candidateV0.mom = RecoDecay::pVec(candidateV0.momPos, candidateV0.momNeg); - - candidateV0.pT = std::hypot(candidateV0.mom[0], candidateV0.mom[1]); - // topological selections: - // v0 eta - candidateV0.eta = RecoDecay::eta(candidateV0.mom); - if (std::abs(candidateV0.eta) > cfgV0Cuts.etaMax) { - return false; - } - // daughters DCA - candidateV0.dcaDau = std::sqrt(fitter.getChi2AtPCACandidate()); - if (candidateV0.dcaDau > cfgV0Cuts.dcaDau) { - return false; - } - // v0 radius - const auto& vtx = fitter.getPCACandidate(); - candidateV0.radius = std::hypot(vtx[0], vtx[1]); - if (candidateV0.radius < cfgV0Cuts.radiusMin) { - return false; - } - std::copy(vtx.begin(), vtx.end(), candidateV0.pos.begin()); - - // v0 DCA to primary vertex - candidateV0.dcaV0ToPv = calculateDCAStraightToPV( - vtx[0], vtx[1], vtx[2], - candidateV0.momPos[0] + candidateV0.momNeg[0], - candidateV0.momPos[1] + candidateV0.momNeg[1], - candidateV0.momPos[2] + candidateV0.momNeg[2], - collision.posX(), collision.posY(), collision.posZ()); - if (std::abs(candidateV0.dcaV0ToPv) > cfgV0Cuts.dcaPv) { - return false; - } - // v0 cosine of pointing angle - std::array const primVtx = {collision.posX(), collision.posY(), collision.posZ()}; - candidateV0.cosPA = RecoDecay::cpa(primVtx, vtx, candidateV0.mom); - if (candidateV0.cosPA < cfgV0Cuts.cosPa) { - return false; - } - // distinguish between K0s, and Lambda hypotesys - candidateV0.v0Type = {BIT(BachelorType::K0s) | BIT(BachelorType::Lambda) | BIT(BachelorType::AntiLambda)}; - // for lambda hypotesys define if its lambda or anti-lambda - candidateV0.alpha = alphaAP(candidateV0.mom, candidateV0.momPos, candidateV0.momNeg); - bool const matter = candidateV0.alpha > 0; - CLRBIT(candidateV0.v0Type, matter ? BachelorType::AntiLambda : BachelorType::Lambda); - auto massPos = matter ? o2::constants::physics::MassProton : o2::constants::physics::MassPionCharged; - auto massNeg = matter ? o2::constants::physics::MassPionCharged : o2::constants::physics::MassProton; - // mass hypotesis - candidateV0.mLambda = RecoDecay::m(std::array{candidateV0.momPos, candidateV0.momNeg}, std::array{massPos, massNeg}); - candidateV0.mK0Short = RecoDecay::m(std::array{candidateV0.momPos, candidateV0.momNeg}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged}); - if (std::fabs(candidateV0.mK0Short - MassK0) > cfgV0Cuts.deltaMassK0s) { - CLRBIT(candidateV0.v0Type, BachelorType::K0s); - } - if (std::fabs(candidateV0.mLambda - MassLambda0) > cfgV0Cuts.deltaMassLambda) { - CLRBIT(candidateV0.v0Type, BachelorType::Lambda); - CLRBIT(candidateV0.v0Type, BachelorType::AntiLambda); - } - // PID - if (TESTBIT(candidateV0.v0Type, BachelorType::K0s)) { - if ((trackPos.hasTPC() && std::fabs(trackPos.tpcNSigmaPi()) > cfgV0Cuts.nSigmaTpc) || - (trackNeg.hasTPC() && std::fabs(trackNeg.tpcNSigmaPi()) > cfgV0Cuts.nSigmaTpc)) { - CLRBIT(candidateV0.v0Type, BachelorType::K0s); - } - } - if (TESTBIT(candidateV0.v0Type, BachelorType::Lambda)) { - if ((trackPos.hasTPC() && std::fabs(trackPos.tpcNSigmaPr()) > cfgV0Cuts.nSigmaTpc) || - (trackPos.hasTOF() && std::fabs(trackPos.tofNSigmaPr()) > cfgV0Cuts.nSigmaTofPr) || - (trackNeg.hasTPC() && std::fabs(trackNeg.tpcNSigmaPi()) > cfgV0Cuts.nSigmaTpc)) { - CLRBIT(candidateV0.v0Type, BachelorType::Lambda); - } - } - if (TESTBIT(candidateV0.v0Type, BachelorType::AntiLambda)) { - if ((trackPos.hasTPC() && std::fabs(trackPos.tpcNSigmaPi()) > cfgV0Cuts.nSigmaTpc) || - (trackNeg.hasTPC() && std::fabs(trackNeg.tpcNSigmaPr()) > cfgV0Cuts.nSigmaTpc) || - (trackNeg.hasTOF() && std::fabs(trackNeg.tofNSigmaPr()) > cfgV0Cuts.nSigmaTofPr)) { - CLRBIT(candidateV0.v0Type, BachelorType::AntiLambda); - } - } - if (candidateV0.v0Type == 0) { - return false; - } - return true; - } - - /// Basic selection of tracks - /// \param track is the track - /// \param dDaughtersIds are the IDs of the D meson daughter tracks - /// \return true if passes all cuts - template - bool isTrackSelected(const Tr& track, const std::array& dDaughtersIds) - { - if (rejectPairsWithCommonDaughter && std::find(dDaughtersIds.begin(), dDaughtersIds.end(), track.globalIndex()) != dDaughtersIds.end()) { - return false; - } - switch (cfgSingleTrackCuts.setTrackSelections) { - case 1: - if (!track.isGlobalTrackWoDCA()) { - return false; - } - break; - case 2: - if (!track.isGlobalTrack()) { - return false; - } - break; - case 3: - if (!track.isQualityTrackITS()) { - return false; - } - break; - } - if (track.pt() < cfgSingleTrackCuts.minPt) { - return false; - } - if (std::abs(track.eta()) > cfgSingleTrackCuts.maxEta) { - return false; - } - if (!track.hasTPC()) { - return false; - } - bool const isPion = std::abs(track.tpcNSigmaPi()) < cfgSingleTrackCuts.maxNsigmaTpcPi; - bool const isKaon = std::abs(track.tpcNSigmaKa()) < cfgSingleTrackCuts.maxNsigmaTpcKa; - bool const isProton = std::abs(track.tpcNSigmaPr()) < cfgSingleTrackCuts.maxNsigmaTpcPr; - return (isPion || isKaon || isProton); // we keep the track if is it compatible with at least one of the PID hypotheses selected - } - - template - int8_t getMatchingFlagV0(PParticles const& particlesMc, const std::array& arrDaughtersV0) - { - int8_t signV0{0}; - int indexRec{-1}; - int flagV0{0}; - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersV0, kK0, std::array{+kPiPlus, -kPiPlus}, true, &signV0, 2); - if (indexRec > -1) { - flagV0 = hf_decay::hf_cand_reso::PartialMatchMc::K0Matched; - } else { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersV0, kLambda0, std::array{+kProton, -kPiPlus}, true, &signV0, 2); - if (indexRec > -1) { - flagV0 = signV0 * hf_decay::hf_cand_reso::PartialMatchMc::LambdaMatched; - } - } - return flagV0; // Placeholder, should return the actual flag based on matching logic - } - - template - float computeInvMassGen(PParticles const& particlesMc, int indexRec) - { - auto particleReso = particlesMc.iteratorAt(indexRec); - auto dau1 = particlesMc.iteratorAt(particleReso.daughtersIds().front()); - auto dau2 = particlesMc.iteratorAt(particleReso.daughtersIds().back()); - std::array, 2> pArr = {{{dau1.px(), dau1.py(), dau1.pz()}, {dau2.px(), dau2.py(), dau2.pz()}}}; - std::array mArr = {static_cast(pdg->Mass(dau1.pdgCode())), static_cast(pdg->Mass(dau2.pdgCode()))}; - return static_cast(RecoDecay::m(pArr, mArr)); - } - - /// Function for filling MC reco information of DV0 candidates in the tables - /// \tparam dType is the D meson type (Dstar, Dplus or D0) - /// \param particlesMc is the table with MC particles - /// \param candCharmBach is the D meson candidate - /// \param bachelorV0 is the V0 candidate - /// \param tracks is the table with tracks - /// \param indexHfCandCharm is the index of the charm-hadron bachelor in the reduced table - /// \param indexCandV0TrBach is the index of the v0 bachelor in the reduced table - template - void fillMcRecoInfoDV0(PParticles const& particlesMc, - CCand const& candCharmBach, - BBachV0 const& bachelorV0, - Tr const& tracks, - int& indexHfCandCharm, - int64_t& indexCandV0Bach) - { - std::vector vecDaughtersReso{}; - int8_t sign{0}, nKinkedTracks{0}, origin{0}, flagCharmBach{0}, flagCharmBachInterm{0}, flagV0{0}, flagReso{0}; - int indexRec{-1}, debugMcRec{0}; - float ptGen{-1.f}, invMassGen{-1.f}; - if constexpr (DType == DType::Dstar) { - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prongPiId())); - // Check if D* is matched - flagCharmBach = candCharmBach.flagMcMatchRec(); - if (flagCharmBach != 0) { - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::DstarMatched); - origin = candCharmBach.originMcRec(); - } - // Check if D0 is matched - flagCharmBachInterm = candCharmBach.flagMcMatchRecD0(); - if (flagCharmBachInterm != 0) { - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::D0Matched); - } - // Check if V0 is matched - vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.posTrackId())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.negTrackId())); - flagV0 = getMatchingFlagV0(particlesMc, std::array{vecDaughtersReso[3], vecDaughtersReso[4]}); - if (flagV0 != 0) { - SETBIT(debugMcRec, std::abs(flagV0)); - } - // If both D* and K0s are matched, try to match resonance - if (flagCharmBach != 0 && flagV0 == hf_decay::hf_cand_reso::PartialMatchMc::K0Matched) { - std::array const pdgCodesDaughters = {+kPiPlus, -kKPlus, +kPiPlus, +kPiPlus, -kPiPlus}; - auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], vecDaughtersReso[3], vecDaughtersReso[4]}; - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarK0s) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; - break; - } - } - } else if (flagCharmBachInterm != 0 && flagV0 == hf_decay::hf_cand_reso::PartialMatchMc::K0Matched) { - std::array const pdgCodesDaughters = {+kPiPlus, -kKPlus, +kPiPlus, -kPiPlus}; - auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[3], vecDaughtersReso[4]}; - // Peaking background of D0K0s <- Ds* with spurious soft pion - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarK0s) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::ResoPartlyMatched); - break; - } - } - } - // No physical channel expected in D*Lambda - if (indexRec > -1) { - auto particleReso = particlesMc.iteratorAt(indexRec); - ptGen = particleReso.pt(); - invMassGen = computeInvMassGen(particlesMc, indexRec); - } - rowHfDstarV0McRecReduced(indexHfCandCharm, indexCandV0Bach, - flagReso, flagCharmBach, - flagCharmBachInterm, debugMcRec, - origin, ptGen, invMassGen, - nKinkedTracks); - } else if constexpr (DType == DType::Dplus) { - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong2Id())); - // Check if D+ is matched - flagCharmBach = candCharmBach.flagMcMatchRec(); - flagCharmBachInterm = candCharmBach.flagMcDecayChanRec(); - if (flagCharmBach != 0) { - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::DplusMatched); - origin = candCharmBach.originMcRec(); - } - // Check if V0 is matched - vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.posTrackId())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.negTrackId())); - flagV0 = getMatchingFlagV0(particlesMc, std::array{vecDaughtersReso[3], vecDaughtersReso[4]}); - if (flagV0 != 0) { - SETBIT(debugMcRec, std::abs(flagV0)); - } - // If both D+ and K0s are matched, try to match resonance - if (hf_decay::hf_cand_3prong::daughtersDplusMain.contains(static_cast(std::abs(flagCharmBach))) && flagV0 == hf_decay::hf_cand_reso::PartialMatchMc::K0Matched) { - auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], vecDaughtersReso[3], vecDaughtersReso[4]}; - auto pdgCodesDplusDaughters = hf_decay::hf_cand_3prong::daughtersDplusMain.at(static_cast(std::abs(flagCharmBach))); - auto pdgCodesDaughters = std::array{pdgCodesDplusDaughters[0], pdgCodesDplusDaughters[1], pdgCodesDplusDaughters[2], +kPiPlus, -kPiPlus}; - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusK0s) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; - break; - } - } - // Partial matching of Dsj -> D*K0s -> (D+ pi0) (K0s) with missing neutral - if (indexRec < 0) { - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarK0s) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::ResoPartlyMatched); - break; - } - } - } - - } else if (hf_decay::hf_cand_3prong::daughtersDplusMain.contains(static_cast(std::abs(flagCharmBach))) && std::abs(flagV0) == hf_decay::hf_cand_reso::PartialMatchMc::LambdaMatched) { - // Peaking background of D+Lambda <- Ds* with spurious soft pion - auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], vecDaughtersReso[3], vecDaughtersReso[4]}; - auto pdgCodesDplusDaughters = hf_decay::hf_cand_3prong::daughtersDplusMain.at(static_cast(std::abs(flagCharmBach))); - auto pdgCodesDaughters = std::array{pdgCodesDplusDaughters[0], pdgCodesDplusDaughters[1], pdgCodesDplusDaughters[2], +kProton, -kPiPlus}; - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusLambda) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; - break; - } - } - } - if (indexRec > -1) { - auto particleReso = particlesMc.iteratorAt(indexRec); - ptGen = particleReso.pt(); - invMassGen = computeInvMassGen(particlesMc, indexRec); - } - rowHf3PrV0McRecReduced(indexHfCandCharm, indexCandV0Bach, - flagReso, flagCharmBach, - flagCharmBachInterm, debugMcRec, - origin, ptGen, invMassGen, - nKinkedTracks); - } else if constexpr (DType == DType::D0) { - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); - // Check if D0 is matched - flagCharmBach = candCharmBach.flagMcMatchRec(); - flagCharmBachInterm = candCharmBach.flagMcDecayChanRec(); - if (flagCharmBach != 0) { - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::D0Matched); - origin = candCharmBach.originMcRec(); - } - // Check if V0 is matched - vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.posTrackId())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.negTrackId())); - flagV0 = getMatchingFlagV0(particlesMc, std::array{vecDaughtersReso[2], vecDaughtersReso[3]}); - if (flagV0 != 0) { - SETBIT(debugMcRec, std::abs(flagV0)); - } - // No physical channel expected in D0 K0s - // If both D0 and Lambda are matched, try to match resonance - if (hf_decay::hf_cand_2prong::daughtersD0Main.contains(static_cast(std::abs(flagCharmBach))) && std::abs(flagV0) == hf_decay::hf_cand_reso::PartialMatchMc::LambdaMatched) { - auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], vecDaughtersReso[3]}; - auto pdgCodesDzeroDaughters = hf_decay::hf_cand_2prong::daughtersD0Main.at(static_cast(std::abs(flagCharmBach))); - auto pdgCodesDaughters = std::array{pdgCodesDzeroDaughters[0], pdgCodesDzeroDaughters[1], +kProton, -kPiPlus}; - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Lambda) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; - break; - } - } - } - if (indexRec > -1) { - auto particleReso = particlesMc.iteratorAt(indexRec); - ptGen = particleReso.pt(); - invMassGen = computeInvMassGen(particlesMc, indexRec); - } - rowHf2PrV0McRecReduced(indexHfCandCharm, indexCandV0Bach, - flagReso, flagCharmBach, - flagCharmBachInterm, debugMcRec, - origin, ptGen, invMassGen, - nKinkedTracks); - } - registry.fill(HIST("hMCRecDebug"), debugMcRec); - if (indexRec > -1) { - registry.fill(HIST("hMCRecCounter"), flagReso); - registry.fill(HIST("hMCRecOrigin"), origin); - registry.fill(HIST("hMCRecMassGen"), invMassGen); - } - if (flagCharmBach != 0) { - registry.fill(HIST("hMCRecCharmDau"), flagCharmBach); - } - } - - template - int8_t getMatchingFlagTrack(Tr const& bachTrack) - { - auto particle = bachTrack.mcParticle(); - auto pdgCode = std::abs(particle.pdgCode()); - if (pdgCode == kPiPlus) { - return hf_decay::hf_cand_reso::PartialMatchMc::PionMatched; - } - if (pdgCode == kKPlus) { - return hf_decay::hf_cand_reso::PartialMatchMc::KaonMatched; - } - if (pdgCode == kProton) { - return hf_decay::hf_cand_reso::PartialMatchMc::ProtonMatched; - } - return 0; - } - // Function for filling MC reco information of D Track candidates in the tables - /// \tparam dType is the D meson type (Dstar, Dplus or D0) - /// \param particlesMc is the table with MC particles - /// \param candCharmBach is the D meson candidate - /// \param bachelorTrack is the bachelor track - /// \param tracks is the table with tracks - /// \param indexHfCandCharm is the index of the charm-hadron bachelor in the reduced table - /// \param indexCandTrBach is the index of the v0 bachelor in the reduced table - template - void fillMcRecoInfoDTrack(PParticles const& particlesMc, - CCand const& candCharmBach, - BBachTr const& bachelorTrack, - Tr const& tracks, - const int64_t indexHfCandCharm, - const int64_t indexCandTrBach) - { - std::vector vecDaughtersReso{}; - int8_t sign{0}, nKinkedTracks{0}, origin{0}, flagCharmBach{0}, flagCharmBachInterm{0}, flagTrack{0}, flagReso{0}; - int indexRec{-1}; - uint16_t debugMcRec{0}; - float ptGen{-1.f}, invMassGen{-1.f}; - if constexpr (DType == DType::Dstar) { - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prongPiId())); - // Check if D* is matched - flagCharmBach = candCharmBach.flagMcMatchRec(); - if (flagCharmBach != 0) { - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::DstarMatched); - origin = candCharmBach.originMcRec(); - } - // Check if D0 is matched - flagCharmBachInterm = candCharmBach.flagMcMatchRecD0(); - if (flagCharmBachInterm != 0) { - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::D0Matched); - } - // Check if Track is matched - flagTrack = getMatchingFlagTrack(bachelorTrack); - if (flagTrack != 0) { - SETBIT(debugMcRec, flagTrack); - } - // If both D* and Track are matched, try to match resonance - if (flagCharmBach != 0 && flagTrack == hf_decay::hf_cand_reso::PartialMatchMc::PionMatched) { - auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], bachelorTrack}; - auto pdgCodesDaughters = std::array{+kPiPlus, -kKPlus, +kPiPlus, -kPiPlus}; - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarPi) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; - break; - } - } - } - // No channels in D*K+ or D*Pr - if (indexRec > -1) { - auto particleReso = particlesMc.iteratorAt(indexRec); - ptGen = particleReso.pt(); - invMassGen = computeInvMassGen(particlesMc, indexRec); - } - rowHfDstarTrkMcRecReduced(indexHfCandCharm, indexCandTrBach, - flagReso, flagCharmBach, - flagCharmBachInterm, debugMcRec, - origin, ptGen, invMassGen, - nKinkedTracks); - } else if constexpr (DType == DType::Dplus) { - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong2Id())); - // Check if D+ is matched - flagCharmBach = candCharmBach.flagMcMatchRec(); - flagCharmBachInterm = candCharmBach.flagMcDecayChanRec(); - if (flagCharmBach != 0) { - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::DplusMatched); - origin = candCharmBach.originMcRec(); - } - // Check if Track is matched - flagTrack = getMatchingFlagTrack(bachelorTrack); - if (flagTrack != 0) { - SETBIT(debugMcRec, flagTrack); - } - // If both D+ and Track are matched, try to match resonance - if (hf_decay::hf_cand_3prong::daughtersDplusMain.contains(static_cast(std::abs(flagCharmBach))) && flagTrack == hf_decay::hf_cand_reso::PartialMatchMc::PionMatched) { - auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], bachelorTrack}; - auto pdgCodesDplusDaughters = hf_decay::hf_cand_3prong::daughtersDplusMain.at(static_cast(std::abs(flagCharmBach))); - auto pdgCodesDaughters = std::array{pdgCodesDplusDaughters[0], pdgCodesDplusDaughters[1], pdgCodesDplusDaughters[2], -kPiPlus}; - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusPi) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; - break; - } - } - // Partial matching of Dj -> D*Pi -> (D+ pi0) (pi) with missing neutral - if (indexRec < 0) { - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarPi) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::ResoPartlyMatched); - break; - } - } - } - } - // No channels in D+K+ or D+Pr - if (indexRec > -1) { - auto particleReso = particlesMc.iteratorAt(indexRec); - ptGen = particleReso.pt(); - invMassGen = computeInvMassGen(particlesMc, indexRec); - } - rowHf3PrTrkMcRecReduced(indexHfCandCharm, indexCandTrBach, - flagReso, flagCharmBach, - flagCharmBachInterm, debugMcRec, - origin, ptGen, invMassGen, - nKinkedTracks); - } else if constexpr (DType == DType::D0) { - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); - // Check if D0 is matched - flagCharmBach = candCharmBach.flagMcMatchRec(); - flagCharmBachInterm = candCharmBach.flagMcDecayChanRec(); - if (flagCharmBach != 0) { - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::D0Matched); - origin = candCharmBach.originMcRec(); - } - flagTrack = getMatchingFlagTrack(bachelorTrack); - if (flagTrack != 0) { - SETBIT(debugMcRec, flagTrack); - } - if (hf_decay::hf_cand_2prong::daughtersD0Main.contains(static_cast(std::abs(flagCharmBach))) && flagTrack == hf_decay::hf_cand_reso::PartialMatchMc::PionMatched) { - auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], bachelorTrack}; - auto pdgCodesDzeroDaughters = hf_decay::hf_cand_2prong::daughtersD0Main.at(static_cast(std::abs(flagCharmBach))); - auto pdgCodesDaughters = std::array{pdgCodesDzeroDaughters[0], pdgCodesDzeroDaughters[1], +kPiPlus}; - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Pi) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; - break; - } - } - // Partial matching of Dj -> D*Pi -> (D0 pi) (pi) with missing pion - if (indexRec < 0) { - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarPi) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::ResoPartlyMatched); - break; - } - } - } - } else if (hf_decay::hf_cand_2prong::daughtersD0Main.contains(static_cast(std::abs(flagCharmBach))) && flagTrack == hf_decay::hf_cand_reso::PartialMatchMc::KaonMatched) { - auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], bachelorTrack}; - auto pdgCodesDzeroDaughters = hf_decay::hf_cand_2prong::daughtersD0Main.at(static_cast(std::abs(flagCharmBach))); - auto pdgCodesDaughters = std::array{pdgCodesDzeroDaughters[0], pdgCodesDzeroDaughters[1], +kKPlus}; - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Kplus) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; - break; - } - } - } - if (indexRec > -1) { - auto particleReso = particlesMc.iteratorAt(indexRec); - ptGen = particleReso.pt(); - invMassGen = computeInvMassGen(particlesMc, indexRec); - } - rowHf2PrTrkMcRecReduced(indexHfCandCharm, indexCandTrBach, - flagReso, flagCharmBach, - flagCharmBachInterm, debugMcRec, - origin, ptGen, invMassGen, - nKinkedTracks); - } - registry.fill(HIST("hMCRecDebug"), debugMcRec); - if (indexRec > -1) { - registry.fill(HIST("hMCRecCounter"), flagReso); - registry.fill(HIST("hMCRecOrigin"), origin); - registry.fill(HIST("hMCRecMassGen"), invMassGen); - } - if (flagCharmBach != 0) { - registry.fill(HIST("hMCRecCharmDau"), flagCharmBach); - } - } // fillMcRecoInfoDTrack - - template - void runDataCreation(Coll const& collision, - CCands const& candsD, - BBachV0s const& bachelorV0s, - BBachTracks const& bachelorTrks, - Tr const& tracks, - TrIU const& tracksIU, - PParticles const& particlesMc, - BCs const&) - { - // helpers for ReducedTables filling - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); - if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { - return; - } - int const indexHfReducedCollision = hfReducedCollision.lastIndex() + 1; - // std::map where the key is the V0.globalIndex() and - // the value is the V0 index in the table of the selected v0s - std::map selectedV0s; - std::map selectedTracks; - bool fillHfReducedCollision = false; - constexpr bool DoTracks = PairingType == PairingType::TrackOnly || PairingType == PairingType::V0AndTrack; - constexpr bool DoV0s = PairingType == PairingType::V0Only || PairingType == PairingType::V0AndTrack; - auto bc = collision.template bc_as(); - if (runNumber != bc.runNumber()) { - LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; - initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); - bz = o2::base::Propagator::Instance()->getNominalBz(); - LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; - } - fitter.setBz(bz); - // loop on D candidates - for (const auto& candD : candsD) { - // initialize variables depending on D meson type - bool fillHfCandD = false; - std::array secondaryVertexD{}; - std::array prongIdsD{}; - std::array bdtScores = {-1.f, -1.f, -1.f, -1.f, -1.f, -1.f}; - std::vector> charmHadDauTracks{}; - varUtils.ptD = candD.pt(); - if constexpr (DType == DType::Dstar) { - varUtils.signD = candD.signSoftPi(); - if (varUtils.signD > 0) { - varUtils.invMassD = candD.invMassDstar(); - varUtils.invMassD0 = candD.invMassD0(); - } else { - varUtils.invMassD = candD.invMassAntiDstar(); - varUtils.invMassD0 = candD.invMassD0Bar(); - } - secondaryVertexD[0] = candD.xSecondaryVertexD0(); - secondaryVertexD[1] = candD.ySecondaryVertexD0(); - secondaryVertexD[2] = candD.zSecondaryVertexD0(); - prongIdsD[0] = candD.prong0Id(); - prongIdsD[1] = candD.prong1Id(); - prongIdsD[2] = candD.prongPiId(); - varUtils.pVectorProng0 = candD.pVectorProng0(); - varUtils.pVectorProng1 = candD.pVectorProng1(); - varUtils.pVectorProng2 = candD.pVecSoftPi(); - charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong0Id())); - charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong1Id())); - if constexpr (WithMl) { - std::copy(candD.mlProbDstarToD0Pi().begin(), candD.mlProbDstarToD0Pi().end(), bdtScores.begin()); - } - registry.fill(HIST("hMassVsPtDstarAll"), varUtils.ptD, varUtils.invMassD - varUtils.invMassD0); - } else if constexpr (DType == DType::Dplus) { - auto prong0 = tracksIU.rawIteratorAt(candD.prong0Id()); - varUtils.invMassD = HfHelper::invMassDplusToPiKPi(candD); - secondaryVertexD[0] = candD.xSecondaryVertex(); - secondaryVertexD[1] = candD.ySecondaryVertex(); - secondaryVertexD[2] = candD.zSecondaryVertex(); - prongIdsD[0] = candD.prong0Id(); - prongIdsD[1] = candD.prong1Id(); - prongIdsD[2] = candD.prong2Id(); - varUtils.signD = prong0.sign(); - varUtils.pVectorProng0 = candD.pVectorProng0(); - varUtils.pVectorProng1 = candD.pVectorProng1(); - varUtils.pVectorProng2 = candD.pVectorProng2(); - charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong0Id())); - charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong1Id())); - charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong2Id())); - if constexpr (WithMl) { - std::copy(candD.mlProbDplusToPiKPi().begin(), candD.mlProbDplusToPiKPi().end(), bdtScores.begin()); - } - registry.fill(HIST("hMassVsPtDplusAll"), varUtils.ptD, varUtils.invMassD); - } else if constexpr (DType == DType::D0) { - varUtils.invMassD0 = HfHelper::invMassD0ToPiK(candD); - varUtils.invMassD0Bar = HfHelper::invMassD0barToKPi(candD); - secondaryVertexD[0] = candD.xSecondaryVertex(); - secondaryVertexD[1] = candD.ySecondaryVertex(); - secondaryVertexD[2] = candD.zSecondaryVertex(); - prongIdsD[0] = candD.prong0Id(); - prongIdsD[1] = candD.prong1Id(); - prongIdsD[2] = -1; // D0 does not have a third prong - charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong0Id())); - charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong1Id())); - varUtils.pVectorProng0 = candD.pVectorProng0(); - varUtils.pVectorProng1 = candD.pVectorProng1(); - varUtils.pVectorProng2 = {0.f, 0.f, 0.f}; // D0 does not have a third prong - if constexpr (WithMl) { - std::copy(candD.mlProbD0().begin(), candD.mlProbD0().end(), bdtScores.begin()); - std::copy(candD.mlProbD0bar().begin(), candD.mlProbD0bar().end(), bdtScores.begin() + 3); - } - if (candD.isSelD0() >= cfgDmesCuts.selectionFlagD0) { - registry.fill(HIST("hMassVsPtD0All"), varUtils.ptD, varUtils.invMassD0); - } - if (candD.isSelD0bar() >= cfgDmesCuts.selectionFlagD0Bar) { - registry.fill(HIST("hMassVsPtD0BarAll"), varUtils.ptD, varUtils.invMassD0Bar); - } - } // end of dType switch - - // Get single track variables - float chi2TpcDauMax = -1.f; - int nItsClsDauMin = 8, nTpcCrossRowsDauMin = 200; - float chi2TpcSoftPi = -1.f; - int nItsClsSoftPi = 8, nTpcCrossRowsSoftPi = 200; - for (const auto& charmHadTrack : charmHadDauTracks) { - if (charmHadTrack.itsNCls() < nItsClsDauMin) { - nItsClsDauMin = charmHadTrack.itsNCls(); - } - if (charmHadTrack.tpcNClsCrossedRows() < nTpcCrossRowsDauMin) { - nTpcCrossRowsDauMin = charmHadTrack.tpcNClsCrossedRows(); - } - if (charmHadTrack.tpcChi2NCl() > chi2TpcDauMax) { - chi2TpcDauMax = charmHadTrack.tpcChi2NCl(); - } - } - if constexpr (DType == DType::Dstar) { - auto softPi = tracksIU.rawIteratorAt(candD.prongPiId()); - nItsClsSoftPi = softPi.itsNCls(); - nTpcCrossRowsSoftPi = softPi.tpcNClsCrossedRows(); - chi2TpcSoftPi = softPi.tpcChi2NCl(); - charmHadDauTracks.push_back(softPi); - } - // Loop on the bachelor V0s - if constexpr (DoV0s) { - for (const auto& v0 : bachelorV0s) { - auto trackPos = tracksIU.rawIteratorAt(v0.posTrackId()); - auto trackNeg = tracksIU.rawIteratorAt(v0.negTrackId()); - // Apply selsection - auto v0DauTracks = std::array{trackPos, trackNeg}; - if (!buildAndSelectV0(collision, prongIdsD, v0DauTracks)) { - continue; - } - // Get single track variables - float chi2TpcDauV0Max = -1.f; - int nItsClsDauV0Min = 8, nTpcCrossRowsDauV0Min = 200; - for (const auto& v0Track : v0DauTracks) { - if (v0Track.itsNCls() < nItsClsDauV0Min) { - nItsClsDauV0Min = v0Track.itsNCls(); - } - if (v0Track.tpcNClsCrossedRows() < nTpcCrossRowsDauV0Min) { - nTpcCrossRowsDauV0Min = v0Track.tpcNClsCrossedRows(); - } - if (v0Track.tpcChi2NCl() > chi2TpcDauV0Max) { - chi2TpcDauV0Max = v0Track.tpcChi2NCl(); - } - } - // propagate V0 to primary vertex (if enabled) - if (propagateV0toPV) { - std::array const pVecV0Orig = {candidateV0.mom[0], candidateV0.mom[1], candidateV0.mom[2]}; - std::array dcaInfo{}; - auto trackParK0 = o2::track::TrackPar(candidateV0.pos, pVecV0Orig, 0, true); - trackParK0.setPID(o2::track::PID::K0); - trackParK0.setAbsCharge(0); - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParK0, 2.f, matCorr, &dcaInfo); - getPxPyPz(trackParK0, candidateV0.mom); - } - // compute resonance invariant mass and filling of QA histograms - if (TESTBIT(candidateV0.v0Type, BachelorType::K0s)) { - registry.fill(HIST("hMassVsPtK0s"), candidateV0.pT, candidateV0.mK0Short); - switch (DType) { - case DType::Dstar: - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candidateV0.mom)); - if (varUtils.signD > 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candidateV0.mom}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassK0}); - } else { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, candidateV0.mom}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassK0}); - } - if (!cfgQaPlots.applyCutsForQaHistograms || - (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin && - varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax && - candidateV0.mK0Short > cfgQaPlots.cutMassK0sMin && - candidateV0.mK0Short < cfgQaPlots.cutMassK0sMax)) { - registry.fill(HIST("hMassDstarK0s"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); - } - break; - case DType::Dplus: - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candidateV0.mom}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassK0}); - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candidateV0.mom)); - if (!cfgQaPlots.applyCutsForQaHistograms || - (varUtils.invMassD > cfgQaPlots.cutMassDMin && - varUtils.invMassD < cfgQaPlots.cutMassDMax && - candidateV0.mK0Short > cfgQaPlots.cutMassK0sMin && - candidateV0.mK0Short < cfgQaPlots.cutMassK0sMax)) { - registry.fill(HIST("hMassDplusK0s"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); - } - break; - default: - break; // no other D meson types expected - } // end of dType switch - } // matched with K0s - bool const isLambda = TESTBIT(candidateV0.v0Type, BachelorType::Lambda); - bool const isAntiLambda = TESTBIT(candidateV0.v0Type, BachelorType::AntiLambda); - if (isLambda || isAntiLambda) { - registry.fill(HIST("hMassVsPtLambda"), candidateV0.pT, candidateV0.mLambda); - switch (DType) { - case DType::Dstar: - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candidateV0.mom)); - if (varUtils.signD > 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candidateV0.mom}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassLambda}); - } else { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, candidateV0.mom}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassLambda}); - } - if (!cfgQaPlots.applyCutsForQaHistograms || - (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin && - varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax && - candidateV0.mLambda > cfgQaPlots.cutMassLambdaMin && - candidateV0.mLambda < cfgQaPlots.cutMassLambdaMax)) { - registry.fill(HIST("hMassDstarLambda"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); - } - break; - case DType::Dplus: - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candidateV0.mom}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassLambda}); - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candidateV0.mom)); - if (!cfgQaPlots.applyCutsForQaHistograms || - (varUtils.invMassD > cfgQaPlots.cutMassDMin && - varUtils.invMassD < cfgQaPlots.cutMassDMax && - candidateV0.mLambda > cfgQaPlots.cutMassLambdaMin && - candidateV0.mLambda < cfgQaPlots.cutMassLambdaMax)) { - registry.fill(HIST("hMassDplusLambda"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); - } - break; - case DType::D0: - if (isLambda) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, candidateV0.mom}, std::array{MassPiPlus, MassKPlus, MassLambda}); - } else { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, candidateV0.mom}, std::array{MassPiPlus, MassKPlus, MassLambda}); - } - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, candidateV0.mom)); - if (!cfgQaPlots.applyCutsForQaHistograms || - (((varUtils.invMassD0 > cfgQaPlots.cutMassDMin && varUtils.invMassD0 < cfgQaPlots.cutMassDMax) || - (varUtils.invMassD0Bar > cfgQaPlots.cutMassDMin && varUtils.invMassD0Bar < cfgQaPlots.cutMassDMax)) && - candidateV0.mLambda > cfgQaPlots.cutMassLambdaMin && - candidateV0.mLambda < cfgQaPlots.cutMassLambdaMax)) { - if (isLambda) { - registry.fill(HIST("hMassD0Lambda"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0); - } else { - registry.fill(HIST("hMassD0Lambda"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0Bar); - } - } - break; - default: - break; - } // end of dType switch - } // matched with Lambda or AntiLambda - // fill V0 table - // if information on V0 already stored, go to next V0 - if (!selectedV0s.count(v0.globalIndex())) { - hfCandV0(trackPos.globalIndex(), trackNeg.globalIndex(), - indexHfReducedCollision, - candidateV0.pos[0], candidateV0.pos[1], candidateV0.pos[2], - candidateV0.momPos[0], candidateV0.momPos[1], candidateV0.momPos[2], - candidateV0.momNeg[0], candidateV0.momNeg[1], candidateV0.momNeg[2], - candidateV0.cosPA, - candidateV0.dcaV0ToPv, - nItsClsDauV0Min, nTpcCrossRowsDauV0Min, chi2TpcDauV0Max, - candidateV0.v0Type); - selectedV0s[v0.globalIndex()] = hfCandV0.lastIndex(); - } - fillHfCandD = true; - // Optional filling of MC Rec table, for now only implemented for Ds1->D*K0s and Ds2*->D+K0s - if constexpr (DoMc) { - int indexHfCandCharm{-1}; - if constexpr (DType == DType::Dstar) { - indexHfCandCharm = hfCandDstar.lastIndex() + 1; - } else if constexpr (DType == DType::Dplus) { - indexHfCandCharm = hfCandD3Pr.lastIndex() + 1; - } else if constexpr (DType == DType::D0) { - indexHfCandCharm = hfCandD2Pr.lastIndex() + 1; - } - fillMcRecoInfoDV0(particlesMc, candD, v0, tracksIU, indexHfCandCharm, selectedV0s[v0.globalIndex()]); - } - } // end of loop on V0 candidates - } // end of do V0s - // Loop on the bachelor tracks - if constexpr (DoTracks) { - for (const auto& trackIndex : bachelorTrks) { - auto track = tracks.rawIteratorAt(trackIndex.trackId()); - if (!isTrackSelected(track, prongIdsD)) { - continue; - } - // if the track has been reassociated, re-propagate it to PV (minor difference) - auto trackParCovTrack = getTrackParCov(track); - std::array dcaTrack{track.dcaXY(), track.dcaZ()}; - std::array pVecTrack = track.pVector(); - if (track.collisionId() != collision.globalIndex()) { - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParCovTrack, 2.f, matCorr, &dcaTrack); - getPxPyPz(trackParCovTrack, pVecTrack); - } - registry.fill(HIST("hdEdxVsP"), track.p(), track.tpcSignal()); - // compute invariant mass and filling of QA histograms - switch (DType) { - case DType::Dstar: - // D* pi - if (std::abs(track.tpcNSigmaPi()) < cfgSingleTrackCuts.maxNsigmaTpcPi) { - if (varUtils.signD > 0 && track.sign() < 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassPiPlus}); - } else if (varUtils.signD < 0 && track.sign() > 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassPiPlus}); - } else { - varUtils.invMassReso = -1.f; // invalid case - } - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); - if (!cfgQaPlots.applyCutsForQaHistograms || - (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin && - varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax)) { - registry.fill(HIST("hMassDstarPi"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); - } - } - if (std::abs(track.tpcNSigmaKa()) < cfgSingleTrackCuts.maxNsigmaTpcKa) { - if (varUtils.signD > 0 && track.sign() < 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassKPlus}); - } else if (varUtils.signD < 0 && track.sign() > 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassKPlus}); - } else { - varUtils.invMassReso = -1.f; // invalid case - } - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); - if (!cfgQaPlots.applyCutsForQaHistograms || - (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin && - varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax)) { - registry.fill(HIST("hMassDstarK"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); - } - } - // D* p - if (std::abs(track.tpcNSigmaPr()) < cfgSingleTrackCuts.maxNsigmaTpcPr) { - if (varUtils.signD > 0 && track.sign() > 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassProton}); - } else if (varUtils.signD < 0 && track.sign() < 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassProton}); - } else { - varUtils.invMassReso = -1.f; // invalid case - } - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); - if (!cfgQaPlots.applyCutsForQaHistograms || - (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin && - varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax)) { - registry.fill(HIST("hMassDstarProton"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); - } - } - break; - case DType::Dplus: - // D+ pi - if (std::abs(track.tpcNSigmaPi()) < cfgSingleTrackCuts.maxNsigmaTpcPi) { - if (varUtils.signD * track.sign() < 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassPiPlus}); - } else { - varUtils.invMassReso = -1.f; // invalid case - } - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); - if (!cfgQaPlots.applyCutsForQaHistograms || - (varUtils.invMassD > cfgQaPlots.cutMassDMin && - varUtils.invMassD < cfgQaPlots.cutMassDMax)) { - registry.fill(HIST("hMassDplusPi"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); - } - } - // D+ K - if (std::abs(track.tpcNSigmaKa()) < cfgSingleTrackCuts.maxNsigmaTpcKa) { - if (varUtils.signD * track.sign() < 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassKPlus}); - } else { - varUtils.invMassReso = -1.f; // invalid case - } - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); - if (!cfgQaPlots.applyCutsForQaHistograms || - (varUtils.invMassD > cfgQaPlots.cutMassDMin && - varUtils.invMassD < cfgQaPlots.cutMassDMax)) { - registry.fill(HIST("hMassDplusK"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); - } - } - // D+ pr - if (std::abs(track.tpcNSigmaPr()) < cfgSingleTrackCuts.maxNsigmaTpcPr) { - if (varUtils.signD * track.sign() < 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassProton}); - } else { - varUtils.invMassReso = -1.f; // invalid case - } - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); - if (!cfgQaPlots.applyCutsForQaHistograms || - (varUtils.invMassD > cfgQaPlots.cutMassDMin && - varUtils.invMassD < cfgQaPlots.cutMassDMax)) { - registry.fill(HIST("hMassDplusProton"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); - } - } - break; - case DType::D0: - // D0 pi - if (std::abs(track.tpcNSigmaPi()) < cfgSingleTrackCuts.maxNsigmaTpcPi) { - if (track.sign() > 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus}); - } else { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus}); - } - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack)); - if (!cfgQaPlots.applyCutsForQaHistograms || - ((varUtils.invMassD0 > cfgQaPlots.cutMassDMin && - varUtils.invMassD0 < cfgQaPlots.cutMassDMax) || - (varUtils.invMassD0Bar > cfgQaPlots.cutMassDMin && - varUtils.invMassD0Bar < cfgQaPlots.cutMassDMax))) { - if (track.sign() > 0) { - registry.fill(HIST("hMassD0Pi"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0); - } else { - registry.fill(HIST("hMassD0Pi"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0Bar); - } - } - } - // D0 K - if (std::abs(track.tpcNSigmaKa()) < cfgSingleTrackCuts.maxNsigmaTpcKa) { - if (track.sign() > 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassKPlus}); - } else { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassKPlus}); - } - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack)); - if (!cfgQaPlots.applyCutsForQaHistograms || - ((varUtils.invMassD0 > cfgQaPlots.cutMassDMin && - varUtils.invMassD0 < cfgQaPlots.cutMassDMax) || - (varUtils.invMassD0Bar > cfgQaPlots.cutMassDMin && - varUtils.invMassD0Bar < cfgQaPlots.cutMassDMax))) { - if (track.sign() > 0) { - registry.fill(HIST("hMassD0K"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0); - } else { - registry.fill(HIST("hMassD0K"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0Bar); - } - } - } - // D0 p - if (std::abs(track.tpcNSigmaPr()) < cfgSingleTrackCuts.maxNsigmaTpcPr) { - if (track.sign() > 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassProton}); - } else { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassProton}); - } - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack)); - if (!cfgQaPlots.applyCutsForQaHistograms || - ((varUtils.invMassD0 > cfgQaPlots.cutMassDMin && - varUtils.invMassD0 < cfgQaPlots.cutMassDMax) || - (varUtils.invMassD0Bar > cfgQaPlots.cutMassDMin && - varUtils.invMassD0Bar < cfgQaPlots.cutMassDMax))) { - if (track.sign() > 0) { - registry.fill(HIST("hMassD0Proton"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0); - } else { - registry.fill(HIST("hMassD0Proton"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0Bar); - } - } - } - break; - default: - break; // no other D meson types expected - } // end of DType switch - // fill track table - if (!selectedTracks.count(track.globalIndex())) { - hfTrackNoParam(track.globalIndex(), - indexHfReducedCollision, - track.px(), track.py(), track.pz(), track.sign(), - track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr(), - track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr(), - track.hasTOF(), track.hasTPC(), track.itsNCls(), track.tpcNClsCrossedRows(), track.tpcChi2NCl()); - selectedTracks[track.globalIndex()] = hfTrackNoParam.lastIndex(); - } - fillHfCandD = true; - if constexpr (DoMc) { - int indexHfCandCharm{-1}; - if constexpr (DType == DType::Dstar) { - indexHfCandCharm = hfCandDstar.lastIndex() + 1; - } else if constexpr (DType == DType::Dplus) { - indexHfCandCharm = hfCandD3Pr.lastIndex() + 1; - } else if constexpr (DType == DType::D0) { - indexHfCandCharm = hfCandD2Pr.lastIndex() + 1; - } - fillMcRecoInfoDTrack(particlesMc, candD, track, tracks, indexHfCandCharm, selectedTracks[track.globalIndex()]); - } - } // end of loop on bachelor tracks - } // end of do tracks - // fill D candidate table - if (fillHfCandD) { // fill candDplus table only once per D candidate, only if at least one V0 is found - if constexpr (DType == DType::Dplus) { - hfCandD3Pr(prongIdsD[0], prongIdsD[1], prongIdsD[2], - indexHfReducedCollision, - secondaryVertexD[0], secondaryVertexD[1], secondaryVertexD[2], - candD.pxProng0(), candD.pyProng0(), candD.pzProng0(), - candD.pxProng1(), candD.pyProng1(), candD.pzProng1(), - varUtils.pVectorProng2[0], varUtils.pVectorProng2[1], varUtils.pVectorProng2[2], - nItsClsDauMin, nTpcCrossRowsDauMin, chi2TpcDauMax, varUtils.signD); - if constexpr (WithMl) { - hfCandD3PrMl(bdtScores[0], bdtScores[1], bdtScores[2], bdtScores[3], bdtScores[4], bdtScores[5]); - } - } else if constexpr (DType == DType::D0) { - uint8_t selFlagD0 = {BIT(D0Sel::SelectedD0) | BIT(D0Sel::SelectedD0Bar)}; - if (candD.isSelD0() < cfgDmesCuts.selectionFlagD0) { - CLRBIT(selFlagD0, D0Sel::SelectedD0); - } - if (candD.isSelD0bar() < cfgDmesCuts.selectionFlagD0Bar) { - CLRBIT(selFlagD0, D0Sel::SelectedD0Bar); - } - hfCandD2Pr(prongIdsD[0], prongIdsD[1], - indexHfReducedCollision, - secondaryVertexD[0], secondaryVertexD[1], secondaryVertexD[2], - candD.pxProng0(), candD.pyProng0(), candD.pzProng0(), - candD.pxProng1(), candD.pyProng1(), candD.pzProng1(), - nItsClsDauMin, nTpcCrossRowsDauMin, chi2TpcDauMax, - selFlagD0); - if constexpr (WithMl) { - hfCandD2PrMl(bdtScores[0], bdtScores[1], bdtScores[2], bdtScores[3], bdtScores[4], bdtScores[5]); - } - } else if constexpr (DType == DType::Dstar) { - hfCandDstar(prongIdsD[0], prongIdsD[1], prongIdsD[2], - indexHfReducedCollision, - secondaryVertexD[0], secondaryVertexD[1], secondaryVertexD[2], - candD.pxProng0(), candD.pyProng0(), candD.pzProng0(), - candD.pxProng1(), candD.pyProng1(), candD.pzProng1(), - varUtils.pVectorProng2[0], varUtils.pVectorProng2[1], varUtils.pVectorProng2[2], - nItsClsDauMin, nTpcCrossRowsDauMin, chi2TpcDauMax, - nItsClsSoftPi, nTpcCrossRowsSoftPi, chi2TpcSoftPi, - varUtils.signD); - if constexpr (WithMl) { - hfCandD3PrMl(bdtScores[0], bdtScores[1], bdtScores[2], bdtScores[3], bdtScores[4], bdtScores[5]); - } - } - fillHfReducedCollision = true; - if constexpr (DType == DType::Dstar) { - registry.fill(HIST("hMassVsPtDstarPaired"), candD.pt(), varUtils.invMassD - varUtils.invMassD0); - } else if constexpr (DType == DType::Dplus) { - registry.fill(HIST("hMassVsPtDplusPaired"), candD.pt(), varUtils.invMassD); - } else if constexpr (DType == DType::D0) { - if (candD.isSelD0() >= cfgDmesCuts.selectionFlagD0) { - registry.fill(HIST("hMassVsPtD0Paired"), varUtils.ptD, varUtils.invMassD0); - } - if (candD.isSelD0bar() >= cfgDmesCuts.selectionFlagD0Bar) { - registry.fill(HIST("hMassVsPtD0BarPaired"), varUtils.ptD, varUtils.invMassD0Bar); - } - } - } - } // candsD loop - registry.fill(HIST("hEvents"), 1 + Event::Processed); - if (!fillHfReducedCollision) { - registry.fill(HIST("hEvents"), 1 + Event::NoDV0Selected); - return; - } - registry.fill(HIST("hEvents"), 1 + Event::DV0Selected); - // fill collision table if it contains a DPi pair a minima - hfReducedCollision(collision.posX(), collision.posY(), collision.posZ(), collision.numContrib(), hfRejMap, bz); - } // end of runDataCreation function - - template - void runMcGen(McParticles const& mcParticles, - CCs const& collInfos, - McCollisions const& mcCollisions, - BCsInfo const&) - { - bool const doV0s = (PairingType == PairingType::V0Only || PairingType == PairingType::V0AndTrack); - bool const doTracks = (PairingType == PairingType::TrackOnly || PairingType == PairingType::V0AndTrack); - for (const auto& mcCollision : mcCollisions) { - // Slice the particles table to get the particles for the current MC collision - const auto mcParticlesPerMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, mcCollision.globalIndex()); - // Slice the collisions table to get the collision info for the current MC collision - float centrality{-1.f}; - o2::hf_evsel::HfCollisionRejectionMask rejectionMask{}; - int const nSplitColl = 0; - const auto collSlice = collInfos.sliceBy(colPerMcCollision, mcCollision.globalIndex()); - rejectionMask = hfEvSelMc.getHfMcCollisionRejectionMask(mcCollision, collSlice, centrality); - hfEvSelMc.fillHistograms(mcCollision, rejectionMask, nSplitColl); - if (rejectCollisionsWithBadEvSel && rejectionMask != 0) { - // at least one event selection not satisfied --> reject all gen particles from this collision - continue; - } - for (const auto& particle : mcParticlesPerMcColl) { - int8_t sign{0}; - int8_t flag{0}; - int8_t signD{0}; - int8_t signBach{0}; - int8_t origin{0}; - bool matchedReso{false}, matchedD{false}, matchedV0Tr{false}; - std::vector idxBhadMothers{}; - if constexpr (DType == DType::Dstar) { - if (doV0s) { - // D* K0s - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarK0s) { - matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(Pdg::kDStar), +kK0}, true, &sign, 1); - if (matchedReso) { - flag = sign * decayChannelFlag; - auto candV0MC = mcParticles.rawIteratorAt(particle.daughtersIds().back()); - matchedV0Tr = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candV0MC, kK0, std::array{+kPiPlus, -kPiPlus}, true, &signBach, 2); - break; - } - } - } - if (doTracks && !matchedReso) { - // D*+ pi- - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarPi) { - matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(Pdg::kDStar), -static_cast(kPiPlus)}, true, &sign, 1); - if (matchedReso) { - flag = sign * decayChannelFlag; - matchedV0Tr = true; - break; - } - } - } - if (matchedReso && matchedV0Tr) { - auto candDstarMC = mcParticles.rawIteratorAt(particle.daughtersIds().front()); - matchedD = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candDstarMC, Pdg::kDStar, std::array{static_cast(Pdg::kD0), +static_cast(kPiPlus)}, true, &signD, 1); - if (matchedD) { - auto candD0MC = mcParticles.rawIteratorAt(candDstarMC.daughtersIds().front()); - matchedD = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candD0MC, Pdg::kD0, std::array{-kKPlus, +kPiPlus}, true, &signD, 2); - } - } - } else if constexpr (DType == DType::Dplus) { - if (doV0s) { - // D+ K0s - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusK0s) { - matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(Pdg::kDPlus), +kK0}, true, &sign, 1); - if (matchedReso) { - flag = sign * decayChannelFlag; - auto candV0MC = mcParticles.rawIteratorAt(particle.daughtersIds().back()); - matchedV0Tr = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candV0MC, kK0, std::array{+kPiPlus, -kPiPlus}, true, &signBach, 2); - break; - } - } - if (!matchedReso) { - // D+ lambda - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusLambda) { - matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(Pdg::kDPlus), +kLambda0}, true, &sign, 1); - if (matchedReso) { - flag = sign * decayChannelFlag; - auto candV0MC = mcParticles.rawIteratorAt(particle.daughtersIds().back()); - matchedV0Tr = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candV0MC, kLambda0, std::array{+kProton, -kPiPlus}, true, &signBach, 1); - break; - } - } - } - } - if (doTracks && !matchedReso) { - // D+ pi- - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusPi) { - matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(Pdg::kDPlus), -static_cast(kPiPlus)}, true, &sign, 1); - if (matchedReso) { - flag = sign * decayChannelFlag; - matchedV0Tr = true; - break; - } - } - } - if (matchedReso && matchedV0Tr) { - auto candDplusMC = mcParticles.rawIteratorAt(particle.daughtersIds().front()); - matchedD = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candDplusMC, Pdg::kDPlus, std::array{+kPiPlus, -kKPlus, +kPiPlus}, true, &signD, 2); - } - } else if constexpr (DType == DType::D0) { - if (doV0s) { - // D0 Lambda - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Lambda) { - matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(Pdg::kD0), +kLambda0}, true, &sign, 1); - if (matchedReso) { - flag = sign * decayChannelFlag; - auto candV0MC = mcParticles.rawIteratorAt(particle.daughtersIds().back()); - matchedV0Tr = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candV0MC, kLambda0, std::array{+kProton, -kPiPlus}, true, &signBach, 1); - break; - } - } - } - if (doTracks && !matchedReso) { - // D0 pi+ - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Pi) { - matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(Pdg::kD0), +static_cast(kPiPlus)}, true, &sign, 1); - if (matchedReso) { - flag = sign * decayChannelFlag; - matchedV0Tr = true; - break; - } - } - // D0 K+ - if (!matchedReso) { - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Kplus) { - matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(Pdg::kD0), +static_cast(kKPlus)}, true, &sign, 1); - if (matchedReso) { - flag = sign * decayChannelFlag; - matchedV0Tr = true; - break; - } - } - } - } - if (matchedReso && matchedV0Tr) { - auto candD0MC = mcParticles.rawIteratorAt(particle.daughtersIds().front()); - matchedD = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candD0MC, Pdg::kD0, std::array{-kKPlus, +kPiPlus}, true, &signD, 2); - } - } - if (matchedReso && matchedD && matchedV0Tr) { - origin = RecoDecay::getCharmHadronOrigin(mcParticlesPerMcColl, particle, false, &idxBhadMothers); - registry.fill(HIST("hMCGenOrigin"), origin); - auto ptParticle = particle.pt(); - auto invMassGen = computeInvMassGen(mcParticles, particle.globalIndex()); - auto yParticle = RecoDecay::y(particle.pVector(), invMassGen); - auto etaParticle = particle.eta(); - - std::array ptProngs{}; - std::array yProngs{}; - std::array etaProngs{}; - int counter = 0; - for (const auto& daught : particle.template daughters_as()) { - ptProngs[counter] = daught.pt(); - etaProngs[counter] = daught.eta(); - yProngs[counter] = RecoDecay::y(daught.pVector(), pdg->Mass(daught.pdgCode())); - counter++; - } - registry.fill(HIST("hMCGenCounter"), flag, ptParticle); - rowHfResoMcGenReduced(flag, origin, ptParticle, yParticle, etaParticle, - ptProngs[0], yProngs[0], etaProngs[0], - ptProngs[1], yProngs[1], etaProngs[1], - invMassGen, rejectionMask); - } - } - } - } - - // Process functions - // No ML - // Data - // D* - void processDstarV0(soa::Join const& collisions, - CandsDstarFiltered const& candsDstar, - aod::V0s const& v0s, - TracksIUWithPID const& tracksIU, - aod::BCsWithTimestamps const& bcs) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, bcs); - } - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarV0, "Process Dstar candidates paired with V0s", true); - - void processDstarTrack(soa::Join const& collisions, - CandsDstarFiltered const& candsDstar, - aod::TrackAssoc const& trackIndices, - TracksWithPID const& tracks, - aod::BCsWithTimestamps const& bcs) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, bcs); - } - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarTrack, "Process Dstar candidates paired with Tracks", false); - - void processDstarV0AndTrack(soa::Join const& collisions, - CandsDstarFiltered const& candsDstar, - aod::V0s const& v0s, - aod::TrackAssoc const& trackIndices, - TracksWithPID const& tracks, - TracksIUWithPID const& tracksIU, - aod::BCsWithTimestamps const& bcs) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, tracks, bcs); - } - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarV0AndTrack, "Process Dstar candidates paired with V0s and Tracks", false); - - // Dplus - void processDplusV0(soa::Join const& collisions, - CandsDplusFiltered const& candsDplus, - aod::V0s const& v0s, - TracksIUWithPID const& tracksIU, - aod::BCsWithTimestamps const& bcs) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, bcs); - } - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusV0, "Process Dplus candidates paired with V0s", false); - - void processDplusTrack(soa::Join const& collisions, - CandsDplusFiltered const& candsDplus, - aod::TrackAssoc const& trackIndices, - TracksWithPID const& tracks, - aod::BCsWithTimestamps const& bcs) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, bcs); - } - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusTrack, "Process Dplus candidates paired with Tracks", false); - - void processDplusV0AndTrack(soa::Join const& collisions, - CandsDplusFiltered const& candsDplus, - aod::V0s const& v0s, - aod::TrackAssoc const& trackIndices, - TracksWithPID const& tracks, - TracksIUWithPID const& tracksIU, - aod::BCsWithTimestamps const& bcs) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, tracks, bcs); - } - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusV0AndTrack, "Process Dplus candidates paired with V0s and Tracks", false); - - // D0 - void processD0V0(soa::Join const& collisions, - CandsD0Filtered const& candsD0, - aod::V0s const& v0s, - TracksIUWithPID const& tracksIU, - aod::BCsWithTimestamps const& bcs) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsD0.sliceBy(candsD0PerCollision, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, bcs); - } - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processD0V0, "Process D0 candidates paired with V0s", false); - - void processD0Track(soa::Join const& collisions, - CandsD0Filtered const& candsD0, - aod::TrackAssoc const& trackIndices, - TracksWithPID const& tracks, - aod::BCsWithTimestamps const& bcs) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsD0.sliceBy(candsD0PerCollision, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, bcs); - } - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processD0Track, "Process D0 candidates paired with Tracks", false); - - void processD0V0AndTrack(soa::Join const& collisions, - CandsD0Filtered const& candsD0, - aod::V0s const& v0s, - aod::TrackAssoc const& trackIndices, - TracksWithPID const& tracks, - TracksIUWithPID const& tracksIU, - aod::BCsWithTimestamps const& bcs) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsD0.sliceBy(candsD0PerCollision, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, tracks, bcs); - } - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processD0V0AndTrack, "Process D0 candidates paired with V0s and Tracks", false); - - // ML - // Data - // D* - void processDstarV0WithMl(soa::Join const& collisions, - CandsDstarFilteredWithMl const& candsDstar, - aod::V0s const& v0s, - TracksIUWithPID const& tracksIU, - aod::BCsWithTimestamps const& bcs) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollisionWithMl, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, bcs); - } - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarV0WithMl, "Process Dstar candidates paired with V0s with ML info", false); - - void processDstarTrackWithMl(soa::Join const& collisions, - CandsDstarFilteredWithMl const& candsDstar, - aod::TrackAssoc const& trackIndices, - TracksWithPID const& tracks, - aod::BCsWithTimestamps const& bcs) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollisionWithMl, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, bcs); - } - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarTrackWithMl, "Process Dstar candidates paired with Tracks with ML info", false); - - void processDstarV0AndTrackWithMl(soa::Join const& collisions, - CandsDstarFilteredWithMl const& candsDstar, - aod::V0s const& v0s, - aod::TrackAssoc const& trackIndices, - TracksWithPID const& tracks, - TracksIUWithPID const& tracksIU, - aod::BCsWithTimestamps const& bcs) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollisionWithMl, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, tracks, bcs); - } - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarV0AndTrackWithMl, "Process Dstar candidates paired with V0s and Tracks with ML info", false); - - // Dplus - void processDplusV0WithMl(soa::Join const& collisions, - CandsDplusFilteredWithMl const& candsDplus, - aod::V0s const& v0s, - TracksIUWithPID const& tracksIU, - aod::BCsWithTimestamps const& bcs) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollisionWithMl, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, bcs); - } - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusV0WithMl, "Process Dplus candidates paired with V0s with ML info", false); - - void processDplusTrackWithMl(soa::Join const& collisions, - CandsDplusFilteredWithMl const& candsDplus, - aod::TrackAssoc const& trackIndices, - TracksWithPID const& tracks, - aod::BCsWithTimestamps const& bcs) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollisionWithMl, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, bcs); - } - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusTrackWithMl, "Process Dplus candidates paired with Tracks with ML info", false); - - void processDplusV0AndTrackWithMl(soa::Join const& collisions, - CandsDplusFilteredWithMl const& candsDplus, - aod::V0s const& v0s, - aod::TrackAssoc const& trackIndices, - TracksWithPID const& tracks, - TracksIUWithPID const& tracksIU, - aod::BCsWithTimestamps const& bcs) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollisionWithMl, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, tracks, bcs); - } - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusV0AndTrackWithMl, "Process Dplus candidates paired with V0s and Tracks with ML info", false); - - // D0 - void processD0V0WithMl(soa::Join const& collisions, - CandsD0FilteredWithMl const& candsD0, - aod::V0s const& v0s, - TracksIUWithPID const& tracksIU, - aod::BCsWithTimestamps const& bcs) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsD0.sliceBy(candsD0PerCollisionWithMl, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, bcs); - } - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processD0V0WithMl, "Process D0 candidates paired with V0s with ML info", false); - - void processD0TrackWithMl(soa::Join const& collisions, - CandsD0FilteredWithMl const& candsD0, - aod::TrackAssoc const& trackIndices, - TracksWithPID const& tracks, - aod::BCsWithTimestamps const& bcs) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsD0.sliceBy(candsD0PerCollisionWithMl, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, bcs); - } - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processD0TrackWithMl, "Process D0 candidates paired with Tracks with ML info", false); - - void processD0V0AndTrackWithMl(soa::Join const& collisions, - CandsD0FilteredWithMl const& candsD0, - aod::V0s const& v0s, - aod::TrackAssoc const& trackIndices, - TracksWithPID const& tracks, - TracksIUWithPID const& tracksIU, - aod::BCsWithTimestamps const& bcs) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsD0.sliceBy(candsD0PerCollisionWithMl, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, tracks, bcs); - } - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processD0V0AndTrackWithMl, "Process D0 candidates paired with V0s and Tracks with ML info", false); - - // MC - // No ML - // D* - void processDstarV0MC(soa::Join const& collisions, - CandsDstarFilteredWithMc const& candsDstar, - aod::V0s const& v0s, - TracksIUWithPIDAndMC const& tracksIU, - aod::McParticles const& particlesMc, - BCsInfo const& bcs, - McCollisionsNoCents const& collInfos, - aod::McCollisions const& mcCollisions) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, v0sThisColl, tracksIU, tracksIU, particlesMc, bcs); - } - runMcGen(particlesMc, collInfos, mcCollisions, bcs); - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarV0MC, "Process Dstar candidates paired with V0s with MC matching", false); - - void processDstarTrackMC(soa::Join const& collisions, - CandsDstarFilteredWithMc const& candsDstar, - TracksWithPIDAndMC const& tracks, - aod::TrackAssoc const& trackIndices, - aod::McParticles const& particlesMc, - BCsInfo const& bcs, - McCollisionsNoCents const& collInfos, - aod::McCollisions const& mcCollisions) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, trackIdsThisColl, trackIdsThisColl, tracks, tracks, particlesMc, bcs); - } - runMcGen(particlesMc, collInfos, mcCollisions, bcs); - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarTrackMC, "Process Dstar candidates paired with tracks with MC matching", false); - - void processDstarV0AndTrackMC(soa::Join const& collisions, - CandsDstarFilteredWithMc const& candsDstar, - aod::V0s const& v0s, - aod::TrackAssoc const& trackIndices, - TracksWithPIDAndMC const& tracks, - TracksIUWithPIDAndMC const& tracksIU, - aod::McParticles const& particlesMc, - BCsInfo const& bcs, - McCollisionsNoCents const& collInfos, - aod::McCollisions const& mcCollisions) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, bcs); - } - runMcGen(particlesMc, collInfos, mcCollisions, bcs); - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarV0AndTrackMC, "Process Dstar candidates paired with V0s and tracks with MC matching", false); - - // Dplus - void processDplusV0MC(soa::Join const& collisions, - CandsDplusFilteredWithMc const& candsDplus, - aod::V0s const& v0s, - TracksIUWithPIDAndMC const& tracksIU, - aod::McParticles const& particlesMc, - BCsInfo const& bcs, - McCollisionsNoCents const& collInfos, - aod::McCollisions const& mcCollisions) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, v0sThisColl, tracksIU, tracksIU, particlesMc, bcs); - } - runMcGen(particlesMc, collInfos, mcCollisions, bcs); - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusV0MC, "Process Dstar candidates paired with V0s with MC matching", false); - - void processDplusTrackMC(soa::Join const& collisions, - CandsDplusFilteredWithMc const& candsDplus, - TracksWithPIDAndMC const& tracks, - aod::TrackAssoc const& trackIndices, - aod::McParticles const& particlesMc, - BCsInfo const& bcs, - McCollisionsNoCents const& collInfos, - aod::McCollisions const& mcCollisions) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, trackIdsThisColl, trackIdsThisColl, tracks, tracks, particlesMc, bcs); - } - runMcGen(particlesMc, collInfos, mcCollisions, bcs); - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusTrackMC, "Process Dplus candidates paired with tracks with MC matching", false); - - void processDplusV0AndTrackMC(soa::Join const& collisions, - CandsDplusFilteredWithMc const& candsDplus, - aod::V0s const& v0s, - aod::TrackAssoc const& trackIndices, - TracksWithPIDAndMC const& tracks, - TracksIUWithPIDAndMC const& tracksIU, - aod::McParticles const& particlesMc, - BCsInfo const& bcs, - McCollisionsNoCents const& collInfos, - aod::McCollisions const& mcCollisions) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, bcs); - } - runMcGen(particlesMc, collInfos, mcCollisions, bcs); - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusV0AndTrackMC, "Process Dplus candidates paired with V0s and tracks with MC matching", false); - - // D0 - void processD0V0MC(soa::Join const& collisions, - CandsD0FilteredWithMc const& candsD0, - aod::V0s const& v0s, - TracksIUWithPIDAndMC const& tracksIU, - aod::McParticles const& particlesMc, - BCsInfo const& bcs, - McCollisionsNoCents const& collInfos, - aod::McCollisions const& mcCollisions) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsD0.sliceBy(candsD0PerCollision, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, v0sThisColl, tracksIU, tracksIU, particlesMc, bcs); - } - runMcGen(particlesMc, collInfos, mcCollisions, bcs); - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processD0V0MC, "Process D0 candidates paired with V0s with MC matching", false); - - void processD0TrackMC(soa::Join const& collisions, - CandsD0FilteredWithMc const& candsD0, - TracksWithPIDAndMC const& tracks, - aod::TrackAssoc const& trackIndices, - aod::McParticles const& particlesMc, - BCsInfo const& bcs, - McCollisionsNoCents const& collInfos, - aod::McCollisions const& mcCollisions) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsD0.sliceBy(candsD0PerCollision, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, trackIdsThisColl, trackIdsThisColl, tracks, tracks, particlesMc, bcs); - } - runMcGen(particlesMc, collInfos, mcCollisions, bcs); - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processD0TrackMC, "Process D0 candidates paired with tracks with MC matching", false); - - void processD0V0AndTrackMC(soa::Join const& collisions, - CandsD0FilteredWithMc const& candsD0, - aod::V0s const& v0s, - aod::TrackAssoc const& trackIndices, - TracksWithPIDAndMC const& tracks, - TracksIUWithPIDAndMC const& tracksIU, - aod::McParticles const& particlesMc, - BCsInfo const& bcs, - McCollisionsNoCents const& collInfos, - aod::McCollisions const& mcCollisions) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsD0.sliceBy(candsD0PerCollision, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, bcs); - } - runMcGen(particlesMc, collInfos, mcCollisions, bcs); - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processD0V0AndTrackMC, "Process D0 candidates paired with V0s and tracks with MC matching", false); - // ML - // D* - void processDstarV0MCWithMl(soa::Join const& collisions, - CandsDstarFilteredWithMlAndMc const& candsDstar, - aod::V0s const& v0s, - TracksIUWithPIDAndMC const& tracksIU, - aod::McParticles const& particlesMc, - BCsInfo const& bcs, - McCollisionsNoCents const& collInfos, - aod::McCollisions const& mcCollisions) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollisionWithMl, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, particlesMc, bcs); - } - runMcGen(particlesMc, collInfos, mcCollisions, bcs); - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarV0MCWithMl, "Process Dstar candidates paired with V0s with MC matching and with ML info", false); - - void processDstarTrackMCWithMl(soa::Join const& collisions, - CandsDstarFilteredWithMlAndMc const& candsDstar, - TracksWithPIDAndMC const& tracks, - aod::TrackAssoc const& trackIndices, - aod::McParticles const& particlesMc, - BCsInfo const& bcs, - McCollisionsNoCents const& collInfos, - aod::McCollisions const& mcCollisions) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollisionWithMl, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, trackIdsThisColl, trackIdsThisColl, tracks, tracks, particlesMc, bcs); - } - runMcGen(particlesMc, collInfos, mcCollisions, bcs); - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarTrackMCWithMl, "Process Dstar candidates paired with tracks with MC matching and with ML info", false); - - void processDstarV0AndTrackMCWithMl(soa::Join const& collisions, - CandsDstarFilteredWithMlAndMc const& candsDstar, - aod::V0s const& v0s, - aod::TrackAssoc const& trackIndices, - TracksWithPIDAndMC const& tracks, - TracksIUWithPIDAndMC const& tracksIU, - aod::McParticles const& particlesMc, - BCsInfo const& bcs, - McCollisionsNoCents const& collInfos, - aod::McCollisions const& mcCollisions) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollisionWithMl, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, bcs); - } - runMcGen(particlesMc, collInfos, mcCollisions, bcs); - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarV0AndTrackMCWithMl, "Process Dstar candidates paired with V0s and tracks with MC matching and with ML info", false); - - // Dplus - void processDplusV0MCWithMl(soa::Join const& collisions, - CandsDplusFilteredWithMlAndMc const& candsDplus, - aod::V0s const& v0s, - TracksIUWithPIDAndMC const& tracksIU, - aod::McParticles const& particlesMc, - BCsInfo const& bcs, - McCollisionsNoCents const& collInfos, - aod::McCollisions const& mcCollisions) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollisionWithMl, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, particlesMc, bcs); - } - runMcGen(particlesMc, collInfos, mcCollisions, bcs); - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusV0MCWithMl, "Process Dplus candidates paired with V0s with MC matching and with ML info", false); - - void processDplusTrackMCWithMl(soa::Join const& collisions, - CandsDplusFilteredWithMlAndMc const& candsDplus, - TracksWithPIDAndMC const& tracks, - aod::TrackAssoc const& trackIndices, - aod::McParticles const& particlesMc, - BCsInfo const& bcs, - McCollisionsNoCents const& collInfos, - aod::McCollisions const& mcCollisions) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollisionWithMl, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, trackIdsThisColl, trackIdsThisColl, tracks, tracks, particlesMc, bcs); - } - runMcGen(particlesMc, collInfos, mcCollisions, bcs); - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusTrackMCWithMl, "Process Dplus candidates paired with tracks with MC matching and with ML info", false); - - void processDplusV0AndTrackMCWithMl(soa::Join const& collisions, - CandsDplusFilteredWithMlAndMc const& candsDplus, - aod::V0s const& v0s, - aod::TrackAssoc const& trackIndices, - TracksWithPIDAndMC const& tracks, - TracksIUWithPIDAndMC const& tracksIU, - aod::McParticles const& particlesMc, - BCsInfo const& bcs, - McCollisionsNoCents const& collInfos, - aod::McCollisions const& mcCollisions) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollisionWithMl, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, bcs); - } - runMcGen(particlesMc, collInfos, mcCollisions, bcs); - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusV0AndTrackMCWithMl, "Process Dplus candidates paired with V0s and tracks with MC matching and with ML info", false); - - // D0 - void processD0V0MCWithMl(soa::Join const& collisions, - CandsD0FilteredWithMlAndMc const& candsD0, - aod::V0s const& v0s, - TracksIUWithPIDAndMC const& tracksIU, - aod::McParticles const& particlesMc, - BCsInfo const& bcs, - McCollisionsNoCents const& collInfos, - aod::McCollisions const& mcCollisions) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsD0.sliceBy(candsD0PerCollisionWithMl, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, particlesMc, bcs); - } - runMcGen(particlesMc, collInfos, mcCollisions, bcs); - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processD0V0MCWithMl, "Process D0 candidates paired with V0s with MC matching and with ML info", false); - - void processD0TrackMCWithMl(soa::Join const& collisions, - CandsD0FilteredWithMlAndMc const& candsD0, - TracksWithPIDAndMC const& tracks, - aod::TrackAssoc const& trackIndices, - aod::McParticles const& particlesMc, - BCsInfo const& bcs, - McCollisionsNoCents const& collInfos, - aod::McCollisions const& mcCollisions) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsD0.sliceBy(candsD0PerCollisionWithMl, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, trackIdsThisColl, trackIdsThisColl, tracks, tracks, particlesMc, bcs); - } - runMcGen(particlesMc, collInfos, mcCollisions, bcs); - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processD0TrackMCWithMl, "Process D0 candidates paired with tracks with MC matching and with ML info", false); - - void processD0V0AndTrackMCWithMl(soa::Join const& collisions, - CandsD0FilteredWithMlAndMc const& candsD0, - aod::V0s const& v0s, - aod::TrackAssoc const& trackIndices, - TracksWithPIDAndMC const& tracks, - TracksIUWithPIDAndMC const& tracksIU, - aod::McParticles const& particlesMc, - BCsInfo const& bcs, - McCollisionsNoCents const& collInfos, - aod::McCollisions const& mcCollisions) - { - int zvtxColl{0}; - int sel8Coll{0}; - int zvtxAndSel8Coll{0}; - int zvtxAndSel8CollAndSoftTrig{0}; - int allSelColl{0}; - for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsD0.sliceBy(candsD0PerCollisionWithMl, thisCollId); - auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, bcs); - } - runMcGen(particlesMc, collInfos, mcCollisions, bcs); - // handle normalization by the right number of collisions - hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); - } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processD0V0AndTrackMCWithMl, "Process D0 candidates paired with V0s and tracks with MC matching and with ML info", false); -}; // struct - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{adaptAnalysisTask(cfgc)}; -} diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx new file mode 100644 index 00000000000..afdbb6bb978 --- /dev/null +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx @@ -0,0 +1,777 @@ +// Copyright 2019-2020 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 dataCreatorCharmResoReduced.cxx +/// \brief Creation of D0 V0 and D0 track pairs +/// +/// \author Luca Aglietta , UniTO Turin +/// \author Fabrizio Grosa , CERN + +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/DecayChannels.h" +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/D2H/Core/DataCreationCharmReso.h" +#include "PWGHF/D2H/DataModel/ReducedDataModel.h" +#include "PWGHF/D2H/Utils/utilsRedDataFormat.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsBfieldCCDB.h" +#include "PWGHF/Utils/utilsEvSelHf.h" +#include "PWGHF/Utils/utilsMcMatching.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::analysis; +using namespace o2::aod; +using namespace o2::analysis::hf_charm_reso; +using namespace o2::constants::physics; +using namespace o2::framework; +using namespace o2::framework::expressions; + + +/// Creation of D-V0 pairs +struct HfDataCreatorCharmResoToD0Reduced { + + // Produces AOD tables to store collision information + Produces hfReducedCollision; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h + Produces hfCollisionCounter; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h + // tracks, V0 and D candidates reduced tables + Produces hfCandV0; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h + Produces hfTrackNoParam; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h + Produces hfCandD2Pr; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h + // ML optional Tables + Produces hfCandD2PrMl; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h + // MC Tables + Produces rowHfResoMcGenReduced; + Produces rowHf2PrV0McRecReduced; + Produces rowHf2PrTrkMcRecReduced; + + // selection D + struct : ConfigurableGroup { + std::string prefix = "dmesons"; + Configurable selectionFlagD0{"selectionFlagD0", 1, "Selection Flag for D0"}; + Configurable selectionFlagD0Bar{"selectionFlagD0Bar", 1, "Selection Flag for D0bar"}; + } cfgDmesCuts; + + // selection V0 + struct : ConfigurableGroup { + std::string prefix = "v0s"; + Configurable deltaMassK0s{"deltaMassK0s", 0.02, "delta mass cut for K0S"}; + Configurable deltaMassLambda{"deltaMassLambda", 0.01, "delta mass cut for Lambda"}; + Configurable etaMax{"etaMax", 0.8f, "maximum eta"}; + Configurable etaMaxDau{"etaMaxDau", 5.f, "maximum eta V0 daughters"}; + Configurable trackNclusItsCut{"trackNclusItsCut", 0, "Minimum number of ITS clusters for V0 daughter"}; + Configurable trackNCrossedRowsTpc{"trackNCrossedRowsTpc", 50, "Minimum TPC crossed rows"}; + Configurable trackNsharedClusTpc{"trackNsharedClusTpc", 1000, "Maximum number of shared TPC clusters for V0 daughter"}; + Configurable trackFracMaxindableTpcCls{"trackFracMaxindableTpcCls", 0.8f, "Maximum fraction of findable TPC clusters for V0 daughter"}; + Configurable dcaDau{"dcaDau", 1.f, "DCA V0 daughters"}; + Configurable dcaMaxDauToPv{"dcaMaxDauToPv", 0.1f, "Maximum daughter's DCA to PV"}; + Configurable dcaPv{"dcaPv", 1.f, "DCA V0 to PV"}; + Configurable cosPa{"cosPa", 0.99f, "V0 CosPA"}; + Configurable radiusMin{"radiusMin", 0.9f, "Minimum v0 radius accepted"}; + Configurable nSigmaTpc{"nSigmaTpc", 4.f, "Nsigmatpc"}; + Configurable nSigmaTofPr{"nSigmaTofPr", 4.f, "N sigma TOF for protons only"}; + Configurable propagateV0toPV{"propagateV0toPV", false, "Enable or disable V0 propagation to V0"}; + } cfgV0Cuts; + + // selection single tracks + struct : ConfigurableGroup { + std::string prefix = "singleTracks"; + Configurable setTrackSelections{"setTrackSelections", 2, "flag to apply track selections: 0=none; 1=global track w/o DCA selection; 2=global track; 3=only ITS quality"}; + Configurable maxEta{"maxEta", 0.8, "maximum pseudorapidity for single tracks to be paired with D mesons"}; + Configurable minPt{"minPt", 0.1, "minimum pT for single tracks to be paired with D mesons"}; + Configurable maxNsigmaTpcPi{"maxNsigmaTpcPi", -1., "maximum pion NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; + Configurable maxNsigmaTpcKa{"maxNsigmaTpcKa", -1., "maximum kaon NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; + Configurable maxNsigmaTpcPr{"maxNsigmaTpcPr", 3., "maximum proton NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; + } cfgSingleTrackCuts; + + // QA histograms + struct : ConfigurableGroup { + std::string prefix = "qaPlots"; + Configurable applyCutsForQaHistograms{"applyCutsForQaHistograms", true, "flag to apply cuts to QA histograms"}; + Configurable cutMassDstarMin{"cutMassDstarMin", 0.143, "minimum mass for Dstar candidates"}; + Configurable cutMassDstarMax{"cutMassDstarMax", 0.155, "maximum mass for Dstar candidates"}; + Configurable cutMassDMin{"cutMassDMin", 1.83, "minimum mass for D0 and Dplus candidates"}; + Configurable cutMassDMax{"cutMassDMax", 1.92, "maximum mass for D0 and Dplus candidates"}; + Configurable cutMassK0sMin{"cutMassK0sMin", 0.485, "minimum mass for K0s candidates"}; + Configurable cutMassK0sMax{"cutMassK0sMax", 0.509, "maximum mass for K0s candidates"}; + Configurable cutMassLambdaMin{"cutMassLambdaMin", 1.11, "minimum mass for Lambda candidates"}; + Configurable cutMassLambdaMax{"cutMassLambdaMax", 1.12, "maximum mass for Lambda candidates"}; + } cfgQaPlots; + // other configurables + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; + Configurable doMcRecQa{"doMcRecQa", true, "Fill QA histograms for Mc matching"}; + Configurable rejectPairsWithCommonDaughter{"rejectPairsWithCommonDaughter", true, "flag to reject already at this stage the pairs that share a daughter track"}; + Configurable rejectCollisionsWithBadEvSel{"rejectCollisionsWithBadEvSel", true, "flag to reject collisions with bad event selection"}; + + o2::hf_evsel::HfEventSelection hfEvSel; + o2::hf_evsel::HfEventSelectionMc hfEvSelMc; + + // CCDB service + o2::ccdb::CcdbApi ccdbApi; + Service ccdb; + double bz{0.}; + int runNumber{0}; // needed to detect if the run changed and trigger update of calibrations etc. + + // material correction for track propagation + o2::base::MatLayerCylSet* lut{}; + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + + // O2DatabasePDG service + Service pdg; + + // vertex fitter + o2::vertexing::DCAFitterN<2> fitter; + + // D0 + using CandsD0Filtered = soa::Filtered>; + using CandsD0FilteredWithMl = soa::Filtered>; + using CandsD0FilteredWithMc = soa::Filtered>; + using CandsD0FilteredWithMlAndMc = soa::Filtered>; + // Tracks + using TracksWithPID = soa::Join; + using TracksWithPIDAndMC = soa::Join; + using TracksIUWithPID = soa::Join; + using TracksIUWithPIDAndMC = soa::Join; + // Collisions MC + using BCsInfo = soa::Join; + using McCollisionsNoCents = soa::Join; + + Filter filterSelectD0Candidates = (aod::hf_sel_candidate_d0::isSelD0 >= cfgDmesCuts.selectionFlagD0 || aod::hf_sel_candidate_d0::isSelD0bar >= cfgDmesCuts.selectionFlagD0Bar); + + Preslice candsD0PerCollision = aod::hf_cand::collisionId; + Preslice candsD0PerCollisionWithMl = aod::hf_cand::collisionId; + Preslice candsV0PerCollision = aod::v0::collisionId; + Preslice trackIndicesPerCollision = aod::track_association::collisionId; + Preslice mcParticlesPerMcCollision = aod::mcparticle::mcCollisionId; + PresliceUnsorted colPerMcCollision = aod::mccollisionlabel::mcCollisionId; + + HistogramRegistry registry{"registry"}; + + void init(InitContext& initContext) + { + // histograms + constexpr int kNBinsEvents = kNEvent; + std::string labels[kNBinsEvents]; + labels[Event::Processed] = "processed"; + labels[Event::NoDV0Selected] = "without DV0 pairs"; + labels[Event::DV0Selected] = "with DV0 pairs"; + static const AxisSpec axisEvents = {kNBinsEvents, 0.5, kNBinsEvents + 0.5, ""}; + registry.add("hEvents", "Events;;entries", HistType::kTH1D, {axisEvents}); + for (int iBin = 0; iBin < kNBinsEvents; iBin++) { + registry.get(HIST("hEvents"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); + } + + const AxisSpec axisPt{50, 0.f, 50.f, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec axisP{100, 0.f, 10.f, "#it{p} (GeV/#it{c})"}; + const AxisSpec axisDeDx{500, 0.f, 1000.f, ""}; + const AxisSpec axisMassD0{200, 1.7f, 2.1f, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisMassDplus{200, 1.7f, 2.1f, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisMassDstar{200, 0.139f, 0.179f, "delta inv. mass (GeV/#it{c}^{2})"}; // o2-linter: disable=pdg/explicit-mass (false positive) + const AxisSpec axisMassLambda{100, 1.05f, 1.35f, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisMassKzero{100, 0.35f, 0.65f, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisDeltaMassToK{500, 0.49, 1.49, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisDeltaMassToPi{500, 0.13, 1.13, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisDeltaMassToPr{500, 0.93, 1.93, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisDeltaMassToLambda{500, 1.05, 2.05, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisMassDsj{400, 0.49f, 0.89f, ""}; // Ds1 and Ds2Star legacy + registry.add("hMassVsPtK0s", "K0^{s} candidates;#it{p}_{T} (GeV/#it{c});inv. mass (#pi^{#plus}#pi^{#minus}) (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassKzero}}); + registry.add("hMassVsPtLambda", "Lambda candidates;#it{p}_{T} (GeV/#it{c});inv. mass (p #pi^{#minus}) (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassLambda}}); + registry.add("hdEdxVsP", "Tracks;#it{p} (GeV/#it{c});d#it{E}/d#it{x};entries", {HistType::kTH2D, {axisP, axisDeDx}}); + registry.add("hMassVsPtD0All", "D0 candidates (all, regardless the pairing with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassD0}}); + registry.add("hMassVsPtD0BarAll", "D0bar candidates (all, regardless the pairing with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassD0}}); + registry.add("hMassVsPtD0Paired", "D0 candidates (paired with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassD0}}); + registry.add("hMassVsPtD0BarPaired", "D0 candidates (paired with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassD0}}); + registry.add("hMassD0Pi", "D0Pi candidates; m_{D^{0}#pi^{+}} - m_{D^{0}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPi}}); + registry.add("hMassD0K", "D0Kplus candidates; m_{D^{0}K^{+}} - m_{D^{0}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToK}}); + registry.add("hMassD0Proton", "D0Proton candidates; m_{D^{0}p} - m_{D^{0}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPr}}); + registry.add("hMassD0Lambda", "D0Lambda candidates; m_{D^{0}#Lambda} - m_{D^{0}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToLambda}}); + if (doprocessD0V0MC || doprocessD0TrackMC || doprocessD0V0AndTrackMC || doprocessD0V0MCWithMl || doprocessD0TrackMCWithMl || doprocessD0V0AndTrackMCWithMl) { + // MC Rec + int const nChannels = hf_decay::hf_cand_reso::DecayChannelMain::NChannelsMain; + registry.add("hMCRecCounter", "Number of Reconstructed MC Matched candidates per channel", {HistType::kTH1D, {{2 * nChannels + 1, -(nChannels + 0.5), nChannels + 0.5}}}); + registry.add("hMCRecDebug", "Debug of MC Reco", {HistType::kTH1D, {{551, -0.5, 550.5}}}); + registry.add("hMCRecOrigin", "Origin of Matched particles", {HistType::kTH1D, {{3, -0.5, 2.5}}}); + registry.add("hMCRecMassGen", "Generated inv. mass of resoncances", {HistType::kTH1D, {{2000, 1.8, 3.8}}}); + registry.add("hMCRecCharmDau", "Charm daughter flag", {HistType::kTH1D, {{57, -28.5, 28.5}}}); + // MC Gen + registry.add("hMCGenCounter", "Number of Generated particles; Decay Channel Flag; pT [GeV/c]", {HistType::kTH2D, {{17, -8.5, 8.5}, {100, 0, 50}}}); + registry.add("hMCGenOrigin", "Origin of Generated particles", {HistType::kTH1D, {{3, -0.5, 2.5}}}); + } + // Configure CCDB access + ccdb->setURL(ccdbUrl.value); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); + ccdbApi.init(ccdbUrl); + runNumber = 0; + lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get("GLO/Param/MatLUT")); + + // Configure DCA fitter + fitter.setPropagateToPCA(true); + fitter.setMaxR(200.); + fitter.setMinParamChange(1e-3); + fitter.setMinRelChi2Change(0.9); + fitter.setMaxDZIni(1e9); + fitter.setMaxDXYIni(4); + fitter.setMaxChi2(1e9); + fitter.setUseAbsDCA(true); + fitter.setWeightedFinalPCA(false); + + // init HF event selection helper + hfEvSel.init(registry); + + const auto& workflows = initContext.services().get(); + for (const DeviceSpec& device : workflows.devices) { + if (device.name == "hf-data-creator-charm-reso-to-d0-reduced") { + // init HF event selection helper + hfEvSelMc.init(device, registry); + break; + } + } + } + + // Process functions + // No ML + // Data + void processD0V0(soa::Join const& collisions, + CandsD0Filtered const& candsD0, + aod::V0s const& v0s, + TracksIUWithPID const& tracksIU, + aod::BCsWithTimestamps const&) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsD0.sliceBy(candsD0PerCollision, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, dummyTable, dummyTable, dummyTable, dummyTable); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToD0Reduced, processD0V0, "Process D0 candidates paired with V0s", false); + + void processD0Track(soa::Join const& collisions, + CandsD0Filtered const& candsD0, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, + aod::BCsWithTimestamps const&) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsD0.sliceBy(candsD0PerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, dummyTable, hfTrackNoParam, dummyTable, dummyTable, dummyTable); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToD0Reduced, processD0Track, "Process D0 candidates paired with Tracks", false); + + void processD0V0AndTrack(soa::Join const& collisions, + CandsD0Filtered const& candsD0, + aod::V0s const& v0s, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, + TracksIUWithPID const& tracksIU, + aod::BCsWithTimestamps const&) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsD0.sliceBy(candsD0PerCollision, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, hfTrackNoParam, dummyTable, dummyTable, dummyTable); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToD0Reduced, processD0V0AndTrack, "Process D0 candidates paired with V0s and Tracks", false); + + // ML + // Data + void processD0V0WithMl(soa::Join const& collisions, + CandsD0FilteredWithMl const& candsD0, + aod::V0s const& v0s, + TracksIUWithPID const& tracksIU, + aod::BCsWithTimestamps const&) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsD0.sliceBy(candsD0PerCollisionWithMl, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, dummyTable, dummyTable, dummyTable, hfCandD2PrMl); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToD0Reduced, processD0V0WithMl, "Process D0 candidates paired with V0s with ML info", false); + + void processD0TrackWithMl(soa::Join const& collisions, + CandsD0FilteredWithMl const& candsD0, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, + aod::BCsWithTimestamps const&) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsD0.sliceBy(candsD0PerCollisionWithMl, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, dummyTable, hfTrackNoParam, dummyTable, dummyTable, hfCandD2PrMl); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToD0Reduced, processD0TrackWithMl, "Process D0 candidates paired with Tracks with ML info", false); + + void processD0V0AndTrackWithMl(soa::Join const& collisions, + CandsD0FilteredWithMl const& candsD0, + aod::V0s const& v0s, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, + TracksIUWithPID const& tracksIU, + aod::BCsWithTimestamps const&) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsD0.sliceBy(candsD0PerCollisionWithMl, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, hfTrackNoParam, dummyTable, dummyTable, hfCandD2PrMl); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToD0Reduced, processD0V0AndTrackWithMl, "Process D0 candidates paired with V0s and Tracks with ML info", false); + + // MC + // No ML + void processD0V0MC(soa::Join const& collisions, + CandsD0FilteredWithMc const& candsD0, + aod::V0s const& v0s, + TracksIUWithPIDAndMC const& tracksIU, + aod::McParticles const& particlesMc, + BCsInfo const& bcs, + McCollisionsNoCents const& collInfos, + aod::McCollisions const& mcCollisions) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsD0.sliceBy(candsD0PerCollision, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, dummyTable, rowHf2PrV0McRecReduced, dummyTable, dummyTable); + } + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToD0Reduced, processD0V0MC, "Process D0 candidates paired with V0s with MC matching", false); + + void processD0TrackMC(soa::Join const& collisions, + CandsD0FilteredWithMc const& candsD0, + TracksWithPIDAndMC const& tracks, + aod::TrackAssoc const& trackIndices, + aod::McParticles const& particlesMc, + BCsInfo const& bcs, + McCollisionsNoCents const& collInfos, + aod::McCollisions const& mcCollisions) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsD0.sliceBy(candsD0PerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, dummyTable, hfTrackNoParam, dummyTable, rowHf2PrTrkMcRecReduced, dummyTable); + } + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToD0Reduced, processD0TrackMC, "Process D0 candidates paired with tracks with MC matching", false); + + void processD0V0AndTrackMC(soa::Join const& collisions, + CandsD0FilteredWithMc const& candsD0, + aod::V0s const& v0s, + aod::TrackAssoc const& trackIndices, + TracksWithPIDAndMC const& tracks, + TracksIUWithPIDAndMC const& tracksIU, + aod::McParticles const& particlesMc, + BCsInfo const& bcs, + McCollisionsNoCents const& collInfos, + aod::McCollisions const& mcCollisions) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsD0.sliceBy(candsD0PerCollision, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, hfTrackNoParam, rowHf2PrV0McRecReduced, rowHf2PrTrkMcRecReduced, dummyTable); + } + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToD0Reduced, processD0V0AndTrackMC, "Process D0 candidates paired with V0s and tracks with MC matching", false); + + // ML + void processD0V0MCWithMl(soa::Join const& collisions, + CandsD0FilteredWithMlAndMc const& candsD0, + aod::V0s const& v0s, + TracksIUWithPIDAndMC const& tracksIU, + aod::McParticles const& particlesMc, + BCsInfo const& bcs, + McCollisionsNoCents const& collInfos, + aod::McCollisions const& mcCollisions) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsD0.sliceBy(candsD0PerCollisionWithMl, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, dummyTable, rowHf2PrV0McRecReduced, dummyTable, hfCandD2PrMl); + } + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToD0Reduced, processD0V0MCWithMl, "Process D0 candidates paired with V0s with MC matching and with ML info", false); + + void processD0TrackMCWithMl(soa::Join const& collisions, + CandsD0FilteredWithMlAndMc const& candsD0, + TracksWithPIDAndMC const& tracks, + aod::TrackAssoc const& trackIndices, + aod::McParticles const& particlesMc, + BCsInfo const& bcs, + McCollisionsNoCents const& collInfos, + aod::McCollisions const& mcCollisions) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsD0.sliceBy(candsD0PerCollisionWithMl, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, dummyTable, hfTrackNoParam, dummyTable, rowHf2PrTrkMcRecReduced, hfCandD2PrMl); + } + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToD0Reduced, processD0TrackMCWithMl, "Process D0 candidates paired with tracks with MC matching and with ML info", false); + + void processD0V0AndTrackMCWithMl(soa::Join const& collisions, + CandsD0FilteredWithMlAndMc const& candsD0, + aod::V0s const& v0s, + aod::TrackAssoc const& trackIndices, + TracksWithPIDAndMC const& tracks, + TracksIUWithPIDAndMC const& tracksIU, + aod::McParticles const& particlesMc, + BCsInfo const& bcs, + McCollisionsNoCents const& collInfos, + aod::McCollisions const& mcCollisions) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsD0.sliceBy(candsD0PerCollisionWithMl, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, hfTrackNoParam, rowHf2PrV0McRecReduced, rowHf2PrTrkMcRecReduced, hfCandD2PrMl); + } + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToD0Reduced, processD0V0AndTrackMCWithMl, "Process D0 candidates paired with V0s and tracks with MC matching and with ML info", false); +}; // struct + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDplusReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDplusReduced.cxx new file mode 100644 index 00000000000..74bbb1fbfc6 --- /dev/null +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDplusReduced.cxx @@ -0,0 +1,771 @@ +// Copyright 2019-2020 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 dataCreatorCharmResoReduced.cxx +/// \brief Creation of D+ V0 and D+ track pairs +/// +/// \author Luca Aglietta , UniTO Turin +/// \author Fabrizio Grosa , CERN + +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/DecayChannels.h" +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/D2H/Core/DataCreationCharmReso.h" +#include "PWGHF/D2H/DataModel/ReducedDataModel.h" +#include "PWGHF/D2H/Utils/utilsRedDataFormat.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsBfieldCCDB.h" +#include "PWGHF/Utils/utilsEvSelHf.h" +#include "PWGHF/Utils/utilsMcMatching.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::analysis; +using namespace o2::aod; +using namespace o2::analysis::hf_charm_reso; +using namespace o2::constants::physics; +using namespace o2::framework; +using namespace o2::framework::expressions; + + +/// Creation of D-V0 pairs +struct HfDataCreatorCharmResoToDplusReduced { + + // Produces AOD tables to store collision information + Produces hfReducedCollision; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h + Produces hfCollisionCounter; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h + // tracks, V0 and D candidates reduced tables + Produces hfCandV0; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h + Produces hfTrackNoParam; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h + Produces hfCandD3Pr; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h + // ML optional Tables + Produces hfCandD3PrMl; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h + // MC Tables + Produces rowHfResoMcGenReduced; + Produces rowHf3PrV0McRecReduced; + Produces rowHf3PrTrkMcRecReduced; + + // selection D + struct : ConfigurableGroup { + std::string prefix = "dmesons"; + Configurable selectionFlagDplus{"selectionFlagDplus", 7, "Selection Flag for D"}; + } cfgDmesCuts; + + // selection V0 + struct : ConfigurableGroup { + std::string prefix = "v0s"; + Configurable deltaMassK0s{"deltaMassK0s", 0.02, "delta mass cut for K0S"}; + Configurable deltaMassLambda{"deltaMassLambda", 0.01, "delta mass cut for Lambda"}; + Configurable etaMax{"etaMax", 0.8f, "maximum eta"}; + Configurable etaMaxDau{"etaMaxDau", 5.f, "maximum eta V0 daughters"}; + Configurable trackNclusItsCut{"trackNclusItsCut", 0, "Minimum number of ITS clusters for V0 daughter"}; + Configurable trackNCrossedRowsTpc{"trackNCrossedRowsTpc", 50, "Minimum TPC crossed rows"}; + Configurable trackNsharedClusTpc{"trackNsharedClusTpc", 1000, "Maximum number of shared TPC clusters for V0 daughter"}; + Configurable trackFracMaxindableTpcCls{"trackFracMaxindableTpcCls", 0.8f, "Maximum fraction of findable TPC clusters for V0 daughter"}; + Configurable dcaDau{"dcaDau", 1.f, "DCA V0 daughters"}; + Configurable dcaMaxDauToPv{"dcaMaxDauToPv", 0.1f, "Maximum daughter's DCA to PV"}; + Configurable dcaPv{"dcaPv", 1.f, "DCA V0 to PV"}; + Configurable cosPa{"cosPa", 0.99f, "V0 CosPA"}; + Configurable radiusMin{"radiusMin", 0.9f, "Minimum v0 radius accepted"}; + Configurable nSigmaTpc{"nSigmaTpc", 4.f, "Nsigmatpc"}; + Configurable nSigmaTofPr{"nSigmaTofPr", 4.f, "N sigma TOF for protons only"}; + Configurable propagateV0toPV{"propagateV0toPV", false, "Enable or disable V0 propagation to V0"}; + } cfgV0Cuts; + + // selection single tracks + struct : ConfigurableGroup { + std::string prefix = "singleTracks"; + Configurable setTrackSelections{"setTrackSelections", 2, "flag to apply track selections: 0=none; 1=global track w/o DCA selection; 2=global track; 3=only ITS quality"}; + Configurable maxEta{"maxEta", 0.8, "maximum pseudorapidity for single tracks to be paired with D mesons"}; + Configurable minPt{"minPt", 0.1, "minimum pT for single tracks to be paired with D mesons"}; + Configurable maxNsigmaTpcPi{"maxNsigmaTpcPi", -1., "maximum pion NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; + Configurable maxNsigmaTpcKa{"maxNsigmaTpcKa", -1., "maximum kaon NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; + Configurable maxNsigmaTpcPr{"maxNsigmaTpcPr", 3., "maximum proton NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; + } cfgSingleTrackCuts; + + // QA histograms + struct : ConfigurableGroup { + std::string prefix = "qaPlots"; + Configurable applyCutsForQaHistograms{"applyCutsForQaHistograms", true, "flag to apply cuts to QA histograms"}; + Configurable cutMassDMin{"cutMassDMin", 1.83, "minimum mass for D0 and Dplus candidates"}; + Configurable cutMassDMax{"cutMassDMax", 1.92, "maximum mass for D0 and Dplus candidates"}; + Configurable cutMassK0sMin{"cutMassK0sMin", 0.485, "minimum mass for K0s candidates"}; + Configurable cutMassK0sMax{"cutMassK0sMax", 0.509, "maximum mass for K0s candidates"}; + Configurable cutMassLambdaMin{"cutMassLambdaMin", 1.11, "minimum mass for Lambda candidates"}; + Configurable cutMassLambdaMax{"cutMassLambdaMax", 1.12, "maximum mass for Lambda candidates"}; + } cfgQaPlots; + // other configurables + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; + Configurable doMcRecQa{"doMcRecQa", true, "Fill QA histograms for Mc matching"}; + Configurable rejectPairsWithCommonDaughter{"rejectPairsWithCommonDaughter", true, "flag to reject already at this stage the pairs that share a daughter track"}; + Configurable rejectCollisionsWithBadEvSel{"rejectCollisionsWithBadEvSel", true, "flag to reject collisions with bad event selection"}; + + o2::hf_evsel::HfEventSelection hfEvSel; + o2::hf_evsel::HfEventSelectionMc hfEvSelMc; + + // CCDB service + o2::ccdb::CcdbApi ccdbApi; + Service ccdb; + double bz{0.}; + int runNumber{0}; // needed to detect if the run changed and trigger update of calibrations etc. + + // material correction for track propagation + o2::base::MatLayerCylSet* lut{}; + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + + // O2DatabasePDG service + Service pdg; + + // vertex fitter + o2::vertexing::DCAFitterN<2> fitter; + + // Dplus + using CandsDplusFiltered = soa::Filtered>; + using CandsDplusFilteredWithMl = soa::Filtered>; + using CandsDplusFilteredWithMc = soa::Filtered>; + using CandsDplusFilteredWithMlAndMc = soa::Filtered>; + // Tracks + using TracksWithPID = soa::Join; + using TracksWithPIDAndMC = soa::Join; + using TracksIUWithPID = soa::Join; + using TracksIUWithPIDAndMC = soa::Join; + // Collisions MC + using BCsInfo = soa::Join; + using McCollisionsNoCents = soa::Join; + + Filter filterSelectDplus = (aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= cfgDmesCuts.selectionFlagDplus); + + Preslice candsDplusPerCollision = aod::hf_cand::collisionId; + Preslice candsDplusPerCollisionWithMl = aod::hf_cand::collisionId; + Preslice candsV0PerCollision = aod::v0::collisionId; + Preslice trackIndicesPerCollision = aod::track_association::collisionId; + Preslice mcParticlesPerMcCollision = aod::mcparticle::mcCollisionId; + PresliceUnsorted colPerMcCollision = aod::mccollisionlabel::mcCollisionId; + + HistogramRegistry registry{"registry"}; + + void init(InitContext& initContext) + { + // histograms + constexpr int kNBinsEvents = kNEvent; + std::string labels[kNBinsEvents]; + labels[Event::Processed] = "processed"; + labels[Event::NoDV0Selected] = "without DV0 pairs"; + labels[Event::DV0Selected] = "with DV0 pairs"; + static const AxisSpec axisEvents = {kNBinsEvents, 0.5, kNBinsEvents + 0.5, ""}; + registry.add("hEvents", "Events;;entries", HistType::kTH1D, {axisEvents}); + for (int iBin = 0; iBin < kNBinsEvents; iBin++) { + registry.get(HIST("hEvents"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); + } + + const AxisSpec axisPt{50, 0.f, 50.f, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec axisP{100, 0.f, 10.f, "#it{p} (GeV/#it{c})"}; + const AxisSpec axisDeDx{500, 0.f, 1000.f, ""}; + const AxisSpec axisMassD0{200, 1.7f, 2.1f, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisMassDplus{200, 1.7f, 2.1f, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisMassLambda{100, 1.05f, 1.35f, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisMassKzero{100, 0.35f, 0.65f, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisDeltaMassToK{500, 0.49, 1.49, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisDeltaMassToPi{500, 0.13, 1.13, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisDeltaMassToPr{500, 0.93, 1.93, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisDeltaMassToLambda{500, 1.05, 2.05, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisMassDsj{400, 0.49f, 0.89f, ""}; // Ds1 and Ds2Star legacy + registry.add("hMassVsPtK0s", "K0^{s} candidates;#it{p}_{T} (GeV/#it{c});inv. mass (#pi^{#plus}#pi^{#minus}) (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassKzero}}); + registry.add("hMassVsPtLambda", "Lambda candidates;#it{p}_{T} (GeV/#it{c});inv. mass (p #pi^{#minus}) (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassLambda}}); + registry.add("hdEdxVsP", "Tracks;#it{p} (GeV/#it{c});d#it{E}/d#it{x};entries", {HistType::kTH2D, {axisP, axisDeDx}}); + registry.add("hMassVsPtDplusAll", "Dplus candidates (all, regardless the pairing with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDplus}}); + registry.add("hMassVsPtDplusPaired", "Dplus candidates (paired with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDplus}}); + registry.add("hMassDplusK0s", "DplusK0s candidates; m_{D^{+}K^{0}_{S}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToK}}); + registry.add("hMassDplusPi", "DplusPi candidates; m_{D^{+}#pi^{-}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPi}}); + registry.add("hMassDplusK", "DplusK candidates; m_{D^{+}#pi^{-}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToK}}); + registry.add("hMassDplusProton", "DplusProton candidates; m_{D^{+}p} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPr}}); + registry.add("hMassDplusLambda", "DplusLambda candidates; m_{D^{+}#Lambda} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToLambda}}); + if (doprocessDplusV0MC || doprocessDplusTrackMC || doprocessDplusV0AndTrackMC || doprocessDplusV0MCWithMl || doprocessDplusTrackMCWithMl || doprocessDplusV0AndTrackMCWithMl) { + // MC Rec + int const nChannels = hf_decay::hf_cand_reso::DecayChannelMain::NChannelsMain; + registry.add("hMCRecCounter", "Number of Reconstructed MC Matched candidates per channel", {HistType::kTH1D, {{2 * nChannels + 1, -(nChannels + 0.5), nChannels + 0.5}}}); + registry.add("hMCRecDebug", "Debug of MC Reco", {HistType::kTH1D, {{551, -0.5, 550.5}}}); + registry.add("hMCRecOrigin", "Origin of Matched particles", {HistType::kTH1D, {{3, -0.5, 2.5}}}); + registry.add("hMCRecMassGen", "Generated inv. mass of resoncances", {HistType::kTH1D, {{2000, 1.8, 3.8}}}); + registry.add("hMCRecCharmDau", "Charm daughter flag", {HistType::kTH1D, {{57, -28.5, 28.5}}}); + // MC Gen + registry.add("hMCGenCounter", "Number of Generated particles; Decay Channel Flag; pT [GeV/c]", {HistType::kTH2D, {{17, -8.5, 8.5}, {100, 0, 50}}}); + registry.add("hMCGenOrigin", "Origin of Generated particles", {HistType::kTH1D, {{3, -0.5, 2.5}}}); + } + // Configure CCDB access + ccdb->setURL(ccdbUrl.value); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); + ccdbApi.init(ccdbUrl); + runNumber = 0; + lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get("GLO/Param/MatLUT")); + + // Configure DCA fitter + fitter.setPropagateToPCA(true); + fitter.setMaxR(200.); + fitter.setMinParamChange(1e-3); + fitter.setMinRelChi2Change(0.9); + fitter.setMaxDZIni(1e9); + fitter.setMaxDXYIni(4); + fitter.setMaxChi2(1e9); + fitter.setUseAbsDCA(true); + fitter.setWeightedFinalPCA(false); + + // init HF event selection helper + hfEvSel.init(registry); + + const auto& workflows = initContext.services().get(); + for (const DeviceSpec& device : workflows.devices) { + if (device.name == "hf-data-creator-charm-reso-to-dplus-reduced") { + // init HF event selection helper + hfEvSelMc.init(device, registry); + break; + } + } + } + + // Process functions + // No ML + // Data + void processDplusV0(soa::Join const& collisions, + CandsDplusFiltered const& candsDplus, + aod::V0s const& v0s, + TracksIUWithPID const& tracksIU, + aod::BCsWithTimestamps const&) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, dummyTable, dummyTable, dummyTable, dummyTable); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDplusReduced, processDplusV0, "Process Dplus candidates paired with V0s", false); + + void processDplusTrack(soa::Join const& collisions, + CandsDplusFiltered const& candsDplus, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, + aod::BCsWithTimestamps const&) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, dummyTable, hfTrackNoParam, dummyTable, dummyTable, dummyTable); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDplusReduced, processDplusTrack, "Process Dplus candidates paired with Tracks", false); + + void processDplusV0AndTrack(soa::Join const& collisions, + CandsDplusFiltered const& candsDplus, + aod::V0s const& v0s, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, + TracksIUWithPID const& tracksIU, + aod::BCsWithTimestamps const&) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, hfTrackNoParam, dummyTable, dummyTable, dummyTable); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDplusReduced, processDplusV0AndTrack, "Process Dplus candidates paired with V0s and Tracks", false); + + // ML + // Data + void processDplusV0WithMl(soa::Join const& collisions, + CandsDplusFilteredWithMl const& candsDplus, + aod::V0s const& v0s, + TracksIUWithPID const& tracksIU, + aod::BCsWithTimestamps const&) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollisionWithMl, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, dummyTable, dummyTable, dummyTable, hfCandD3PrMl); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDplusReduced, processDplusV0WithMl, "Process Dplus candidates paired with V0s with ML info", false); + + void processDplusTrackWithMl(soa::Join const& collisions, + CandsDplusFilteredWithMl const& candsDplus, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, + aod::BCsWithTimestamps const&) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollisionWithMl, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, dummyTable, hfTrackNoParam, dummyTable, dummyTable, hfCandD3PrMl); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDplusReduced, processDplusTrackWithMl, "Process Dplus candidates paired with Tracks with ML info", false); + + void processDplusV0AndTrackWithMl(soa::Join const& collisions, + CandsDplusFilteredWithMl const& candsDplus, + aod::V0s const& v0s, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, + TracksIUWithPID const& tracksIU, + aod::BCsWithTimestamps const&) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollisionWithMl, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, hfTrackNoParam, dummyTable, dummyTable, hfCandD3PrMl); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDplusReduced, processDplusV0AndTrackWithMl, "Process Dplus candidates paired with V0s and Tracks with ML info", false); + + // Dplus + void processDplusV0MC(soa::Join const& collisions, + CandsDplusFilteredWithMc const& candsDplus, + aod::V0s const& v0s, + TracksIUWithPIDAndMC const& tracksIU, + aod::McParticles const& particlesMc, + BCsInfo const& bcs, + McCollisionsNoCents const& collInfos, + aod::McCollisions const& mcCollisions) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, dummyTable, rowHf3PrV0McRecReduced, dummyTable, dummyTable); + } + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDplusReduced, processDplusV0MC, "Process Dplus candidates paired with V0s with MC matching", false); + + void processDplusTrackMC(soa::Join const& collisions, + CandsDplusFilteredWithMc const& candsDplus, + TracksWithPIDAndMC const& tracks, + aod::TrackAssoc const& trackIndices, + aod::McParticles const& particlesMc, + BCsInfo const& bcs, + McCollisionsNoCents const& collInfos, + aod::McCollisions const& mcCollisions) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, dummyTable, hfTrackNoParam, dummyTable, rowHf3PrTrkMcRecReduced, dummyTable); + } + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDplusReduced, processDplusTrackMC, "Process Dplus candidates paired with tracks with MC matching", false); + + void processDplusV0AndTrackMC(soa::Join const& collisions, + CandsDplusFilteredWithMc const& candsDplus, + aod::V0s const& v0s, + aod::TrackAssoc const& trackIndices, + TracksWithPIDAndMC const& tracks, + TracksIUWithPIDAndMC const& tracksIU, + aod::McParticles const& particlesMc, + BCsInfo const& bcs, + McCollisionsNoCents const& collInfos, + aod::McCollisions const& mcCollisions) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, hfTrackNoParam, rowHf3PrV0McRecReduced, rowHf3PrTrkMcRecReduced, dummyTable); + } + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDplusReduced, processDplusV0AndTrackMC, "Process Dplus candidates paired with V0s and tracks with MC matching", false); + + // ML + void processDplusV0MCWithMl(soa::Join const& collisions, + CandsDplusFilteredWithMlAndMc const& candsDplus, + aod::V0s const& v0s, + TracksIUWithPIDAndMC const& tracksIU, + aod::McParticles const& particlesMc, + BCsInfo const& bcs, + McCollisionsNoCents const& collInfos, + aod::McCollisions const& mcCollisions) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollisionWithMl, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, dummyTable, rowHf3PrV0McRecReduced, dummyTable, hfCandD3PrMl); + } + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDplusReduced, processDplusV0MCWithMl, "Process Dplus candidates paired with V0s with MC matching and with ML info", false); + + void processDplusTrackMCWithMl(soa::Join const& collisions, + CandsDplusFilteredWithMlAndMc const& candsDplus, + TracksWithPIDAndMC const& tracks, + aod::TrackAssoc const& trackIndices, + aod::McParticles const& particlesMc, + BCsInfo const& bcs, + McCollisionsNoCents const& collInfos, + aod::McCollisions const& mcCollisions) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollisionWithMl, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, dummyTable, hfTrackNoParam, dummyTable, rowHf3PrTrkMcRecReduced, hfCandD3PrMl); + } + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDplusReduced, processDplusTrackMCWithMl, "Process Dplus candidates paired with tracks with MC matching and with ML info", false); + + void processDplusV0AndTrackMCWithMl(soa::Join const& collisions, + CandsDplusFilteredWithMlAndMc const& candsDplus, + aod::V0s const& v0s, + aod::TrackAssoc const& trackIndices, + TracksWithPIDAndMC const& tracks, + TracksIUWithPIDAndMC const& tracksIU, + aod::McParticles const& particlesMc, + BCsInfo const& bcs, + McCollisionsNoCents const& collInfos, + aod::McCollisions const& mcCollisions) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollisionWithMl, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, hfTrackNoParam, rowHf3PrV0McRecReduced, rowHf3PrTrkMcRecReduced, hfCandD3PrMl); + } + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDplusReduced, processDplusV0AndTrackMCWithMl, "Process Dplus candidates paired with V0s and tracks with MC matching and with ML info", false); +}; // struct + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDstarReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDstarReduced.cxx new file mode 100644 index 00000000000..a3b65badc8a --- /dev/null +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDstarReduced.cxx @@ -0,0 +1,773 @@ +// Copyright 2019-2020 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 dataCreatorCharmResoToDstarReduced.cxx +/// \brief Creation of D* V0 and D* track pairs +/// +/// \author Luca Aglietta , UniTO Turin +/// \author Fabrizio Grosa , CERN + +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/DecayChannels.h" +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/D2H/Core/DataCreationCharmReso.h" +#include "PWGHF/D2H/DataModel/ReducedDataModel.h" +#include "PWGHF/D2H/Utils/utilsRedDataFormat.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsBfieldCCDB.h" +#include "PWGHF/Utils/utilsEvSelHf.h" +#include "PWGHF/Utils/utilsMcMatching.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::analysis; +using namespace o2::aod; +using namespace o2::analysis::hf_charm_reso; +using namespace o2::constants::physics; +using namespace o2::framework; +using namespace o2::framework::expressions; + + +/// Creation of D-V0 pairs +struct HfDataCreatorCharmResoToDstarReduced { + + // Produces AOD tables to store collision information + Produces hfReducedCollision; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h + Produces hfCollisionCounter; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h + // tracks, V0 and D candidates reduced tables + Produces hfCandV0; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h + Produces hfTrackNoParam; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h + Produces hfCandDstar; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h + // ML optional Tables + Produces hfCandD3PrMl; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h + // MC Tables + Produces rowHfResoMcGenReduced; + Produces rowHfDstarV0McRecReduced; + Produces rowHfDstarTrkMcRecReduced; + + // selection D + struct : ConfigurableGroup { + std::string prefix = "dmesons"; + Configurable selectionFlagDstarToD0Pi{"selectionFlagDstarToD0Pi", true, "Selection Flag for D* decay to D0 & Pi"}; + } cfgDmesCuts; + + // selection V0 + struct : ConfigurableGroup { + std::string prefix = "v0s"; + Configurable deltaMassK0s{"deltaMassK0s", 0.02, "delta mass cut for K0S"}; + Configurable deltaMassLambda{"deltaMassLambda", 0.01, "delta mass cut for Lambda"}; + Configurable etaMax{"etaMax", 0.8f, "maximum eta"}; + Configurable etaMaxDau{"etaMaxDau", 5.f, "maximum eta V0 daughters"}; + Configurable trackNclusItsCut{"trackNclusItsCut", 0, "Minimum number of ITS clusters for V0 daughter"}; + Configurable trackNCrossedRowsTpc{"trackNCrossedRowsTpc", 50, "Minimum TPC crossed rows"}; + Configurable trackNsharedClusTpc{"trackNsharedClusTpc", 1000, "Maximum number of shared TPC clusters for V0 daughter"}; + Configurable trackFracMaxindableTpcCls{"trackFracMaxindableTpcCls", 0.8f, "Maximum fraction of findable TPC clusters for V0 daughter"}; + Configurable dcaDau{"dcaDau", 1.f, "DCA V0 daughters"}; + Configurable dcaMaxDauToPv{"dcaMaxDauToPv", 0.1f, "Maximum daughter's DCA to PV"}; + Configurable dcaPv{"dcaPv", 1.f, "DCA V0 to PV"}; + Configurable cosPa{"cosPa", 0.99f, "V0 CosPA"}; + Configurable radiusMin{"radiusMin", 0.9f, "Minimum v0 radius accepted"}; + Configurable nSigmaTpc{"nSigmaTpc", 4.f, "Nsigmatpc"}; + Configurable nSigmaTofPr{"nSigmaTofPr", 4.f, "N sigma TOF for protons only"}; + Configurable propagateV0toPV{"propagateV0toPV", false, "Enable or disable V0 propagation to V0"}; + } cfgV0Cuts; + + // selection single tracks + struct : ConfigurableGroup { + std::string prefix = "singleTracks"; + Configurable setTrackSelections{"setTrackSelections", 2, "flag to apply track selections: 0=none; 1=global track w/o DCA selection; 2=global track; 3=only ITS quality"}; + Configurable maxEta{"maxEta", 0.8, "maximum pseudorapidity for single tracks to be paired with D mesons"}; + Configurable minPt{"minPt", 0.1, "minimum pT for single tracks to be paired with D mesons"}; + Configurable maxNsigmaTpcPi{"maxNsigmaTpcPi", -1., "maximum pion NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; + Configurable maxNsigmaTpcKa{"maxNsigmaTpcKa", -1., "maximum kaon NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; + Configurable maxNsigmaTpcPr{"maxNsigmaTpcPr", 3., "maximum proton NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; + } cfgSingleTrackCuts; + + // QA histograms + struct : ConfigurableGroup { + std::string prefix = "qaPlots"; + Configurable applyCutsForQaHistograms{"applyCutsForQaHistograms", true, "flag to apply cuts to QA histograms"}; + Configurable cutMassDstarMin{"cutMassDstarMin", 0.143, "minimum mass for Dstar candidates"}; + Configurable cutMassDstarMax{"cutMassDstarMax", 0.155, "maximum mass for Dstar candidates"}; + Configurable cutMassK0sMin{"cutMassK0sMin", 0.485, "minimum mass for K0s candidates"}; + Configurable cutMassK0sMax{"cutMassK0sMax", 0.509, "maximum mass for K0s candidates"}; + Configurable cutMassLambdaMin{"cutMassLambdaMin", 1.11, "minimum mass for Lambda candidates"}; + Configurable cutMassLambdaMax{"cutMassLambdaMax", 1.12, "maximum mass for Lambda candidates"}; + } cfgQaPlots; + // other configurables + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; + Configurable doMcRecQa{"doMcRecQa", true, "Fill QA histograms for Mc matching"}; + Configurable rejectPairsWithCommonDaughter{"rejectPairsWithCommonDaughter", true, "flag to reject already at this stage the pairs that share a daughter track"}; + Configurable rejectCollisionsWithBadEvSel{"rejectCollisionsWithBadEvSel", true, "flag to reject collisions with bad event selection"}; + + o2::hf_evsel::HfEventSelection hfEvSel; + o2::hf_evsel::HfEventSelectionMc hfEvSelMc; + + // CCDB service + o2::ccdb::CcdbApi ccdbApi; + Service ccdb; + double bz{0.}; + int runNumber{0}; // needed to detect if the run changed and trigger update of calibrations etc. + + // material correction for track propagation + o2::base::MatLayerCylSet* lut{}; + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + + // O2DatabasePDG service + Service pdg; + + // vertex fitter + o2::vertexing::DCAFitterN<2> fitter; + + // Dstar + using CandsDstarFiltered = soa::Filtered>; + using CandsDstarFilteredWithMl = soa::Filtered>; + using CandsDstarFilteredWithMc = soa::Filtered>; + using CandsDstarFilteredWithMlAndMc = soa::Filtered>; + // Tracks + using TracksWithPID = soa::Join; + using TracksWithPIDAndMC = soa::Join; + using TracksIUWithPID = soa::Join; + using TracksIUWithPIDAndMC = soa::Join; + // Collisions MC + using BCsInfo = soa::Join; + using McCollisionsNoCents = soa::Join; + + Filter filterSelectedCandDstar = (aod::hf_sel_candidate_dstar::isSelDstarToD0Pi == cfgDmesCuts.selectionFlagDstarToD0Pi); + + Preslice candsDstarPerCollision = aod::hf_cand::collisionId; + Preslice candsDstarPerCollisionWithMl = aod::hf_cand::collisionId; + Preslice candsV0PerCollision = aod::v0::collisionId; + Preslice trackIndicesPerCollision = aod::track_association::collisionId; + Preslice mcParticlesPerMcCollision = aod::mcparticle::mcCollisionId; + PresliceUnsorted colPerMcCollision = aod::mccollisionlabel::mcCollisionId; + + HistogramRegistry registry{"registry"}; + + void init(InitContext& initContext) + { + // histograms + constexpr int kNBinsEvents = kNEvent; + std::string labels[kNBinsEvents]; + labels[Event::Processed] = "processed"; + labels[Event::NoDV0Selected] = "without DV0 pairs"; + labels[Event::DV0Selected] = "with DV0 pairs"; + static const AxisSpec axisEvents = {kNBinsEvents, 0.5, kNBinsEvents + 0.5, ""}; + registry.add("hEvents", "Events;;entries", HistType::kTH1D, {axisEvents}); + for (int iBin = 0; iBin < kNBinsEvents; iBin++) { + registry.get(HIST("hEvents"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); + } + + const AxisSpec axisPt{50, 0.f, 50.f, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec axisP{100, 0.f, 10.f, "#it{p} (GeV/#it{c})"}; + const AxisSpec axisDeDx{500, 0.f, 1000.f, ""}; + const AxisSpec axisMassDstar{200, 0.139f, 0.179f, "delta inv. mass (GeV/#it{c}^{2})"}; // o2-linter: disable=pdg/explicit-mass (false positive) + const AxisSpec axisMassLambda{100, 1.05f, 1.35f, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisMassKzero{100, 0.35f, 0.65f, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisDeltaMassToK{500, 0.49, 1.49, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisDeltaMassToPi{500, 0.13, 1.13, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisDeltaMassToPr{500, 0.93, 1.93, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisDeltaMassToLambda{500, 1.05, 2.05, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisMassDsj{400, 0.49f, 0.89f, ""}; // Ds1 and Ds2Star legacy + registry.add("hMassVsPtK0s", "K0^{s} candidates;#it{p}_{T} (GeV/#it{c});inv. mass (#pi^{#plus}#pi^{#minus}) (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassKzero}}); + registry.add("hMassVsPtLambda", "Lambda candidates;#it{p}_{T} (GeV/#it{c});inv. mass (p #pi^{#minus}) (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassLambda}}); + registry.add("hdEdxVsP", "Tracks;#it{p} (GeV/#it{c});d#it{E}/d#it{x};entries", {HistType::kTH2D, {axisP, axisDeDx}}); + registry.add("hMassVsPtDstarAll", "Dstar candidates (all, regardless the pairing with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDstar}}); + registry.add("hMassVsPtDstarPaired", "Dstar candidates (paired with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDstar}}); + registry.add("hMassDstarPi", "DstarPi candidates; m_{D^{*+}#pi^{-}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPi}}); + registry.add("hMassDstarK", "DstarK candidates; m_{D^{*+}#pi^{-}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToK}}); + registry.add("hMassDstarProton", "DstarProton candidates; m_{D^{*}p} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPr}}); + registry.add("hMassDstarK0s", "DstarK0s candidates; m_{D^{*}K^{0}_{S}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToK}}); + registry.add("hMassDstarLambda", "DstarLambda candidates; m_{D^{*}#Lambda} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToLambda}}); + if (doprocessDstarV0MC || doprocessDstarTrackMC || doprocessDstarV0AndTrackMC || doprocessDstarV0MCWithMl || doprocessDstarTrackMCWithMl || doprocessDstarV0AndTrackMCWithMl) { + // MC Rec + int const nChannels = hf_decay::hf_cand_reso::DecayChannelMain::NChannelsMain; + registry.add("hMCRecCounter", "Number of Reconstructed MC Matched candidates per channel", {HistType::kTH1D, {{2 * nChannels + 1, -(nChannels + 0.5), nChannels + 0.5}}}); + registry.add("hMCRecDebug", "Debug of MC Reco", {HistType::kTH1D, {{551, -0.5, 550.5}}}); + registry.add("hMCRecOrigin", "Origin of Matched particles", {HistType::kTH1D, {{3, -0.5, 2.5}}}); + registry.add("hMCRecMassGen", "Generated inv. mass of resoncances", {HistType::kTH1D, {{2000, 1.8, 3.8}}}); + registry.add("hMCRecCharmDau", "Charm daughter flag", {HistType::kTH1D, {{57, -28.5, 28.5}}}); + // MC Gen + registry.add("hMCGenCounter", "Number of Generated particles; Decay Channel Flag; pT [GeV/c]", {HistType::kTH2D, {{17, -8.5, 8.5}, {100, 0, 50}}}); + registry.add("hMCGenOrigin", "Origin of Generated particles", {HistType::kTH1D, {{3, -0.5, 2.5}}}); + } + // Configure CCDB access + ccdb->setURL(ccdbUrl.value); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); + ccdbApi.init(ccdbUrl); + runNumber = 0; + lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get("GLO/Param/MatLUT")); + + // Configure DCA fitter + fitter.setPropagateToPCA(true); + fitter.setMaxR(200.); + fitter.setMinParamChange(1e-3); + fitter.setMinRelChi2Change(0.9); + fitter.setMaxDZIni(1e9); + fitter.setMaxDXYIni(4); + fitter.setMaxChi2(1e9); + fitter.setUseAbsDCA(true); + fitter.setWeightedFinalPCA(false); + + // init HF event selection helper + hfEvSel.init(registry); + + const auto& workflows = initContext.services().get(); + for (const DeviceSpec& device : workflows.devices) { + if (device.name == "hf-data-creator-charm-reso-to-dstar-reduced") { + // init HF event selection helper + hfEvSelMc.init(device, registry); + break; + } + } + } + + // Process functions + // No ML + // Data + void processDstarV0(soa::Join const& collisions, + CandsDstarFiltered const& candsDstar, + aod::V0s const& v0s, + TracksIUWithPID const& tracksIU, + aod::BCsWithTimestamps const&) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, dummyTable, dummyTable, dummyTable, dummyTable); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDstarReduced, processDstarV0, "Process Dstar candidates paired with V0s", true); + + void processDstarTrack(soa::Join const& collisions, + CandsDstarFiltered const& candsDstar, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, + aod::BCsWithTimestamps const&) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, dummyTable, hfTrackNoParam, dummyTable, dummyTable, dummyTable); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDstarReduced, processDstarTrack, "Process Dstar candidates paired with Tracks", false); + + void processDstarV0AndTrack(soa::Join const& collisions, + CandsDstarFiltered const& candsDstar, + aod::V0s const& v0s, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, + TracksIUWithPID const& tracksIU, + aod::BCsWithTimestamps const&) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, hfTrackNoParam, dummyTable, dummyTable, dummyTable); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDstarReduced, processDstarV0AndTrack, "Process Dstar candidates paired with V0s and Tracks", false); + + // ML + // Data + void processDstarV0WithMl(soa::Join const& collisions, + CandsDstarFilteredWithMl const& candsDstar, + aod::V0s const& v0s, + TracksIUWithPID const& tracksIU, + aod::BCsWithTimestamps const&) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollisionWithMl, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, dummyTable, dummyTable, dummyTable, hfCandD3PrMl); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDstarReduced, processDstarV0WithMl, "Process Dstar candidates paired with V0s with ML info", false); + + void processDstarTrackWithMl(soa::Join const& collisions, + CandsDstarFilteredWithMl const& candsDstar, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, + aod::BCsWithTimestamps const&) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollisionWithMl, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, dummyTable, hfTrackNoParam, dummyTable, dummyTable, hfCandD3PrMl); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDstarReduced, processDstarTrackWithMl, "Process Dstar candidates paired with Tracks with ML info", false); + + void processDstarV0AndTrackWithMl(soa::Join const& collisions, + CandsDstarFilteredWithMl const& candsDstar, + aod::V0s const& v0s, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, + TracksIUWithPID const& tracksIU, + aod::BCsWithTimestamps const&) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollisionWithMl, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, hfTrackNoParam, dummyTable, dummyTable, hfCandD3PrMl); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDstarReduced, processDstarV0AndTrackWithMl, "Process Dstar candidates paired with V0s and Tracks with ML info", false); + + // MC + // No ML + void processDstarV0MC(soa::Join const& collisions, + CandsDstarFilteredWithMc const& candsDstar, + aod::V0s const& v0s, + TracksIUWithPIDAndMC const& tracksIU, + aod::McParticles const& particlesMc, + BCsInfo const& bcs, + McCollisionsNoCents const& collInfos, + aod::McCollisions const& mcCollisions) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, dummyTable, rowHfDstarV0McRecReduced, dummyTable, dummyTable); + } + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDstarReduced, processDstarV0MC, "Process Dstar candidates paired with V0s with MC matching", false); + + void processDstarTrackMC(soa::Join const& collisions, + CandsDstarFilteredWithMc const& candsDstar, + TracksWithPIDAndMC const& tracks, + aod::TrackAssoc const& trackIndices, + aod::McParticles const& particlesMc, + BCsInfo const& bcs, + McCollisionsNoCents const& collInfos, + aod::McCollisions const& mcCollisions) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, dummyTable, hfTrackNoParam, dummyTable, rowHfDstarTrkMcRecReduced, dummyTable); + } + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDstarReduced, processDstarTrackMC, "Process Dstar candidates paired with tracks with MC matching", false); + + void processDstarV0AndTrackMC(soa::Join const& collisions, + CandsDstarFilteredWithMc const& candsDstar, + aod::V0s const& v0s, + aod::TrackAssoc const& trackIndices, + TracksWithPIDAndMC const& tracks, + TracksIUWithPIDAndMC const& tracksIU, + aod::McParticles const& particlesMc, + BCsInfo const& bcs, + McCollisionsNoCents const& collInfos, + aod::McCollisions const& mcCollisions) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, hfTrackNoParam, rowHfDstarV0McRecReduced, rowHfDstarTrkMcRecReduced, dummyTable); + } + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDstarReduced, processDstarV0AndTrackMC, "Process Dstar candidates paired with V0s and tracks with MC matching", false); + + // ML + void processDstarV0MCWithMl(soa::Join const& collisions, + CandsDstarFilteredWithMlAndMc const& candsDstar, + aod::V0s const& v0s, + TracksIUWithPIDAndMC const& tracksIU, + aod::McParticles const& particlesMc, + BCsInfo const& bcs, + McCollisionsNoCents const& collInfos, + aod::McCollisions const& mcCollisions) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollisionWithMl, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, dummyTable, rowHfDstarV0McRecReduced, dummyTable, hfCandD3PrMl); + } + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDstarReduced, processDstarV0MCWithMl, "Process Dstar candidates paired with V0s with MC matching and with ML info", false); + + void processDstarTrackMCWithMl(soa::Join const& collisions, + CandsDstarFilteredWithMlAndMc const& candsDstar, + TracksWithPIDAndMC const& tracks, + aod::TrackAssoc const& trackIndices, + aod::McParticles const& particlesMc, + BCsInfo const& bcs, + McCollisionsNoCents const& collInfos, + aod::McCollisions const& mcCollisions) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + int dummyTable{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollisionWithMl, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, dummyTable, hfTrackNoParam, dummyTable, rowHfDstarTrkMcRecReduced, hfCandD3PrMl); + } + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDstarReduced, processDstarTrackMCWithMl, "Process Dstar candidates paired with tracks with MC matching and with ML info", false); + + void processDstarV0AndTrackMCWithMl(soa::Join const& collisions, + CandsDstarFilteredWithMlAndMc const& candsDstar, + aod::V0s const& v0s, + aod::TrackAssoc const& trackIndices, + TracksWithPIDAndMC const& tracks, + TracksIUWithPIDAndMC const& tracksIU, + aod::McParticles const& particlesMc, + BCsInfo const& bcs, + McCollisionsNoCents const& collInfos, + aod::McCollisions const& mcCollisions) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + float centrality = -1.f; + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { + continue; + } + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag, lut, false); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + fitter.setBz(bz); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollisionWithMl, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, hfTrackNoParam, rowHfDstarV0McRecReduced, rowHfDstarTrkMcRecReduced, hfCandD3PrMl); + } + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoToDstarReduced, processDstarV0AndTrackMCWithMl, "Process Dstar candidates paired with V0s and tracks with MC matching and with ML info", false); +}; // struct + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} From 6d9644209cdb961319bb5f3cf0978fff70b10a61 Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Fri, 28 Nov 2025 16:28:38 +0000 Subject: [PATCH 02/10] Please consider the following formatting changes --- PWGHF/D2H/Core/DataCreationCharmReso.h | 2765 +++++++++-------- .../dataCreatorCharmResoToD0Reduced.cxx | 1 - .../dataCreatorCharmResoToDplusReduced.cxx | 1 - .../dataCreatorCharmResoToDstarReduced.cxx | 1 - 4 files changed, 1383 insertions(+), 1385 deletions(-) diff --git a/PWGHF/D2H/Core/DataCreationCharmReso.h b/PWGHF/D2H/Core/DataCreationCharmReso.h index afb12678053..d2fdac71f21 100644 --- a/PWGHF/D2H/Core/DataCreationCharmReso.h +++ b/PWGHF/D2H/Core/DataCreationCharmReso.h @@ -20,8 +20,8 @@ #include "PWGHF/Core/CentralityEstimation.h" #include "PWGHF/Core/DecayChannels.h" -#include "PWGHF/Utils/utilsMcMatching.h" #include "PWGHF/Utils/utilsEvSelHf.h" +#include "PWGHF/Utils/utilsMcMatching.h" #include "Common/Core/RecoDecay.h" #include "Common/Core/trackUtilities.h" @@ -45,1499 +45,1500 @@ #include #include -namespace o2::analysis { - namespace hf_charm_reso { +namespace o2::analysis +{ +namespace hf_charm_reso +{ - // event types - enum Event : uint8_t { - Processed = 0, - NoDV0Selected, - DV0Selected, - kNEvent - }; +// event types +enum Event : uint8_t { + Processed = 0, + NoDV0Selected, + DV0Selected, + kNEvent +}; - enum BachelorType : uint8_t { - K0s = 0, - Lambda, - AntiLambda, - Track - }; +enum BachelorType : uint8_t { + K0s = 0, + Lambda, + AntiLambda, + Track +}; - enum DType : uint8_t { - Dplus = 1, - Dstar, - D0 - }; +enum DType : uint8_t { + Dplus = 1, + Dstar, + D0 +}; - enum PairingType : uint8_t { - V0Only, - TrackOnly, - V0AndTrack - }; +enum PairingType : uint8_t { + V0Only, + TrackOnly, + V0AndTrack +}; - enum D0Sel : uint8_t { - SelectedD0 = 0, - SelectedD0Bar - }; +enum D0Sel : uint8_t { + SelectedD0 = 0, + SelectedD0Bar +}; - // Helper structs to pass D and V0 informations +// Helper structs to pass D and V0 informations - struct candidateV0 { - std::array pos; - std::array mom; - std::array momPos; - std::array momNeg; - float pT; - float cosPA; - float dcaV0ToPv; - float dcaDau; - float alpha; - float eta; - float radius; - float mK0Short; - float mLambda; - uint8_t v0Type; - }; +struct candidateV0 { + std::array pos; + std::array mom; + std::array momPos; + std::array momNeg; + float pT; + float cosPA; + float dcaV0ToPv; + float dcaDau; + float alpha; + float eta; + float radius; + float mK0Short; + float mLambda; + uint8_t v0Type; +}; - struct varContainer { - float invMassD; - float ptD; - float invMassD0; - float invMassD0Bar; - float invMassReso; - float ptReso; - int8_t signD; - std::array pVectorProng0; - std::array pVectorProng1; - std::array pVectorProng2; - }; +struct varContainer { + float invMassD; + float ptD; + float invMassD0; + float invMassD0Bar; + float invMassReso; + float ptReso; + int8_t signD; + std::array pVectorProng0; + std::array pVectorProng1; + std::array pVectorProng2; +}; - /// Basic track quality selections for V0 daughters - /// \param Tr is a track - /// \param dDaughtersIds are the IDs of the D meson daughter tracks - /// \param cfgV0Cuts are the cuts to be applied to the V0 - /// \param rejectPairsWithCommonDaughter is a flag to activate rejection of pairs sharing a daughter track - template - bool selectV0Daughter(Tr const& track, const std::array& dDaughtersIds, const Cuts& cfgV0Cuts, bool rejectPairsWithCommonDaughter) - { - // acceptance selection - if (std::abs(track.eta()) > cfgV0Cuts.etaMaxDau.value) { - return false; - } - // Tpc Refit - if (!(track.hasTPC())) { - return false; - } - // track quality selection - if (track.itsNCls() < cfgV0Cuts.trackNclusItsCut.value || - track.tpcNClsFound() < cfgV0Cuts.trackNCrossedRowsTpc.value || - track.tpcNClsCrossedRows() < cfgV0Cuts.trackNCrossedRowsTpc.value || - track.tpcNClsCrossedRows() < cfgV0Cuts.trackFracMaxindableTpcCls.value * track.tpcNClsFindable() || - track.tpcNClsShared() > cfgV0Cuts.trackNsharedClusTpc.value) { - return false; - } - // rejection of tracks that share a daughter with the D meson - if (rejectPairsWithCommonDaughter && std::find(dDaughtersIds.begin(), dDaughtersIds.end(), track.globalIndex()) != dDaughtersIds.end()) { - return false; - } - return true; - } +/// Basic track quality selections for V0 daughters +/// \param Tr is a track +/// \param dDaughtersIds are the IDs of the D meson daughter tracks +/// \param cfgV0Cuts are the cuts to be applied to the V0 +/// \param rejectPairsWithCommonDaughter is a flag to activate rejection of pairs sharing a daughter track +template +bool selectV0Daughter(Tr const& track, const std::array& dDaughtersIds, const Cuts& cfgV0Cuts, bool rejectPairsWithCommonDaughter) +{ + // acceptance selection + if (std::abs(track.eta()) > cfgV0Cuts.etaMaxDau.value) { + return false; + } + // Tpc Refit + if (!(track.hasTPC())) { + return false; + } + // track quality selection + if (track.itsNCls() < cfgV0Cuts.trackNclusItsCut.value || + track.tpcNClsFound() < cfgV0Cuts.trackNCrossedRowsTpc.value || + track.tpcNClsCrossedRows() < cfgV0Cuts.trackNCrossedRowsTpc.value || + track.tpcNClsCrossedRows() < cfgV0Cuts.trackFracMaxindableTpcCls.value * track.tpcNClsFindable() || + track.tpcNClsShared() > cfgV0Cuts.trackNsharedClusTpc.value) { + return false; + } + // rejection of tracks that share a daughter with the D meson + if (rejectPairsWithCommonDaughter && std::find(dDaughtersIds.begin(), dDaughtersIds.end(), track.globalIndex()) != dDaughtersIds.end()) { + return false; + } + return true; +} - /// Utility to find which v0 daughter carries the largest fraction of the mother longitudinal momentum - /// \param momV0 is the momentum of the V0 - /// \param momDau0 is the momentum of first daughter - /// \param momDau1 is the momentum of second daughter - /// \return alphaAP - float alphaAP(std::array const& momV0, std::array const& momDau0, std::array const& momDau1) - { - float const momTot = std::sqrt(std::pow(momV0[0], 2.) + std::pow(momV0[1], 2.) + std::pow(momV0[2], 2.)); - float const lQlPos = (momDau0[0] * momV0[0] + momDau0[1] * momV0[1] + momDau0[2] * momV0[2]) / momTot; - float const lQlNeg = (momDau1[0] * momV0[0] + momDau1[1] * momV0[1] + momDau1[2] * momV0[2]) / momTot; - return (lQlPos - lQlNeg) / (lQlPos + lQlNeg); - } +/// Utility to find which v0 daughter carries the largest fraction of the mother longitudinal momentum +/// \param momV0 is the momentum of the V0 +/// \param momDau0 is the momentum of first daughter +/// \param momDau1 is the momentum of second daughter +/// \return alphaAP +float alphaAP(std::array const& momV0, std::array const& momDau0, std::array const& momDau1) +{ + float const momTot = std::sqrt(std::pow(momV0[0], 2.) + std::pow(momV0[1], 2.) + std::pow(momV0[2], 2.)); + float const lQlPos = (momDau0[0] * momV0[0] + momDau0[1] * momV0[1] + momDau0[2] * momV0[2]) / momTot; + float const lQlNeg = (momDau1[0] * momV0[0] + momDau1[1] * momV0[1] + momDau1[2] * momV0[2]) / momTot; + return (lQlPos - lQlNeg) / (lQlPos + lQlNeg); +} + +/// Utility to find DCA of V0 to Primary vertex +/// \param x is the x-coordinate +/// \param y is the y-coordinate +/// \param z is the z-coordinate +/// \param px is the x-component of the momentum +/// \param py is the y-component of the momentum +/// \param pz is the z-component of the momentum +/// \param pvX is the x-coordinate of the PV +/// \param pvY is the y-coordinate of the PV +/// \param pvZ is the z-coordinate of the PV +/// \return the DCA +float calculateDCAStraightToPV(float x, float y, float z, float px, float py, float pz, float pvX, float pvY, float pvZ) +{ + return std::sqrt((std::pow((pvY - y) * pz - (pvZ - z) * py, 2) + std::pow((pvX - x) * pz - (pvZ - z) * px, 2) + std::pow((pvX - x) * py - (pvY - y) * px, 2)) / (px * px + py * py + pz * pz)); +} + +/// Basic selection of V0 candidates +/// \param collision is the current collision +/// \param dauTracks are the v0 daughter tracks +/// \param dDaughtersIds are the IDs of the D meson daughter tracks +/// \param fitter is the DCAFitter object +/// \param cfgV0Cuts are the cuts to be applied to the V0 +/// \param v0 is the V0 candidate +/// \param rejectPairsWithCommonDaughter is a flag to activate rejection of pairs sharing a daughter track +/// \return a bitmap with mass hypotesis if passes all cuts +template +bool buildAndSelectV0(const Coll& collision, const std::array& dDaughtersIds, const std::array& dauTracks, const Cuts& cfgV0Cuts, o2::vertexing::DCAFitterN<2>& fitter, candidateV0& v0, bool rejectPairsWithCommonDaughter) +{ + const auto& trackPos = dauTracks[0]; + const auto& trackNeg = dauTracks[1]; + // single-tracks selection + if (!selectV0Daughter(trackPos, dDaughtersIds, cfgV0Cuts, rejectPairsWithCommonDaughter) || !selectV0Daughter(trackNeg, dDaughtersIds, cfgV0Cuts, rejectPairsWithCommonDaughter)) { + return false; + } + // daughters DCA to V0's collision primary vertex + std::array dcaInfo{}; + auto trackPosPar = getTrackPar(trackPos); + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackPosPar, 2.f, fitter.getMatCorrType(), &dcaInfo); + auto trackPosDcaXY = dcaInfo[0]; + auto trackNegPar = getTrackPar(trackNeg); + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackNegPar, 2.f, fitter.getMatCorrType(), &dcaInfo); + auto trackNegDcaXY = dcaInfo[0]; + if (std::fabs(trackPosDcaXY) < cfgV0Cuts.dcaMaxDauToPv.value || std::fabs(trackNegDcaXY) < cfgV0Cuts.dcaMaxDauToPv.value) { + return false; + } + // vertex reconstruction + auto trackPosCov = getTrackParCov(trackPos); + auto trackNegCov = getTrackParCov(trackNeg); + int nCand = 0; + try { + nCand = fitter.process(trackPosCov, trackNegCov); + } catch (...) { + return false; + } + if (nCand == 0) { + return false; + } + // compute candidate momentum from tracks propagated to decay vertex + auto& trackPosProp = fitter.getTrack(0); + auto& trackNegProp = fitter.getTrack(1); + trackPosProp.getPxPyPzGlo(v0.momPos); + trackNegProp.getPxPyPzGlo(v0.momNeg); + + v0.mom = RecoDecay::pVec(v0.momPos, v0.momNeg); - /// Utility to find DCA of V0 to Primary vertex - /// \param x is the x-coordinate - /// \param y is the y-coordinate - /// \param z is the z-coordinate - /// \param px is the x-component of the momentum - /// \param py is the y-component of the momentum - /// \param pz is the z-component of the momentum - /// \param pvX is the x-coordinate of the PV - /// \param pvY is the y-coordinate of the PV - /// \param pvZ is the z-coordinate of the PV - /// \return the DCA - float calculateDCAStraightToPV(float x, float y, float z, float px, float py, float pz, float pvX, float pvY, float pvZ) - { - return std::sqrt((std::pow((pvY - y) * pz - (pvZ - z) * py, 2) + std::pow((pvX - x) * pz - (pvZ - z) * px, 2) + std::pow((pvX - x) * py - (pvY - y) * px, 2)) / (px * px + py * py + pz * pz)); + v0.pT = std::hypot(v0.mom[0], v0.mom[1]); + // topological selections: + // v0 eta + v0.eta = RecoDecay::eta(v0.mom); + if (std::abs(v0.eta) > cfgV0Cuts.etaMax.value) { + return false; + } + // daughters DCA + v0.dcaDau = std::sqrt(fitter.getChi2AtPCACandidate()); + if (v0.dcaDau > cfgV0Cuts.dcaDau.value) { + return false; + } + // v0 radius + const auto& vtx = fitter.getPCACandidate(); + v0.radius = std::hypot(vtx[0], vtx[1]); + if (v0.radius < cfgV0Cuts.radiusMin.value) { + return false; + } + std::copy(vtx.begin(), vtx.end(), v0.pos.begin()); + + // v0 DCA to primary vertex + v0.dcaV0ToPv = calculateDCAStraightToPV( + vtx[0], vtx[1], vtx[2], + v0.momPos[0] + v0.momNeg[0], + v0.momPos[1] + v0.momNeg[1], + v0.momPos[2] + v0.momNeg[2], + collision.posX(), collision.posY(), collision.posZ()); + if (std::abs(v0.dcaV0ToPv) > cfgV0Cuts.dcaPv.value) { + return false; + } + // v0 cosine of pointing angle + std::array const primVtx = {collision.posX(), collision.posY(), collision.posZ()}; + v0.cosPA = RecoDecay::cpa(primVtx, vtx, v0.mom); + if (v0.cosPA < cfgV0Cuts.cosPa.value) { + return false; + } + // distinguish between K0s, and Lambda hypotesys + v0.v0Type = {BIT(BachelorType::K0s) | BIT(BachelorType::Lambda) | BIT(BachelorType::AntiLambda)}; + // for lambda hypotesys define if its lambda or anti-lambda + v0.alpha = alphaAP(v0.mom, v0.momPos, v0.momNeg); + bool const matter = v0.alpha > 0; + CLRBIT(v0.v0Type, matter ? BachelorType::AntiLambda : BachelorType::Lambda); + auto massPos = matter ? o2::constants::physics::MassProton : o2::constants::physics::MassPionCharged; + auto massNeg = matter ? o2::constants::physics::MassPionCharged : o2::constants::physics::MassProton; + // mass hypotesis + v0.mLambda = RecoDecay::m(std::array{v0.momPos, v0.momNeg}, std::array{massPos, massNeg}); + v0.mK0Short = RecoDecay::m(std::array{v0.momPos, v0.momNeg}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged}); + if (std::fabs(v0.mK0Short - o2::constants::physics::MassK0) > cfgV0Cuts.deltaMassK0s.value) { + CLRBIT(v0.v0Type, BachelorType::K0s); + } + if (std::fabs(v0.mLambda - o2::constants::physics::MassLambda0) > cfgV0Cuts.deltaMassLambda.value) { + CLRBIT(v0.v0Type, BachelorType::Lambda); + CLRBIT(v0.v0Type, BachelorType::AntiLambda); + } + // PID + if (TESTBIT(v0.v0Type, BachelorType::K0s)) { + if ((trackPos.hasTPC() && std::fabs(trackPos.tpcNSigmaPi()) > cfgV0Cuts.nSigmaTpc.value) || + (trackNeg.hasTPC() && std::fabs(trackNeg.tpcNSigmaPi()) > cfgV0Cuts.nSigmaTpc.value)) { + CLRBIT(v0.v0Type, BachelorType::K0s); + } + } + if (TESTBIT(v0.v0Type, BachelorType::Lambda)) { + if ((trackPos.hasTPC() && std::fabs(trackPos.tpcNSigmaPr()) > cfgV0Cuts.nSigmaTpc.value) || + (trackPos.hasTOF() && std::fabs(trackPos.tofNSigmaPr()) > cfgV0Cuts.nSigmaTofPr.value) || + (trackNeg.hasTPC() && std::fabs(trackNeg.tpcNSigmaPi()) > cfgV0Cuts.nSigmaTpc.value)) { + CLRBIT(v0.v0Type, BachelorType::Lambda); + } + } + if (TESTBIT(v0.v0Type, BachelorType::AntiLambda)) { + if ((trackPos.hasTPC() && std::fabs(trackPos.tpcNSigmaPi()) > cfgV0Cuts.nSigmaTpc.value) || + (trackNeg.hasTPC() && std::fabs(trackNeg.tpcNSigmaPr()) > cfgV0Cuts.nSigmaTpc.value) || + (trackNeg.hasTOF() && std::fabs(trackNeg.tofNSigmaPr()) > cfgV0Cuts.nSigmaTofPr.value)) { + CLRBIT(v0.v0Type, BachelorType::AntiLambda); } + } + if (v0.v0Type == 0) { + return false; + } + return true; +} - /// Basic selection of V0 candidates - /// \param collision is the current collision - /// \param dauTracks are the v0 daughter tracks - /// \param dDaughtersIds are the IDs of the D meson daughter tracks - /// \param fitter is the DCAFitter object - /// \param cfgV0Cuts are the cuts to be applied to the V0 - /// \param v0 is the V0 candidate - /// \param rejectPairsWithCommonDaughter is a flag to activate rejection of pairs sharing a daughter track - /// \return a bitmap with mass hypotesis if passes all cuts - template - bool buildAndSelectV0(const Coll& collision, const std::array& dDaughtersIds, const std::array& dauTracks, const Cuts& cfgV0Cuts, o2::vertexing::DCAFitterN<2>& fitter, candidateV0& v0, bool rejectPairsWithCommonDaughter) - { - const auto& trackPos = dauTracks[0]; - const auto& trackNeg = dauTracks[1]; - // single-tracks selection - if (!selectV0Daughter(trackPos, dDaughtersIds, cfgV0Cuts, rejectPairsWithCommonDaughter) || !selectV0Daughter(trackNeg, dDaughtersIds, cfgV0Cuts, rejectPairsWithCommonDaughter)) { - return false; - } - // daughters DCA to V0's collision primary vertex - std::array dcaInfo{}; - auto trackPosPar = getTrackPar(trackPos); - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackPosPar, 2.f, fitter.getMatCorrType(), &dcaInfo); - auto trackPosDcaXY = dcaInfo[0]; - auto trackNegPar = getTrackPar(trackNeg); - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackNegPar, 2.f, fitter.getMatCorrType(), &dcaInfo); - auto trackNegDcaXY = dcaInfo[0]; - if (std::fabs(trackPosDcaXY) < cfgV0Cuts.dcaMaxDauToPv.value || std::fabs(trackNegDcaXY) < cfgV0Cuts.dcaMaxDauToPv.value) { +/// Basic selection of tracks +/// \param track is the track +/// \param dDaughtersIds are the IDs of the D meson daughter tracks +/// \param cfgV0Cuts are the cuts to be applied to the track +/// \param rejectPairsWithCommonDaughter is a flag to activate rejection of pairs sharing a daughter track +/// \return true if passes all cuts +template +bool isTrackSelected(const Tr& track, const std::array& dDaughtersIds, const Cuts& cfgSingleTrackCuts, bool rejectPairsWithCommonDaughter) +{ + if (rejectPairsWithCommonDaughter && std::find(dDaughtersIds.begin(), dDaughtersIds.end(), track.globalIndex()) != dDaughtersIds.end()) { + return false; + } + switch (cfgSingleTrackCuts.setTrackSelections.value) { + case 1: + if (!track.isGlobalTrackWoDCA()) { return false; } - // vertex reconstruction - auto trackPosCov = getTrackParCov(trackPos); - auto trackNegCov = getTrackParCov(trackNeg); - int nCand = 0; - try { - nCand = fitter.process(trackPosCov, trackNegCov); - } catch (...) { + break; + case 2: + if (!track.isGlobalTrack()) { return false; } - if (nCand == 0) { + break; + case 3: + if (!track.isQualityTrackITS()) { return false; } - // compute candidate momentum from tracks propagated to decay vertex - auto& trackPosProp = fitter.getTrack(0); - auto& trackNegProp = fitter.getTrack(1); - trackPosProp.getPxPyPzGlo(v0.momPos); - trackNegProp.getPxPyPzGlo(v0.momNeg); + break; + } + if (track.pt() < cfgSingleTrackCuts.minPt.value) { + return false; + } + if (std::abs(track.eta()) > cfgSingleTrackCuts.maxEta.value) { + return false; + } + if (!track.hasTPC()) { + return false; + } + bool const isPion = std::abs(track.tpcNSigmaPi()) < cfgSingleTrackCuts.maxNsigmaTpcPi.value; + bool const isKaon = std::abs(track.tpcNSigmaKa()) < cfgSingleTrackCuts.maxNsigmaTpcKa.value; + bool const isProton = std::abs(track.tpcNSigmaPr()) < cfgSingleTrackCuts.maxNsigmaTpcPr.value; + return (isPion || isKaon || isProton); // we keep the track if is it compatible with at least one of the PID hypotheses selected +} - v0.mom = RecoDecay::pVec(v0.momPos, v0.momNeg); +/// Matching of V0 candidates to MC truth +/// \param particlesMc is the table of MC particles +/// \param arrDaughtersV0 is the array of V0 daughter tracks +/// \return the MC matching flag for the V0 +template +int8_t getMatchingFlagV0(PParticles const& particlesMc, const std::array& arrDaughtersV0) +{ + int8_t signV0{0}; + int indexRec{-1}; + int flagV0{0}; + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersV0, kK0, std::array{+kPiPlus, -kPiPlus}, true, &signV0, 2); + if (indexRec > -1) { + flagV0 = hf_decay::hf_cand_reso::PartialMatchMc::K0Matched; + } else { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersV0, kLambda0, std::array{+kProton, -kPiPlus}, true, &signV0, 2); + if (indexRec > -1) { + flagV0 = signV0 * hf_decay::hf_cand_reso::PartialMatchMc::LambdaMatched; + } + } + return flagV0; // Placeholder, should return the actual flag based on matching logic +} - v0.pT = std::hypot(v0.mom[0], v0.mom[1]); - // topological selections: - // v0 eta - v0.eta = RecoDecay::eta(v0.mom); - if (std::abs(v0.eta) > cfgV0Cuts.etaMax.value) { - return false; - } - // daughters DCA - v0.dcaDau = std::sqrt(fitter.getChi2AtPCACandidate()); - if (v0.dcaDau > cfgV0Cuts.dcaDau.value) { - return false; - } - // v0 radius - const auto& vtx = fitter.getPCACandidate(); - v0.radius = std::hypot(vtx[0], vtx[1]); - if (v0.radius < cfgV0Cuts.radiusMin.value) { - return false; - } - std::copy(vtx.begin(), vtx.end(), v0.pos.begin()); +/// Matching of V0 candidates to MC truth +/// \param bachTrack is the track +/// \return the MC matching flag for the track +template +int8_t getMatchingFlagTrack(Tr const& bachTrack) +{ + auto particle = bachTrack.mcParticle(); + auto pdgCode = std::abs(particle.pdgCode()); + if (pdgCode == kPiPlus) { + return hf_decay::hf_cand_reso::PartialMatchMc::PionMatched; + } + if (pdgCode == kKPlus) { + return hf_decay::hf_cand_reso::PartialMatchMc::KaonMatched; + } + if (pdgCode == kProton) { + return hf_decay::hf_cand_reso::PartialMatchMc::ProtonMatched; + } + return 0; +} - // v0 DCA to primary vertex - v0.dcaV0ToPv = calculateDCAStraightToPV( - vtx[0], vtx[1], vtx[2], - v0.momPos[0] + v0.momNeg[0], - v0.momPos[1] + v0.momNeg[1], - v0.momPos[2] + v0.momNeg[2], - collision.posX(), collision.posY(), collision.posZ()); - if (std::abs(v0.dcaV0ToPv) > cfgV0Cuts.dcaPv.value) { - return false; - } - // v0 cosine of pointing angle - std::array const primVtx = {collision.posX(), collision.posY(), collision.posZ()}; - v0.cosPA = RecoDecay::cpa(primVtx, vtx, v0.mom); - if (v0.cosPA < cfgV0Cuts.cosPa.value) { - return false; - } - // distinguish between K0s, and Lambda hypotesys - v0.v0Type = {BIT(BachelorType::K0s) | BIT(BachelorType::Lambda) | BIT(BachelorType::AntiLambda)}; - // for lambda hypotesys define if its lambda or anti-lambda - v0.alpha = alphaAP(v0.mom, v0.momPos, v0.momNeg); - bool const matter = v0.alpha > 0; - CLRBIT(v0.v0Type, matter ? BachelorType::AntiLambda : BachelorType::Lambda); - auto massPos = matter ? o2::constants::physics::MassProton : o2::constants::physics::MassPionCharged; - auto massNeg = matter ? o2::constants::physics::MassPionCharged : o2::constants::physics::MassProton; - // mass hypotesis - v0.mLambda = RecoDecay::m(std::array{v0.momPos, v0.momNeg}, std::array{massPos, massNeg}); - v0.mK0Short = RecoDecay::m(std::array{v0.momPos, v0.momNeg}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged}); - if (std::fabs(v0.mK0Short - o2::constants::physics::MassK0) > cfgV0Cuts.deltaMassK0s.value) { - CLRBIT(v0.v0Type, BachelorType::K0s); +/// Matching of V0 candidates to MC truth +/// \param particlesMc is the table of MC particles +/// \param indexRec is the index of the MC particle associated to the reconstructed canditate +/// \param pdg is the O2DatabasePDG service +/// \return the generated invariant mass +template +float computeInvMassGen(PParticles const& particlesMc, int indexRec, o2::framework::Service const& pdg) +{ + if (indexRec < 0) { + return -1.f; + } + auto particleReso = particlesMc.iteratorAt(indexRec); + auto dau1 = particlesMc.iteratorAt(particleReso.daughtersIds().front()); + auto dau2 = particlesMc.iteratorAt(particleReso.daughtersIds().back()); + std::array, 2> pArr = {{{dau1.px(), dau1.py(), dau1.pz()}, {dau2.px(), dau2.py(), dau2.pz()}}}; + std::array mArr = {static_cast(pdg->Mass(dau1.pdgCode())), static_cast(pdg->Mass(dau2.pdgCode()))}; + return static_cast(RecoDecay::m(pArr, mArr)); +} + +/// Function for filling MC reco information of DV0 candidates in the tables +/// \tparam dType is the D meson type (Dstar, Dplus or D0) +/// \param particlesMc is the table with MC particles +/// \param candCharmBach is the D meson candidate +/// \param bachelorV0 is the V0 candidate +/// \param tracks is the table with tracks +/// \param indexHfCandCharm is the index of the charm-hadron bachelor in the reduced table +/// \param indexCandV0TrBach is the index of the v0 bachelor in the reduced table +/// \param pdg is the O2DatabasePDG service +/// \param registry is the histogram registry +/// \param rowMcRecReduced is the table to be filled +template +void fillMcRecoInfoDV0(PParticles const& particlesMc, + CCand const& candCharmBach, + BBachV0 const& bachelorV0, + Tr const& tracks, + int64_t& indexHfCandCharm, + int64_t& indexCandV0Bach, + o2::framework::Service const& pdg, + o2::framework::HistogramRegistry& registry, + Table& rowMcRecReduced) +{ + std::vector vecDaughtersReso{}; + int8_t sign{0}, nKinkedTracks{0}, origin{0}, flagCharmBach{0}, flagCharmBachInterm{0}, flagV0{0}, flagReso{0}; + int indexRec{-1}, debugMcRec{0}; + float ptGen{-1.f}, invMassGen{-1.f}; + if constexpr (DType == DType::Dstar) { + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prongPiId())); + // Check if D* is matched + flagCharmBach = candCharmBach.flagMcMatchRec(); + if (flagCharmBach != 0) { + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::DstarMatched); + origin = candCharmBach.originMcRec(); + } + // Check if D0 is matched + flagCharmBachInterm = candCharmBach.flagMcMatchRecD0(); + if (flagCharmBachInterm != 0) { + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::D0Matched); + } + // Check if V0 is matched + vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.posTrackId())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.negTrackId())); + flagV0 = getMatchingFlagV0(particlesMc, std::array{vecDaughtersReso[3], vecDaughtersReso[4]}); + if (flagV0 != 0) { + SETBIT(debugMcRec, std::abs(flagV0)); + } + // If both D* and K0s are matched, try to match resonance + if (flagCharmBach != 0 && flagV0 == hf_decay::hf_cand_reso::PartialMatchMc::K0Matched) { + std::array const pdgCodesDaughters = {+kPiPlus, -kKPlus, +kPiPlus, +kPiPlus, -kPiPlus}; + auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], vecDaughtersReso[3], vecDaughtersReso[4]}; + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarK0s) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; + break; + } } - if (std::fabs(v0.mLambda - o2::constants::physics::MassLambda0) > cfgV0Cuts.deltaMassLambda.value) { - CLRBIT(v0.v0Type, BachelorType::Lambda); - CLRBIT(v0.v0Type, BachelorType::AntiLambda); + } else if (flagCharmBachInterm != 0 && flagV0 == hf_decay::hf_cand_reso::PartialMatchMc::K0Matched) { + std::array const pdgCodesDaughters = {+kPiPlus, -kKPlus, +kPiPlus, -kPiPlus}; + auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[3], vecDaughtersReso[4]}; + // Peaking background of D0K0s <- Ds* with spurious soft pion + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarK0s) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::ResoPartlyMatched); + break; + } } - // PID - if (TESTBIT(v0.v0Type, BachelorType::K0s)) { - if ((trackPos.hasTPC() && std::fabs(trackPos.tpcNSigmaPi()) > cfgV0Cuts.nSigmaTpc.value) || - (trackNeg.hasTPC() && std::fabs(trackNeg.tpcNSigmaPi()) > cfgV0Cuts.nSigmaTpc.value)) { - CLRBIT(v0.v0Type, BachelorType::K0s); + } + // No physical channel expected in D*Lambda + if (indexRec > -1) { + auto particleReso = particlesMc.iteratorAt(indexRec); + ptGen = particleReso.pt(); + invMassGen = computeInvMassGen(particlesMc, indexRec, pdg); + } + rowMcRecReduced(indexHfCandCharm, indexCandV0Bach, + flagReso, flagCharmBach, + flagCharmBachInterm, debugMcRec, + origin, ptGen, invMassGen, + nKinkedTracks); + } else if constexpr (DType == DType::Dplus) { + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong2Id())); + // Check if D+ is matched + flagCharmBach = candCharmBach.flagMcMatchRec(); + flagCharmBachInterm = candCharmBach.flagMcDecayChanRec(); + if (flagCharmBach != 0) { + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::DplusMatched); + origin = candCharmBach.originMcRec(); + } + // Check if V0 is matched + vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.posTrackId())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.negTrackId())); + flagV0 = getMatchingFlagV0(particlesMc, std::array{vecDaughtersReso[3], vecDaughtersReso[4]}); + if (flagV0 != 0) { + SETBIT(debugMcRec, std::abs(flagV0)); + } + // If both D+ and K0s are matched, try to match resonance + if (hf_decay::hf_cand_3prong::daughtersDplusMain.contains(static_cast(std::abs(flagCharmBach))) && flagV0 == hf_decay::hf_cand_reso::PartialMatchMc::K0Matched) { + auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], vecDaughtersReso[3], vecDaughtersReso[4]}; + auto pdgCodesDplusDaughters = hf_decay::hf_cand_3prong::daughtersDplusMain.at(static_cast(std::abs(flagCharmBach))); + auto pdgCodesDaughters = std::array{pdgCodesDplusDaughters[0], pdgCodesDplusDaughters[1], pdgCodesDplusDaughters[2], +kPiPlus, -kPiPlus}; + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusK0s) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; + break; } } - if (TESTBIT(v0.v0Type, BachelorType::Lambda)) { - if ((trackPos.hasTPC() && std::fabs(trackPos.tpcNSigmaPr()) > cfgV0Cuts.nSigmaTpc.value) || - (trackPos.hasTOF() && std::fabs(trackPos.tofNSigmaPr()) > cfgV0Cuts.nSigmaTofPr.value) || - (trackNeg.hasTPC() && std::fabs(trackNeg.tpcNSigmaPi()) > cfgV0Cuts.nSigmaTpc.value)) { - CLRBIT(v0.v0Type, BachelorType::Lambda); + // Partial matching of Dsj -> D*K0s -> (D+ pi0) (K0s) with missing neutral + if (indexRec < 0) { + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarK0s) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::ResoPartlyMatched); + break; + } } } - if (TESTBIT(v0.v0Type, BachelorType::AntiLambda)) { - if ((trackPos.hasTPC() && std::fabs(trackPos.tpcNSigmaPi()) > cfgV0Cuts.nSigmaTpc.value) || - (trackNeg.hasTPC() && std::fabs(trackNeg.tpcNSigmaPr()) > cfgV0Cuts.nSigmaTpc.value) || - (trackNeg.hasTOF() && std::fabs(trackNeg.tofNSigmaPr()) > cfgV0Cuts.nSigmaTofPr.value)) { - CLRBIT(v0.v0Type, BachelorType::AntiLambda); + + } else if (hf_decay::hf_cand_3prong::daughtersDplusMain.contains(static_cast(std::abs(flagCharmBach))) && std::abs(flagV0) == hf_decay::hf_cand_reso::PartialMatchMc::LambdaMatched) { + // Peaking background of D+Lambda <- Ds* with spurious soft pion + auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], vecDaughtersReso[3], vecDaughtersReso[4]}; + auto pdgCodesDplusDaughters = hf_decay::hf_cand_3prong::daughtersDplusMain.at(static_cast(std::abs(flagCharmBach))); + auto pdgCodesDaughters = std::array{pdgCodesDplusDaughters[0], pdgCodesDplusDaughters[1], pdgCodesDplusDaughters[2], +kProton, -kPiPlus}; + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusLambda) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; + break; } } - if (v0.v0Type == 0) { - return false; + } + if (indexRec > -1) { + auto particleReso = particlesMc.iteratorAt(indexRec); + ptGen = particleReso.pt(); + invMassGen = computeInvMassGen(particlesMc, indexRec, pdg); + } + rowMcRecReduced(indexHfCandCharm, indexCandV0Bach, + flagReso, flagCharmBach, + flagCharmBachInterm, debugMcRec, + origin, ptGen, invMassGen, + nKinkedTracks); + } else if constexpr (DType == DType::D0) { + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); + // Check if D0 is matched + flagCharmBach = candCharmBach.flagMcMatchRec(); + flagCharmBachInterm = candCharmBach.flagMcDecayChanRec(); + if (flagCharmBach != 0) { + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::D0Matched); + origin = candCharmBach.originMcRec(); + } + // Check if V0 is matched + vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.posTrackId())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.negTrackId())); + flagV0 = getMatchingFlagV0(particlesMc, std::array{vecDaughtersReso[2], vecDaughtersReso[3]}); + if (flagV0 != 0) { + SETBIT(debugMcRec, std::abs(flagV0)); + } + // No physical channel expected in D0 K0s + // If both D0 and Lambda are matched, try to match resonance + if (hf_decay::hf_cand_2prong::daughtersD0Main.contains(static_cast(std::abs(flagCharmBach))) && std::abs(flagV0) == hf_decay::hf_cand_reso::PartialMatchMc::LambdaMatched) { + auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], vecDaughtersReso[3]}; + auto pdgCodesDzeroDaughters = hf_decay::hf_cand_2prong::daughtersD0Main.at(static_cast(std::abs(flagCharmBach))); + auto pdgCodesDaughters = std::array{pdgCodesDzeroDaughters[0], pdgCodesDzeroDaughters[1], +kProton, -kPiPlus}; + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Lambda) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; + break; + } } - return true; } + if (indexRec > -1) { + auto particleReso = particlesMc.iteratorAt(indexRec); + ptGen = particleReso.pt(); + invMassGen = computeInvMassGen(particlesMc, indexRec, pdg); + } + rowMcRecReduced(indexHfCandCharm, indexCandV0Bach, + flagReso, flagCharmBach, + flagCharmBachInterm, debugMcRec, + origin, ptGen, invMassGen, + nKinkedTracks); + } + registry.fill(HIST("hMCRecDebug"), debugMcRec); + if (indexRec > -1) { + registry.fill(HIST("hMCRecCounter"), flagReso); + registry.fill(HIST("hMCRecOrigin"), origin); + registry.fill(HIST("hMCRecMassGen"), invMassGen); + } + if (flagCharmBach != 0) { + registry.fill(HIST("hMCRecCharmDau"), flagCharmBach); + } +} - /// Basic selection of tracks - /// \param track is the track - /// \param dDaughtersIds are the IDs of the D meson daughter tracks - /// \param cfgV0Cuts are the cuts to be applied to the track - /// \param rejectPairsWithCommonDaughter is a flag to activate rejection of pairs sharing a daughter track - /// \return true if passes all cuts - template - bool isTrackSelected(const Tr& track, const std::array& dDaughtersIds, const Cuts& cfgSingleTrackCuts, bool rejectPairsWithCommonDaughter) - { - if (rejectPairsWithCommonDaughter && std::find(dDaughtersIds.begin(), dDaughtersIds.end(), track.globalIndex()) != dDaughtersIds.end()) { - return false; - } - switch (cfgSingleTrackCuts.setTrackSelections.value) { - case 1: - if (!track.isGlobalTrackWoDCA()) { - return false; - } - break; - case 2: - if (!track.isGlobalTrack()) { - return false; - } +// Function for filling MC reco information of D Track candidates in the tables +/// \tparam dType is the D meson type (Dstar, Dplus or D0) +/// \param particlesMc is the table with MC particles +/// \param candCharmBach is the D meson candidate +/// \param bachelorTrack is the bachelor track +/// \param tracks is the table with tracks +/// \param indexHfCandCharm is the index of the charm-hadron bachelor in the reduced table +/// \param indexCandTrBach is the index of the v0 bachelor in the reduced table +/// \param pdg is the O2DatabasePDG service +/// \param registry is the histogram registry +/// \param rowMcRecReduced is the table to be filled +template +void fillMcRecoInfoDTrack(PParticles const& particlesMc, + CCand const& candCharmBach, + BBachTr const& bachelorTrack, + Tr const& tracks, + const int64_t indexHfCandCharm, + const int64_t indexCandTrBach, + o2::framework::Service const& pdg, + o2::framework::HistogramRegistry& registry, + Table& rowMcRecReduced) +{ + std::vector vecDaughtersReso{}; + int8_t sign{0}, nKinkedTracks{0}, origin{0}, flagCharmBach{0}, flagCharmBachInterm{0}, flagTrack{0}, flagReso{0}; + int indexRec{-1}; + uint16_t debugMcRec{0}; + float ptGen{-1.f}, invMassGen{-1.f}; + if constexpr (DType == DType::Dstar) { + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prongPiId())); + // Check if D* is matched + flagCharmBach = candCharmBach.flagMcMatchRec(); + if (flagCharmBach != 0) { + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::DstarMatched); + origin = candCharmBach.originMcRec(); + } + // Check if D0 is matched + flagCharmBachInterm = candCharmBach.flagMcMatchRecD0(); + if (flagCharmBachInterm != 0) { + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::D0Matched); + } + // Check if Track is matched + flagTrack = getMatchingFlagTrack(bachelorTrack); + if (flagTrack != 0) { + SETBIT(debugMcRec, flagTrack); + } + // If both D* and Track are matched, try to match resonance + if (flagCharmBach != 0 && flagTrack == hf_decay::hf_cand_reso::PartialMatchMc::PionMatched) { + auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], bachelorTrack}; + auto pdgCodesDaughters = std::array{+kPiPlus, -kKPlus, +kPiPlus, -kPiPlus}; + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarPi) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; break; - case 3: - if (!track.isQualityTrackITS()) { - return false; - } + } + } + } + // No channels in D*K+ or D*Pr + if (indexRec > -1) { + auto particleReso = particlesMc.iteratorAt(indexRec); + ptGen = particleReso.pt(); + invMassGen = computeInvMassGen(particlesMc, indexRec, pdg); + } + rowMcRecReduced(indexHfCandCharm, indexCandTrBach, + flagReso, flagCharmBach, + flagCharmBachInterm, debugMcRec, + origin, ptGen, invMassGen, + nKinkedTracks); + } else if constexpr (DType == DType::Dplus) { + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong2Id())); + // Check if D+ is matched + flagCharmBach = candCharmBach.flagMcMatchRec(); + flagCharmBachInterm = candCharmBach.flagMcDecayChanRec(); + if (flagCharmBach != 0) { + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::DplusMatched); + origin = candCharmBach.originMcRec(); + } + // Check if Track is matched + flagTrack = getMatchingFlagTrack(bachelorTrack); + if (flagTrack != 0) { + SETBIT(debugMcRec, flagTrack); + } + // If both D+ and Track are matched, try to match resonance + if (hf_decay::hf_cand_3prong::daughtersDplusMain.contains(static_cast(std::abs(flagCharmBach))) && flagTrack == hf_decay::hf_cand_reso::PartialMatchMc::PionMatched) { + auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], bachelorTrack}; + auto pdgCodesDplusDaughters = hf_decay::hf_cand_3prong::daughtersDplusMain.at(static_cast(std::abs(flagCharmBach))); + auto pdgCodesDaughters = std::array{pdgCodesDplusDaughters[0], pdgCodesDplusDaughters[1], pdgCodesDplusDaughters[2], -kPiPlus}; + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusPi) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; break; + } } - if (track.pt() < cfgSingleTrackCuts.minPt.value) { - return false; + // Partial matching of Dj -> D*Pi -> (D+ pi0) (pi) with missing neutral + if (indexRec < 0) { + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarPi) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::ResoPartlyMatched); + break; + } + } } - if (std::abs(track.eta()) > cfgSingleTrackCuts.maxEta.value) { - return false; + } + // No channels in D+K+ or D+Pr + if (indexRec > -1) { + auto particleReso = particlesMc.iteratorAt(indexRec); + ptGen = particleReso.pt(); + invMassGen = computeInvMassGen(particlesMc, indexRec, pdg); + } + rowMcRecReduced(indexHfCandCharm, indexCandTrBach, + flagReso, flagCharmBach, + flagCharmBachInterm, debugMcRec, + origin, ptGen, invMassGen, + nKinkedTracks); + } else if constexpr (DType == DType::D0) { + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); + vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); + // Check if D0 is matched + flagCharmBach = candCharmBach.flagMcMatchRec(); + flagCharmBachInterm = candCharmBach.flagMcDecayChanRec(); + if (flagCharmBach != 0) { + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::D0Matched); + origin = candCharmBach.originMcRec(); + } + flagTrack = getMatchingFlagTrack(bachelorTrack); + if (flagTrack != 0) { + SETBIT(debugMcRec, flagTrack); + } + if (hf_decay::hf_cand_2prong::daughtersD0Main.contains(static_cast(std::abs(flagCharmBach))) && flagTrack == hf_decay::hf_cand_reso::PartialMatchMc::PionMatched) { + auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], bachelorTrack}; + auto pdgCodesDzeroDaughters = hf_decay::hf_cand_2prong::daughtersD0Main.at(static_cast(std::abs(flagCharmBach))); + auto pdgCodesDaughters = std::array{pdgCodesDzeroDaughters[0], pdgCodesDzeroDaughters[1], +kPiPlus}; + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Pi) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; + break; + } } - if (!track.hasTPC()) { - return false; + // Partial matching of Dj -> D*Pi -> (D0 pi) (pi) with missing pion + if (indexRec < 0) { + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarPi) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); + if (indexRec > -1) { + flagReso = sign * decayChannelFlag; + SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::ResoPartlyMatched); + break; + } + } } - bool const isPion = std::abs(track.tpcNSigmaPi()) < cfgSingleTrackCuts.maxNsigmaTpcPi.value; - bool const isKaon = std::abs(track.tpcNSigmaKa()) < cfgSingleTrackCuts.maxNsigmaTpcKa.value; - bool const isProton = std::abs(track.tpcNSigmaPr()) < cfgSingleTrackCuts.maxNsigmaTpcPr.value; - return (isPion || isKaon || isProton); // we keep the track if is it compatible with at least one of the PID hypotheses selected - } - - /// Matching of V0 candidates to MC truth - /// \param particlesMc is the table of MC particles - /// \param arrDaughtersV0 is the array of V0 daughter tracks - /// \return the MC matching flag for the V0 - template - int8_t getMatchingFlagV0(PParticles const& particlesMc, const std::array& arrDaughtersV0) - { - int8_t signV0{0}; - int indexRec{-1}; - int flagV0{0}; - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersV0, kK0, std::array{+kPiPlus, -kPiPlus}, true, &signV0, 2); - if (indexRec > -1) { - flagV0 = hf_decay::hf_cand_reso::PartialMatchMc::K0Matched; - } else { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersV0, kLambda0, std::array{+kProton, -kPiPlus}, true, &signV0, 2); + } else if (hf_decay::hf_cand_2prong::daughtersD0Main.contains(static_cast(std::abs(flagCharmBach))) && flagTrack == hf_decay::hf_cand_reso::PartialMatchMc::KaonMatched) { + auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], bachelorTrack}; + auto pdgCodesDzeroDaughters = hf_decay::hf_cand_2prong::daughtersD0Main.at(static_cast(std::abs(flagCharmBach))); + auto pdgCodesDaughters = std::array{pdgCodesDzeroDaughters[0], pdgCodesDzeroDaughters[1], +kKPlus}; + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Kplus) { + indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); if (indexRec > -1) { - flagV0 = signV0 * hf_decay::hf_cand_reso::PartialMatchMc::LambdaMatched; + flagReso = sign * decayChannelFlag; + break; } } - return flagV0; // Placeholder, should return the actual flag based on matching logic } + if (indexRec > -1) { + auto particleReso = particlesMc.iteratorAt(indexRec); + ptGen = particleReso.pt(); + invMassGen = computeInvMassGen(particlesMc, indexRec, pdg); + } + rowMcRecReduced(indexHfCandCharm, indexCandTrBach, + flagReso, flagCharmBach, + flagCharmBachInterm, debugMcRec, + origin, ptGen, invMassGen, + nKinkedTracks); + } + registry.fill(HIST("hMCRecDebug"), debugMcRec); + if (indexRec > -1) { + registry.fill(HIST("hMCRecCounter"), flagReso); + registry.fill(HIST("hMCRecOrigin"), origin); + registry.fill(HIST("hMCRecMassGen"), invMassGen); + } + if (flagCharmBach != 0) { + registry.fill(HIST("hMCRecCharmDau"), flagCharmBach); + } +} // fillMcRecoInfoDTrack - /// Matching of V0 candidates to MC truth - /// \param bachTrack is the track - /// \return the MC matching flag for the track - template - int8_t getMatchingFlagTrack(Tr const& bachTrack) - { - auto particle = bachTrack.mcParticle(); - auto pdgCode = std::abs(particle.pdgCode()); - if (pdgCode == kPiPlus) { - return hf_decay::hf_cand_reso::PartialMatchMc::PionMatched; +// Function for derived data creation +/// \tparam dType is the D meson type (Dstar, Dplus or D0) +/// \param collision is the current collision +/// \param candsD are the D meson candidates in the current collision +/// \param bachelorV0s are the V0 candidates in the current collision +/// \param bachelorTrks are the track ids in the current collision +/// \param tracks is the track table +/// \param tracksIU is the trackIU table +/// \param particlesMc is the MC particle table +/// \param hfRejMap is the event rejection map from the HF event selection util +/// \param pdg is the O2DatabasePDG service +/// \param registry is the histogram registry +/// \param matCorr is the material correction type to be used in the track propagation +/// \param fitter is the DCAFitter object +/// \param rejectPairsWithCommonDaughter is a flag to activate rejection of pairs sharing a daughter track +/// \param rowCollisionReduced is the collision reduced table to be filled +/// \param rowCandDmesReduced is the D-meson reduced table to be filled +/// \param rowCandV0Reduced is the V0 reduced table to be filled +/// \param rowTrkReduced is the track reduced table to be filled +/// \param rowMcRecV0Reduced is the MC reco D-V0 reduced table to be filled +/// \param rowMcRecTrkReduced is the MC reco D-track reduced table to be filled +/// \param rowCandDmesMlReduced is the ML reduced table to be filled +template +void runDataCreation(Coll const& collision, + CCands const& candsD, + BBachV0s const& bachelorV0s, + BBachTracks const& bachelorTrks, + Tr const& tracks, + TrIU const& tracksIU, + PParticles const& particlesMc, + o2::hf_evsel::HfCollisionRejectionMask hfRejMap, + const float bz, + o2::framework::Service const& pdg, + o2::framework::HistogramRegistry& registry, + o2::base::Propagator::MatCorrType const& matCorr, + o2::vertexing::DCAFitterN<2>& fitter, + DmesCuts const& cfgDmesCuts, + TrkCuts const& cfgSingleTrackCuts, + V0Cuts const& cfgV0Cuts, + QaConfig const& cfgQaPlots, + bool rejectPairsWithCommonDaughter, + TableCollRed& rowCollisionReduced, + TableCandDRed& rowCandDmesReduced, + TableCandV0Red& rowCandV0Reduced, + TableTrkRed& rowTrkReduced, + TableMcRecV0Red& rowMcRecV0Reduced, + TableMcRecTrkRed& rowMcRecTrkReduced, + TableCandDMlRed& rowCandDmesMlReduced) +{ + int const indexHfReducedCollision = rowCollisionReduced.lastIndex() + 1; + // std::map where the key is the V0.globalIndex() and + // the value is the V0 index in the table of the selected v0s + std::map selectedV0s; + std::map selectedTracks; + bool fillHfReducedCollision = false; + constexpr bool DoTracks = PairingType == PairingType::TrackOnly || PairingType == PairingType::V0AndTrack; + constexpr bool DoV0s = PairingType == PairingType::V0Only || PairingType == PairingType::V0AndTrack; + // loop on D candidates + for (const auto& candD : candsD) { + // initialize variables depending on D meson type + bool fillHfCandD = false; + std::array secondaryVertexD{}; + std::array prongIdsD{}; + std::array bdtScores = {-1.f, -1.f, -1.f, -1.f, -1.f, -1.f}; + std::vector> charmHadDauTracks{}; + varContainer varUtils; + varUtils.ptD = candD.pt(); + if constexpr (DType == DType::Dstar) { + varUtils.signD = candD.signSoftPi(); + if (varUtils.signD > 0) { + varUtils.invMassD = candD.invMassDstar(); + varUtils.invMassD0 = candD.invMassD0(); + } else { + varUtils.invMassD = candD.invMassAntiDstar(); + varUtils.invMassD0 = candD.invMassD0Bar(); } - if (pdgCode == kKPlus) { - return hf_decay::hf_cand_reso::PartialMatchMc::KaonMatched; + secondaryVertexD[0] = candD.xSecondaryVertexD0(); + secondaryVertexD[1] = candD.ySecondaryVertexD0(); + secondaryVertexD[2] = candD.zSecondaryVertexD0(); + prongIdsD[0] = candD.prong0Id(); + prongIdsD[1] = candD.prong1Id(); + prongIdsD[2] = candD.prongPiId(); + varUtils.pVectorProng0 = candD.pVectorProng0(); + varUtils.pVectorProng1 = candD.pVectorProng1(); + varUtils.pVectorProng2 = candD.pVecSoftPi(); + charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong0Id())); + charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong1Id())); + if constexpr (WithMl) { + std::copy(candD.mlProbDstarToD0Pi().begin(), candD.mlProbDstarToD0Pi().end(), bdtScores.begin()); } - if (pdgCode == kProton) { - return hf_decay::hf_cand_reso::PartialMatchMc::ProtonMatched; + registry.fill(HIST("hMassVsPtDstarAll"), varUtils.ptD, varUtils.invMassD - varUtils.invMassD0); + } else if constexpr (DType == DType::Dplus) { + auto prong0 = tracksIU.rawIteratorAt(candD.prong0Id()); + varUtils.invMassD = HfHelper::invMassDplusToPiKPi(candD); + secondaryVertexD[0] = candD.xSecondaryVertex(); + secondaryVertexD[1] = candD.ySecondaryVertex(); + secondaryVertexD[2] = candD.zSecondaryVertex(); + prongIdsD[0] = candD.prong0Id(); + prongIdsD[1] = candD.prong1Id(); + prongIdsD[2] = candD.prong2Id(); + varUtils.signD = prong0.sign(); + varUtils.pVectorProng0 = candD.pVectorProng0(); + varUtils.pVectorProng1 = candD.pVectorProng1(); + varUtils.pVectorProng2 = candD.pVectorProng2(); + charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong0Id())); + charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong1Id())); + charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong2Id())); + if constexpr (WithMl) { + std::copy(candD.mlProbDplusToPiKPi().begin(), candD.mlProbDplusToPiKPi().end(), bdtScores.begin()); } - return 0; - } + registry.fill(HIST("hMassVsPtDplusAll"), varUtils.ptD, varUtils.invMassD); + } else if constexpr (DType == DType::D0) { + varUtils.invMassD0 = HfHelper::invMassD0ToPiK(candD); + varUtils.invMassD0Bar = HfHelper::invMassD0barToKPi(candD); + secondaryVertexD[0] = candD.xSecondaryVertex(); + secondaryVertexD[1] = candD.ySecondaryVertex(); + secondaryVertexD[2] = candD.zSecondaryVertex(); + prongIdsD[0] = candD.prong0Id(); + prongIdsD[1] = candD.prong1Id(); + prongIdsD[2] = -1; // D0 does not have a third prong + charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong0Id())); + charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong1Id())); + varUtils.pVectorProng0 = candD.pVectorProng0(); + varUtils.pVectorProng1 = candD.pVectorProng1(); + varUtils.pVectorProng2 = {0.f, 0.f, 0.f}; // D0 does not have a third prong + if constexpr (WithMl) { + std::copy(candD.mlProbD0().begin(), candD.mlProbD0().end(), bdtScores.begin()); + std::copy(candD.mlProbD0bar().begin(), candD.mlProbD0bar().end(), bdtScores.begin() + 3); + } + if (candD.isSelD0() >= cfgDmesCuts.selectionFlagD0.value) { + registry.fill(HIST("hMassVsPtD0All"), varUtils.ptD, varUtils.invMassD0); + } + if (candD.isSelD0bar() >= cfgDmesCuts.selectionFlagD0Bar.value) { + registry.fill(HIST("hMassVsPtD0BarAll"), varUtils.ptD, varUtils.invMassD0Bar); + } + } // end of dType switch - /// Matching of V0 candidates to MC truth - /// \param particlesMc is the table of MC particles - /// \param indexRec is the index of the MC particle associated to the reconstructed canditate - /// \param pdg is the O2DatabasePDG service - /// \return the generated invariant mass - template - float computeInvMassGen(PParticles const& particlesMc, int indexRec, o2::framework::Service const& pdg) - { - if (indexRec < 0) { - return -1.f; + // Get single track variables + float chi2TpcDauMax = -1.f; + int nItsClsDauMin = 8, nTpcCrossRowsDauMin = 200; + float chi2TpcSoftPi = -1.f; + int nItsClsSoftPi = 8, nTpcCrossRowsSoftPi = 200; + for (const auto& charmHadTrack : charmHadDauTracks) { + if (charmHadTrack.itsNCls() < nItsClsDauMin) { + nItsClsDauMin = charmHadTrack.itsNCls(); + } + if (charmHadTrack.tpcNClsCrossedRows() < nTpcCrossRowsDauMin) { + nTpcCrossRowsDauMin = charmHadTrack.tpcNClsCrossedRows(); + } + if (charmHadTrack.tpcChi2NCl() > chi2TpcDauMax) { + chi2TpcDauMax = charmHadTrack.tpcChi2NCl(); } - auto particleReso = particlesMc.iteratorAt(indexRec); - auto dau1 = particlesMc.iteratorAt(particleReso.daughtersIds().front()); - auto dau2 = particlesMc.iteratorAt(particleReso.daughtersIds().back()); - std::array, 2> pArr = {{{dau1.px(), dau1.py(), dau1.pz()}, {dau2.px(), dau2.py(), dau2.pz()}}}; - std::array mArr = {static_cast(pdg->Mass(dau1.pdgCode())), static_cast(pdg->Mass(dau2.pdgCode()))}; - return static_cast(RecoDecay::m(pArr, mArr)); } - - /// Function for filling MC reco information of DV0 candidates in the tables - /// \tparam dType is the D meson type (Dstar, Dplus or D0) - /// \param particlesMc is the table with MC particles - /// \param candCharmBach is the D meson candidate - /// \param bachelorV0 is the V0 candidate - /// \param tracks is the table with tracks - /// \param indexHfCandCharm is the index of the charm-hadron bachelor in the reduced table - /// \param indexCandV0TrBach is the index of the v0 bachelor in the reduced table - /// \param pdg is the O2DatabasePDG service - /// \param registry is the histogram registry - /// \param rowMcRecReduced is the table to be filled - template - void fillMcRecoInfoDV0(PParticles const& particlesMc, - CCand const& candCharmBach, - BBachV0 const& bachelorV0, - Tr const& tracks, - int64_t& indexHfCandCharm, - int64_t& indexCandV0Bach, - o2::framework::Service const& pdg, - o2::framework::HistogramRegistry& registry, - Table& rowMcRecReduced) - { - std::vector vecDaughtersReso{}; - int8_t sign{0}, nKinkedTracks{0}, origin{0}, flagCharmBach{0}, flagCharmBachInterm{0}, flagV0{0}, flagReso{0}; - int indexRec{-1}, debugMcRec{0}; - float ptGen{-1.f}, invMassGen{-1.f}; - if constexpr (DType == DType::Dstar) { - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prongPiId())); - // Check if D* is matched - flagCharmBach = candCharmBach.flagMcMatchRec(); - if (flagCharmBach != 0) { - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::DstarMatched); - origin = candCharmBach.originMcRec(); + if constexpr (DType == DType::Dstar) { + auto softPi = tracksIU.rawIteratorAt(candD.prongPiId()); + nItsClsSoftPi = softPi.itsNCls(); + nTpcCrossRowsSoftPi = softPi.tpcNClsCrossedRows(); + chi2TpcSoftPi = softPi.tpcChi2NCl(); + charmHadDauTracks.push_back(softPi); + } + // Loop on the bachelor V0s + if constexpr (DoV0s) { + for (const auto& v0 : bachelorV0s) { + auto trackPos = tracksIU.rawIteratorAt(v0.posTrackId()); + auto trackNeg = tracksIU.rawIteratorAt(v0.negTrackId()); + // Apply selsection + auto v0DauTracks = std::array{trackPos, trackNeg}; + candidateV0 candV0; + if (!buildAndSelectV0(collision, prongIdsD, v0DauTracks, cfgV0Cuts, fitter, candV0, rejectPairsWithCommonDaughter)) { + continue; } - // Check if D0 is matched - flagCharmBachInterm = candCharmBach.flagMcMatchRecD0(); - if (flagCharmBachInterm != 0) { - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::D0Matched); + // Get single track variables + float chi2TpcDauV0Max = -1.f; + int nItsClsDauV0Min = 8, nTpcCrossRowsDauV0Min = 200; + for (const auto& v0Track : v0DauTracks) { + if (v0Track.itsNCls() < nItsClsDauV0Min) { + nItsClsDauV0Min = v0Track.itsNCls(); + } + if (v0Track.tpcNClsCrossedRows() < nTpcCrossRowsDauV0Min) { + nTpcCrossRowsDauV0Min = v0Track.tpcNClsCrossedRows(); + } + if (v0Track.tpcChi2NCl() > chi2TpcDauV0Max) { + chi2TpcDauV0Max = v0Track.tpcChi2NCl(); + } } - // Check if V0 is matched - vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.posTrackId())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.negTrackId())); - flagV0 = getMatchingFlagV0(particlesMc, std::array{vecDaughtersReso[3], vecDaughtersReso[4]}); - if (flagV0 != 0) { - SETBIT(debugMcRec, std::abs(flagV0)); + // propagate V0 to primary vertex (if enabled) + if (cfgV0Cuts.propagateV0toPV.value) { + std::array const pVecV0Orig = {candV0.mom[0], candV0.mom[1], candV0.mom[2]}; + std::array dcaInfo{}; + auto trackParK0 = o2::track::TrackPar(candV0.pos, pVecV0Orig, 0, true); + trackParK0.setPID(o2::track::PID::K0); + trackParK0.setAbsCharge(0); + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParK0, 2.f, matCorr, &dcaInfo); + getPxPyPz(trackParK0, candV0.mom); } - // If both D* and K0s are matched, try to match resonance - if (flagCharmBach != 0 && flagV0 == hf_decay::hf_cand_reso::PartialMatchMc::K0Matched) { - std::array const pdgCodesDaughters = {+kPiPlus, -kKPlus, +kPiPlus, +kPiPlus, -kPiPlus}; - auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], vecDaughtersReso[3], vecDaughtersReso[4]}; - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarK0s) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; - break; + // compute resonance invariant mass and filling of QA histograms + if (TESTBIT(candV0.v0Type, BachelorType::K0s)) { + registry.fill(HIST("hMassVsPtK0s"), candV0.pT, candV0.mK0Short); + if constexpr (DType == DType::Dstar) { + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom)); + if (varUtils.signD > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassK0}); + } else { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassK0}); } - } - } else if (flagCharmBachInterm != 0 && flagV0 == hf_decay::hf_cand_reso::PartialMatchMc::K0Matched) { - std::array const pdgCodesDaughters = {+kPiPlus, -kKPlus, +kPiPlus, -kPiPlus}; - auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[3], vecDaughtersReso[4]}; - // Peaking background of D0K0s <- Ds* with spurious soft pion - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarK0s) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::ResoPartlyMatched); - break; + if (!cfgQaPlots.applyCutsForQaHistograms.value || + (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin.value && + varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax.value && + candV0.mK0Short > cfgQaPlots.cutMassK0sMin.value && + candV0.mK0Short < cfgQaPlots.cutMassK0sMax.value)) { + registry.fill(HIST("hMassDstarK0s"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); } - } + } else if constexpr (DType == DType::Dplus) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassK0}); + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + (varUtils.invMassD > cfgQaPlots.cutMassDMin.value && + varUtils.invMassD < cfgQaPlots.cutMassDMax.value && + candV0.mK0Short > cfgQaPlots.cutMassK0sMin.value && + candV0.mK0Short < cfgQaPlots.cutMassK0sMax.value)) { + registry.fill(HIST("hMassDplusK0s"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } // end of dType switch + } // matched with K0s + bool const isLambda = TESTBIT(candV0.v0Type, BachelorType::Lambda); + bool const isAntiLambda = TESTBIT(candV0.v0Type, BachelorType::AntiLambda); + if (isLambda || isAntiLambda) { + registry.fill(HIST("hMassVsPtLambda"), candV0.pT, candV0.mLambda); + if constexpr (DType == DType::Dstar) { + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom)); + if (varUtils.signD > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassLambda}); + } else { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassLambda}); + } + if (!cfgQaPlots.applyCutsForQaHistograms.value || + (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin.value && + varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax.value && + candV0.mLambda > cfgQaPlots.cutMassLambdaMin.value && + candV0.mLambda < cfgQaPlots.cutMassLambdaMax.value)) { + registry.fill(HIST("hMassDstarLambda"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } else if constexpr (DType == DType::Dplus) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassLambda}); + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + (varUtils.invMassD > cfgQaPlots.cutMassDMin.value && + varUtils.invMassD < cfgQaPlots.cutMassDMax.value && + candV0.mLambda > cfgQaPlots.cutMassLambdaMin.value && + candV0.mLambda < cfgQaPlots.cutMassLambdaMax.value)) { + registry.fill(HIST("hMassDplusLambda"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } else if constexpr (DType == DType::D0) { + if (isLambda) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassLambda}); + } else { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassLambda}); + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, candV0.mom)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + (((varUtils.invMassD0 > cfgQaPlots.cutMassDMin.value && varUtils.invMassD0 < cfgQaPlots.cutMassDMax.value) || + (varUtils.invMassD0Bar > cfgQaPlots.cutMassDMin.value && varUtils.invMassD0Bar < cfgQaPlots.cutMassDMax.value)) && + candV0.mLambda > cfgQaPlots.cutMassLambdaMin.value && + candV0.mLambda < cfgQaPlots.cutMassLambdaMax.value)) { + if (isLambda) { + registry.fill(HIST("hMassD0Lambda"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0); + } else { + registry.fill(HIST("hMassD0Lambda"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0Bar); + } + } + } // end of dType switch + } // matched with Lambda or AntiLambda + // fill V0 table + // if information on V0 already stored, go to next V0 + if (!selectedV0s.count(v0.globalIndex())) { + rowCandV0Reduced(trackPos.globalIndex(), trackNeg.globalIndex(), + indexHfReducedCollision, + candV0.pos[0], candV0.pos[1], candV0.pos[2], + candV0.momPos[0], candV0.momPos[1], candV0.momPos[2], + candV0.momNeg[0], candV0.momNeg[1], candV0.momNeg[2], + candV0.cosPA, + candV0.dcaV0ToPv, + nItsClsDauV0Min, nTpcCrossRowsDauV0Min, chi2TpcDauV0Max, + candV0.v0Type); + selectedV0s[v0.globalIndex()] = rowCandV0Reduced.lastIndex(); } - // No physical channel expected in D*Lambda - if (indexRec > -1) { - auto particleReso = particlesMc.iteratorAt(indexRec); - ptGen = particleReso.pt(); - invMassGen = computeInvMassGen(particlesMc, indexRec, pdg); + fillHfCandD = true; + // Optional filling of MC Rec table, for now only implemented for Ds1->D*K0s and Ds2*->D+K0s + if constexpr (DoMc) { + auto indexHfCandCharm = rowCandDmesReduced.lastIndex() + 1; + fillMcRecoInfoDV0(particlesMc, candD, v0, tracksIU, indexHfCandCharm, selectedV0s[v0.globalIndex()], pdg, registry, rowMcRecV0Reduced); } - rowMcRecReduced(indexHfCandCharm, indexCandV0Bach, - flagReso, flagCharmBach, - flagCharmBachInterm, debugMcRec, - origin, ptGen, invMassGen, - nKinkedTracks); - } else if constexpr (DType == DType::Dplus) { - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong2Id())); - // Check if D+ is matched - flagCharmBach = candCharmBach.flagMcMatchRec(); - flagCharmBachInterm = candCharmBach.flagMcDecayChanRec(); - if (flagCharmBach != 0) { - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::DplusMatched); - origin = candCharmBach.originMcRec(); + } // end of loop on V0 candidates + } // end of do V0s + // Loop on the bachelor tracks + if constexpr (DoTracks) { + for (const auto& trackIndex : bachelorTrks) { + auto track = tracks.rawIteratorAt(trackIndex.trackId()); + if (!isTrackSelected(track, prongIdsD, cfgSingleTrackCuts, rejectPairsWithCommonDaughter)) { + continue; } - // Check if V0 is matched - vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.posTrackId())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.negTrackId())); - flagV0 = getMatchingFlagV0(particlesMc, std::array{vecDaughtersReso[3], vecDaughtersReso[4]}); - if (flagV0 != 0) { - SETBIT(debugMcRec, std::abs(flagV0)); + // if the track has been reassociated, re-propagate it to PV (minor difference) + auto trackParCovTrack = getTrackParCov(track); + std::array dcaTrack{track.dcaXY(), track.dcaZ()}; + std::array pVecTrack = track.pVector(); + if (track.collisionId() != collision.globalIndex()) { + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParCovTrack, 2.f, matCorr, &dcaTrack); + getPxPyPz(trackParCovTrack, pVecTrack); } - // If both D+ and K0s are matched, try to match resonance - if (hf_decay::hf_cand_3prong::daughtersDplusMain.contains(static_cast(std::abs(flagCharmBach))) && flagV0 == hf_decay::hf_cand_reso::PartialMatchMc::K0Matched) { - auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], vecDaughtersReso[3], vecDaughtersReso[4]}; - auto pdgCodesDplusDaughters = hf_decay::hf_cand_3prong::daughtersDplusMain.at(static_cast(std::abs(flagCharmBach))); - auto pdgCodesDaughters = std::array{pdgCodesDplusDaughters[0], pdgCodesDplusDaughters[1], pdgCodesDplusDaughters[2], +kPiPlus, -kPiPlus}; - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusK0s) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; - break; + registry.fill(HIST("hdEdxVsP"), track.p(), track.tpcSignal()); + // compute invariant mass and filling of QA histograms + if constexpr (DType == DType::Dstar) { + // D* pi + if (std::abs(track.tpcNSigmaPi()) < cfgSingleTrackCuts.maxNsigmaTpcPi.value) { + if (varUtils.signD > 0 && track.sign() < 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged}); + } else if (varUtils.signD < 0 && track.sign() > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged}); + } else { + varUtils.invMassReso = -1.f; // invalid case + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin.value && + varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax.value)) { + registry.fill(HIST("hMassDstarPi"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); } } - // Partial matching of Dsj -> D*K0s -> (D+ pi0) (K0s) with missing neutral - if (indexRec < 0) { - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarK0s) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::ResoPartlyMatched); - break; + if (std::abs(track.tpcNSigmaKa()) < cfgSingleTrackCuts.maxNsigmaTpcKa.value) { + if (varUtils.signD > 0 && track.sign() < 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus}); + } else if (varUtils.signD < 0 && track.sign() > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus}); + } else { + varUtils.invMassReso = -1.f; // invalid case + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin.value && + varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax.value)) { + registry.fill(HIST("hMassDstarK"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } + // D* p + if (std::abs(track.tpcNSigmaPr()) < cfgSingleTrackCuts.maxNsigmaTpcPr.value) { + if (varUtils.signD > 0 && track.sign() > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton}); + } else if (varUtils.signD < 0 && track.sign() < 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton}); + } else { + varUtils.invMassReso = -1.f; // invalid case + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin.value && + varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax.value)) { + registry.fill(HIST("hMassDstarProton"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } + } else if constexpr (DType == DType::Dplus) { + // D+ pi + if (std::abs(track.tpcNSigmaPi()) < cfgSingleTrackCuts.maxNsigmaTpcPi.value) { + if (varUtils.signD * track.sign() < 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged}); + } else { + varUtils.invMassReso = -1.f; // invalid case + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + (varUtils.invMassD > cfgQaPlots.cutMassDMin.value && + varUtils.invMassD < cfgQaPlots.cutMassDMax.value)) { + registry.fill(HIST("hMassDplusPi"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } + // D+ K + if (std::abs(track.tpcNSigmaKa()) < cfgSingleTrackCuts.maxNsigmaTpcKa.value) { + if (varUtils.signD * track.sign() < 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus}); + } else { + varUtils.invMassReso = -1.f; // invalid case + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + (varUtils.invMassD > cfgQaPlots.cutMassDMin.value && + varUtils.invMassD < cfgQaPlots.cutMassDMax.value)) { + registry.fill(HIST("hMassDplusK"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } + // D+ pr + if (std::abs(track.tpcNSigmaPr()) < cfgSingleTrackCuts.maxNsigmaTpcPr.value) { + if (varUtils.signD * track.sign() < 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton}); + } else { + varUtils.invMassReso = -1.f; // invalid case + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + (varUtils.invMassD > cfgQaPlots.cutMassDMin.value && + varUtils.invMassD < cfgQaPlots.cutMassDMax.value)) { + registry.fill(HIST("hMassDplusProton"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } + } else if constexpr (DType == DType::D0) { + // D0 pi + if (std::abs(track.tpcNSigmaPi()) < cfgSingleTrackCuts.maxNsigmaTpcPi.value) { + if (track.sign() > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged}); + } else { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged}); + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + ((varUtils.invMassD0 > cfgQaPlots.cutMassDMin.value && + varUtils.invMassD0 < cfgQaPlots.cutMassDMax.value) || + (varUtils.invMassD0Bar > cfgQaPlots.cutMassDMin.value && + varUtils.invMassD0Bar < cfgQaPlots.cutMassDMax.value))) { + if (track.sign() > 0) { + registry.fill(HIST("hMassD0Pi"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0); + } else { + registry.fill(HIST("hMassD0Pi"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0Bar); } } } - - } else if (hf_decay::hf_cand_3prong::daughtersDplusMain.contains(static_cast(std::abs(flagCharmBach))) && std::abs(flagV0) == hf_decay::hf_cand_reso::PartialMatchMc::LambdaMatched) { - // Peaking background of D+Lambda <- Ds* with spurious soft pion - auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], vecDaughtersReso[3], vecDaughtersReso[4]}; - auto pdgCodesDplusDaughters = hf_decay::hf_cand_3prong::daughtersDplusMain.at(static_cast(std::abs(flagCharmBach))); - auto pdgCodesDaughters = std::array{pdgCodesDplusDaughters[0], pdgCodesDplusDaughters[1], pdgCodesDplusDaughters[2], +kProton, -kPiPlus}; - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusLambda) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; - break; + // D0 K + if (std::abs(track.tpcNSigmaKa()) < cfgSingleTrackCuts.maxNsigmaTpcKa.value) { + if (track.sign() > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassKPlus}); + } else { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassKPlus}); + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + ((varUtils.invMassD0 > cfgQaPlots.cutMassDMin.value && + varUtils.invMassD0 < cfgQaPlots.cutMassDMax.value) || + (varUtils.invMassD0Bar > cfgQaPlots.cutMassDMin.value && + varUtils.invMassD0Bar < cfgQaPlots.cutMassDMax.value))) { + if (track.sign() > 0) { + registry.fill(HIST("hMassD0K"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0); + } else { + registry.fill(HIST("hMassD0K"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0Bar); + } + } + } + // D0 p + if (std::abs(track.tpcNSigmaPr()) < cfgSingleTrackCuts.maxNsigmaTpcPr.value) { + if (track.sign() > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassProton}); + } else { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassProton}); + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms.value || + ((varUtils.invMassD0 > cfgQaPlots.cutMassDMin.value && + varUtils.invMassD0 < cfgQaPlots.cutMassDMax.value) || + (varUtils.invMassD0Bar > cfgQaPlots.cutMassDMin.value && + varUtils.invMassD0Bar < cfgQaPlots.cutMassDMax.value))) { + if (track.sign() > 0) { + registry.fill(HIST("hMassD0Proton"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0); + } else { + registry.fill(HIST("hMassD0Proton"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0Bar); + } } } + } // end of DType switch + // fill track table + if (!selectedTracks.count(track.globalIndex())) { + rowTrkReduced(track.globalIndex(), + indexHfReducedCollision, + track.px(), track.py(), track.pz(), track.sign(), + track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr(), + track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr(), + track.hasTOF(), track.hasTPC(), track.itsNCls(), track.tpcNClsCrossedRows(), track.tpcChi2NCl()); + selectedTracks[track.globalIndex()] = rowTrkReduced.lastIndex(); } - if (indexRec > -1) { - auto particleReso = particlesMc.iteratorAt(indexRec); - ptGen = particleReso.pt(); - invMassGen = computeInvMassGen(particlesMc, indexRec, pdg); + fillHfCandD = true; + if constexpr (DoMc) { + auto indexHfCandCharm = rowCandDmesReduced.lastIndex() + 1; + fillMcRecoInfoDTrack(particlesMc, candD, track, tracks, indexHfCandCharm, selectedTracks[track.globalIndex()], pdg, registry, rowMcRecTrkReduced); + } + } // end of loop on bachelor tracks + } // end of do tracks + // fill D candidate table + if (fillHfCandD) { // fill candDplus table only once per D candidate, only if at least one V0 is found + if constexpr (DType == DType::Dplus) { + rowCandDmesReduced(prongIdsD[0], prongIdsD[1], prongIdsD[2], + indexHfReducedCollision, + secondaryVertexD[0], secondaryVertexD[1], secondaryVertexD[2], + candD.pxProng0(), candD.pyProng0(), candD.pzProng0(), + candD.pxProng1(), candD.pyProng1(), candD.pzProng1(), + varUtils.pVectorProng2[0], varUtils.pVectorProng2[1], varUtils.pVectorProng2[2], + nItsClsDauMin, nTpcCrossRowsDauMin, chi2TpcDauMax, varUtils.signD); + if constexpr (WithMl) { + rowCandDmesMlReduced(bdtScores[0], bdtScores[1], bdtScores[2], bdtScores[3], bdtScores[4], bdtScores[5]); } - rowMcRecReduced(indexHfCandCharm, indexCandV0Bach, - flagReso, flagCharmBach, - flagCharmBachInterm, debugMcRec, - origin, ptGen, invMassGen, - nKinkedTracks); } else if constexpr (DType == DType::D0) { - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); - // Check if D0 is matched - flagCharmBach = candCharmBach.flagMcMatchRec(); - flagCharmBachInterm = candCharmBach.flagMcDecayChanRec(); - if (flagCharmBach != 0) { - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::D0Matched); - origin = candCharmBach.originMcRec(); + uint8_t selFlagD0 = {BIT(D0Sel::SelectedD0) | BIT(D0Sel::SelectedD0Bar)}; + if (candD.isSelD0() < cfgDmesCuts.selectionFlagD0.value) { + CLRBIT(selFlagD0, D0Sel::SelectedD0); } - // Check if V0 is matched - vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.posTrackId())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.negTrackId())); - flagV0 = getMatchingFlagV0(particlesMc, std::array{vecDaughtersReso[2], vecDaughtersReso[3]}); - if (flagV0 != 0) { - SETBIT(debugMcRec, std::abs(flagV0)); + if (candD.isSelD0bar() < cfgDmesCuts.selectionFlagD0Bar.value) { + CLRBIT(selFlagD0, D0Sel::SelectedD0Bar); } - // No physical channel expected in D0 K0s - // If both D0 and Lambda are matched, try to match resonance - if (hf_decay::hf_cand_2prong::daughtersD0Main.contains(static_cast(std::abs(flagCharmBach))) && std::abs(flagV0) == hf_decay::hf_cand_reso::PartialMatchMc::LambdaMatched) { - auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], vecDaughtersReso[3]}; - auto pdgCodesDzeroDaughters = hf_decay::hf_cand_2prong::daughtersD0Main.at(static_cast(std::abs(flagCharmBach))); - auto pdgCodesDaughters = std::array{pdgCodesDzeroDaughters[0], pdgCodesDzeroDaughters[1], +kProton, -kPiPlus}; - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Lambda) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; - break; - } - } + rowCandDmesReduced(prongIdsD[0], prongIdsD[1], + indexHfReducedCollision, + secondaryVertexD[0], secondaryVertexD[1], secondaryVertexD[2], + candD.pxProng0(), candD.pyProng0(), candD.pzProng0(), + candD.pxProng1(), candD.pyProng1(), candD.pzProng1(), + nItsClsDauMin, nTpcCrossRowsDauMin, chi2TpcDauMax, + selFlagD0); + if constexpr (WithMl) { + rowCandDmesMlReduced(bdtScores[0], bdtScores[1], bdtScores[2], bdtScores[3], bdtScores[4], bdtScores[5]); } - if (indexRec > -1) { - auto particleReso = particlesMc.iteratorAt(indexRec); - ptGen = particleReso.pt(); - invMassGen = computeInvMassGen(particlesMc, indexRec, pdg); + } else if constexpr (DType == DType::Dstar) { + rowCandDmesReduced(prongIdsD[0], prongIdsD[1], prongIdsD[2], + indexHfReducedCollision, + secondaryVertexD[0], secondaryVertexD[1], secondaryVertexD[2], + candD.pxProng0(), candD.pyProng0(), candD.pzProng0(), + candD.pxProng1(), candD.pyProng1(), candD.pzProng1(), + varUtils.pVectorProng2[0], varUtils.pVectorProng2[1], varUtils.pVectorProng2[2], + nItsClsDauMin, nTpcCrossRowsDauMin, chi2TpcDauMax, + nItsClsSoftPi, nTpcCrossRowsSoftPi, chi2TpcSoftPi, + varUtils.signD); + if constexpr (WithMl) { + rowCandDmesMlReduced(bdtScores[0], bdtScores[1], bdtScores[2], bdtScores[3], bdtScores[4], bdtScores[5]); } - rowMcRecReduced(indexHfCandCharm, indexCandV0Bach, - flagReso, flagCharmBach, - flagCharmBachInterm, debugMcRec, - origin, ptGen, invMassGen, - nKinkedTracks); } - registry.fill(HIST("hMCRecDebug"), debugMcRec); - if (indexRec > -1) { - registry.fill(HIST("hMCRecCounter"), flagReso); - registry.fill(HIST("hMCRecOrigin"), origin); - registry.fill(HIST("hMCRecMassGen"), invMassGen); - } - if (flagCharmBach != 0) { - registry.fill(HIST("hMCRecCharmDau"), flagCharmBach); + fillHfReducedCollision = true; + if constexpr (DType == DType::Dstar) { + registry.fill(HIST("hMassVsPtDstarPaired"), candD.pt(), varUtils.invMassD - varUtils.invMassD0); + } else if constexpr (DType == DType::Dplus) { + registry.fill(HIST("hMassVsPtDplusPaired"), candD.pt(), varUtils.invMassD); + } else if constexpr (DType == DType::D0) { + if (candD.isSelD0() >= cfgDmesCuts.selectionFlagD0.value) { + registry.fill(HIST("hMassVsPtD0Paired"), varUtils.ptD, varUtils.invMassD0); + } + if (candD.isSelD0bar() >= cfgDmesCuts.selectionFlagD0Bar.value) { + registry.fill(HIST("hMassVsPtD0BarPaired"), varUtils.ptD, varUtils.invMassD0Bar); + } } } + } // candsD loop + registry.fill(HIST("hEvents"), 1 + Event::Processed); + if (!fillHfReducedCollision) { + registry.fill(HIST("hEvents"), 1 + Event::NoDV0Selected); + return; + } + registry.fill(HIST("hEvents"), 1 + Event::DV0Selected); + // fill collision table if it contains a DPi pair a minima + rowCollisionReduced(collision.posX(), collision.posY(), collision.posZ(), collision.numContrib(), hfRejMap, bz); +} // end of runDataCreation function - // Function for filling MC reco information of D Track candidates in the tables - /// \tparam dType is the D meson type (Dstar, Dplus or D0) - /// \param particlesMc is the table with MC particles - /// \param candCharmBach is the D meson candidate - /// \param bachelorTrack is the bachelor track - /// \param tracks is the table with tracks - /// \param indexHfCandCharm is the index of the charm-hadron bachelor in the reduced table - /// \param indexCandTrBach is the index of the v0 bachelor in the reduced table - /// \param pdg is the O2DatabasePDG service - /// \param registry is the histogram registry - /// \param rowMcRecReduced is the table to be filled - template - void fillMcRecoInfoDTrack(PParticles const& particlesMc, - CCand const& candCharmBach, - BBachTr const& bachelorTrack, - Tr const& tracks, - const int64_t indexHfCandCharm, - const int64_t indexCandTrBach, - o2::framework::Service const& pdg, - o2::framework::HistogramRegistry& registry, - Table& rowMcRecReduced) - { - std::vector vecDaughtersReso{}; - int8_t sign{0}, nKinkedTracks{0}, origin{0}, flagCharmBach{0}, flagCharmBachInterm{0}, flagTrack{0}, flagReso{0}; - int indexRec{-1}; - uint16_t debugMcRec{0}; - float ptGen{-1.f}, invMassGen{-1.f}; +// Function for derived data creation +/// \tparam dType is the D meson type (Dstar, Dplus or D0) +/// \param mcParticles is the MC particle table +/// \param collInfos is the reco collision table with MC info +/// \param mcCollisions is the MC collision table +/// \param hfEvSelMc is the HF event selection util object from MC +/// \param rejectCollisionsWithBadEvSel is the flag to not store collisions rejected by event selection +/// \param registry is the histogram registry +/// \param pdg is the O2DatabasePDG service +/// \param rowHfResoMcGenReduced is the MC gen reduced table +template +void runMcGen(McParticles const& mcParticles, + McParticlesPerMcColl const& mcParticlesPerMcCollision, + CCs const& collInfos, + CollPerMcColl const& colPerMcCollision, + McCollisions const& mcCollisions, + o2::hf_evsel::HfEventSelectionMc& hfEvSelMc, + bool rejectCollisionsWithBadEvSel, + o2::framework::HistogramRegistry& registry, + o2::framework::Service const& pdg, + TableMcGenRed& rowHfResoMcGenReduced, + BCsInfo const&) +{ + bool const doV0s = (PairingType == PairingType::V0Only || PairingType == PairingType::V0AndTrack); + bool const doTracks = (PairingType == PairingType::TrackOnly || PairingType == PairingType::V0AndTrack); + for (const auto& mcCollision : mcCollisions) { + // Slice the particles table to get the particles for the current MC collision + const auto mcParticlesPerMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, mcCollision.globalIndex()); + // Slice the collisions table to get the collision info for the current MC collision + float centrality{-1.f}; + o2::hf_evsel::HfCollisionRejectionMask rejectionMask{}; + int const nSplitColl = 0; + const auto collSlice = collInfos.sliceBy(colPerMcCollision, mcCollision.globalIndex()); + rejectionMask = hfEvSelMc.getHfMcCollisionRejectionMask(mcCollision, collSlice, centrality); + hfEvSelMc.fillHistograms(mcCollision, rejectionMask, nSplitColl); + if (rejectCollisionsWithBadEvSel && rejectionMask != 0) { + // at least one event selection not satisfied --> reject all gen particles from this collision + continue; + } + for (const auto& particle : mcParticlesPerMcColl) { + int8_t sign{0}; + int8_t flag{0}; + int8_t signD{0}; + int8_t signBach{0}; + int8_t origin{0}; + bool matchedReso{false}, matchedD{false}, matchedV0Tr{false}; + std::vector idxBhadMothers{}; if constexpr (DType == DType::Dstar) { - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prongPiId())); - // Check if D* is matched - flagCharmBach = candCharmBach.flagMcMatchRec(); - if (flagCharmBach != 0) { - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::DstarMatched); - origin = candCharmBach.originMcRec(); - } - // Check if D0 is matched - flagCharmBachInterm = candCharmBach.flagMcMatchRecD0(); - if (flagCharmBachInterm != 0) { - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::D0Matched); - } - // Check if Track is matched - flagTrack = getMatchingFlagTrack(bachelorTrack); - if (flagTrack != 0) { - SETBIT(debugMcRec, flagTrack); + if (doV0s) { + // D* K0s + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarK0s) { + matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kDStar), +kK0}, true, &sign, 1); + if (matchedReso) { + flag = sign * decayChannelFlag; + auto candV0MC = mcParticles.rawIteratorAt(particle.daughtersIds().back()); + matchedV0Tr = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candV0MC, kK0, std::array{+kPiPlus, -kPiPlus}, true, &signBach, 2); + break; + } + } } - // If both D* and Track are matched, try to match resonance - if (flagCharmBach != 0 && flagTrack == hf_decay::hf_cand_reso::PartialMatchMc::PionMatched) { - auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], bachelorTrack}; - auto pdgCodesDaughters = std::array{+kPiPlus, -kKPlus, +kPiPlus, -kPiPlus}; + if (doTracks && !matchedReso) { + // D*+ pi- for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarPi) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; + matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kDStar), -static_cast(kPiPlus)}, true, &sign, 1); + if (matchedReso) { + flag = sign * decayChannelFlag; + matchedV0Tr = true; break; } } } - // No channels in D*K+ or D*Pr - if (indexRec > -1) { - auto particleReso = particlesMc.iteratorAt(indexRec); - ptGen = particleReso.pt(); - invMassGen = computeInvMassGen(particlesMc, indexRec, pdg); + if (matchedReso && matchedV0Tr) { + auto candDstarMC = mcParticles.rawIteratorAt(particle.daughtersIds().front()); + matchedD = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candDstarMC, o2::constants::physics::Pdg::kDStar, std::array{static_cast(o2::constants::physics::Pdg::kD0), +static_cast(kPiPlus)}, true, &signD, 1); + if (matchedD) { + auto candD0MC = mcParticles.rawIteratorAt(candDstarMC.daughtersIds().front()); + matchedD = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candD0MC, o2::constants::physics::Pdg::kD0, std::array{-kKPlus, +kPiPlus}, true, &signD, 2); + } } - rowMcRecReduced(indexHfCandCharm, indexCandTrBach, - flagReso, flagCharmBach, - flagCharmBachInterm, debugMcRec, - origin, ptGen, invMassGen, - nKinkedTracks); } else if constexpr (DType == DType::Dplus) { - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong2Id())); - // Check if D+ is matched - flagCharmBach = candCharmBach.flagMcMatchRec(); - flagCharmBachInterm = candCharmBach.flagMcDecayChanRec(); - if (flagCharmBach != 0) { - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::DplusMatched); - origin = candCharmBach.originMcRec(); - } - // Check if Track is matched - flagTrack = getMatchingFlagTrack(bachelorTrack); - if (flagTrack != 0) { - SETBIT(debugMcRec, flagTrack); - } - // If both D+ and Track are matched, try to match resonance - if (hf_decay::hf_cand_3prong::daughtersDplusMain.contains(static_cast(std::abs(flagCharmBach))) && flagTrack == hf_decay::hf_cand_reso::PartialMatchMc::PionMatched) { - auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], bachelorTrack}; - auto pdgCodesDplusDaughters = hf_decay::hf_cand_3prong::daughtersDplusMain.at(static_cast(std::abs(flagCharmBach))); - auto pdgCodesDaughters = std::array{pdgCodesDplusDaughters[0], pdgCodesDplusDaughters[1], pdgCodesDplusDaughters[2], -kPiPlus}; - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusPi) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; + if (doV0s) { + // D+ K0s + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusK0s) { + matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kDPlus), +kK0}, true, &sign, 1); + if (matchedReso) { + flag = sign * decayChannelFlag; + auto candV0MC = mcParticles.rawIteratorAt(particle.daughtersIds().back()); + matchedV0Tr = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candV0MC, kK0, std::array{+kPiPlus, -kPiPlus}, true, &signBach, 2); break; } } - // Partial matching of Dj -> D*Pi -> (D+ pi0) (pi) with missing neutral - if (indexRec < 0) { - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarPi) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::ResoPartlyMatched); + if (!matchedReso) { + // D+ lambda + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusLambda) { + matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kDPlus), +kLambda0}, true, &sign, 1); + if (matchedReso) { + flag = sign * decayChannelFlag; + auto candV0MC = mcParticles.rawIteratorAt(particle.daughtersIds().back()); + matchedV0Tr = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candV0MC, kLambda0, std::array{+kProton, -kPiPlus}, true, &signBach, 1); break; } } } } - // No channels in D+K+ or D+Pr - if (indexRec > -1) { - auto particleReso = particlesMc.iteratorAt(indexRec); - ptGen = particleReso.pt(); - invMassGen = computeInvMassGen(particlesMc, indexRec, pdg); + if (doTracks && !matchedReso) { + // D+ pi- + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusPi) { + matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kDPlus), -static_cast(kPiPlus)}, true, &sign, 1); + if (matchedReso) { + flag = sign * decayChannelFlag; + matchedV0Tr = true; + break; + } + } } - rowMcRecReduced(indexHfCandCharm, indexCandTrBach, - flagReso, flagCharmBach, - flagCharmBachInterm, debugMcRec, - origin, ptGen, invMassGen, - nKinkedTracks); - } else if constexpr (DType == DType::D0) { - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); - vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); - // Check if D0 is matched - flagCharmBach = candCharmBach.flagMcMatchRec(); - flagCharmBachInterm = candCharmBach.flagMcDecayChanRec(); - if (flagCharmBach != 0) { - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::D0Matched); - origin = candCharmBach.originMcRec(); + if (matchedReso && matchedV0Tr) { + auto candDplusMC = mcParticles.rawIteratorAt(particle.daughtersIds().front()); + matchedD = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candDplusMC, o2::constants::physics::Pdg::kDPlus, std::array{+kPiPlus, -kKPlus, +kPiPlus}, true, &signD, 2); } - flagTrack = getMatchingFlagTrack(bachelorTrack); - if (flagTrack != 0) { - SETBIT(debugMcRec, flagTrack); + } else if constexpr (DType == DType::D0) { + if (doV0s) { + // D0 Lambda + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Lambda) { + matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kD0), +kLambda0}, true, &sign, 1); + if (matchedReso) { + flag = sign * decayChannelFlag; + auto candV0MC = mcParticles.rawIteratorAt(particle.daughtersIds().back()); + matchedV0Tr = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candV0MC, kLambda0, std::array{+kProton, -kPiPlus}, true, &signBach, 1); + break; + } + } } - if (hf_decay::hf_cand_2prong::daughtersD0Main.contains(static_cast(std::abs(flagCharmBach))) && flagTrack == hf_decay::hf_cand_reso::PartialMatchMc::PionMatched) { - auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], bachelorTrack}; - auto pdgCodesDzeroDaughters = hf_decay::hf_cand_2prong::daughtersD0Main.at(static_cast(std::abs(flagCharmBach))); - auto pdgCodesDaughters = std::array{pdgCodesDzeroDaughters[0], pdgCodesDzeroDaughters[1], +kPiPlus}; + if (doTracks && !matchedReso) { + // D0 pi+ for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Pi) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; + matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kD0), +static_cast(kPiPlus)}, true, &sign, 1); + if (matchedReso) { + flag = sign * decayChannelFlag; + matchedV0Tr = true; break; } } - // Partial matching of Dj -> D*Pi -> (D0 pi) (pi) with missing pion - if (indexRec < 0) { - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarPi) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; - SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::ResoPartlyMatched); + // D0 K+ + if (!matchedReso) { + for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Kplus) { + matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kD0), +static_cast(kKPlus)}, true, &sign, 1); + if (matchedReso) { + flag = sign * decayChannelFlag; + matchedV0Tr = true; break; } } } - } else if (hf_decay::hf_cand_2prong::daughtersD0Main.contains(static_cast(std::abs(flagCharmBach))) && flagTrack == hf_decay::hf_cand_reso::PartialMatchMc::KaonMatched) { - auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], bachelorTrack}; - auto pdgCodesDzeroDaughters = hf_decay::hf_cand_2prong::daughtersD0Main.at(static_cast(std::abs(flagCharmBach))); - auto pdgCodesDaughters = std::array{pdgCodesDzeroDaughters[0], pdgCodesDzeroDaughters[1], +kKPlus}; - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Kplus) { - indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrDaughtersReso, pdgCodeReso, pdgCodesDaughters, true, &sign, 3, &nKinkedTracks); - if (indexRec > -1) { - flagReso = sign * decayChannelFlag; - break; - } - } } - if (indexRec > -1) { - auto particleReso = particlesMc.iteratorAt(indexRec); - ptGen = particleReso.pt(); - invMassGen = computeInvMassGen(particlesMc, indexRec, pdg); + if (matchedReso && matchedV0Tr) { + auto candD0MC = mcParticles.rawIteratorAt(particle.daughtersIds().front()); + matchedD = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candD0MC, o2::constants::physics::Pdg::kD0, std::array{-kKPlus, +kPiPlus}, true, &signD, 2); } - rowMcRecReduced(indexHfCandCharm, indexCandTrBach, - flagReso, flagCharmBach, - flagCharmBachInterm, debugMcRec, - origin, ptGen, invMassGen, - nKinkedTracks); - } - registry.fill(HIST("hMCRecDebug"), debugMcRec); - if (indexRec > -1) { - registry.fill(HIST("hMCRecCounter"), flagReso); - registry.fill(HIST("hMCRecOrigin"), origin); - registry.fill(HIST("hMCRecMassGen"), invMassGen); } - if (flagCharmBach != 0) { - registry.fill(HIST("hMCRecCharmDau"), flagCharmBach); - } - } // fillMcRecoInfoDTrack + if (matchedReso && matchedD && matchedV0Tr) { + origin = RecoDecay::getCharmHadronOrigin(mcParticlesPerMcColl, particle, false, &idxBhadMothers); + registry.fill(HIST("hMCGenOrigin"), origin); + auto ptParticle = particle.pt(); + auto invMassGen = computeInvMassGen(mcParticles, particle.globalIndex(), pdg); + auto yParticle = RecoDecay::y(particle.pVector(), invMassGen); + auto etaParticle = particle.eta(); - // Function for derived data creation - /// \tparam dType is the D meson type (Dstar, Dplus or D0) - /// \param collision is the current collision - /// \param candsD are the D meson candidates in the current collision - /// \param bachelorV0s are the V0 candidates in the current collision - /// \param bachelorTrks are the track ids in the current collision - /// \param tracks is the track table - /// \param tracksIU is the trackIU table - /// \param particlesMc is the MC particle table - /// \param hfRejMap is the event rejection map from the HF event selection util - /// \param pdg is the O2DatabasePDG service - /// \param registry is the histogram registry - /// \param matCorr is the material correction type to be used in the track propagation - /// \param fitter is the DCAFitter object - /// \param rejectPairsWithCommonDaughter is a flag to activate rejection of pairs sharing a daughter track - /// \param rowCollisionReduced is the collision reduced table to be filled - /// \param rowCandDmesReduced is the D-meson reduced table to be filled - /// \param rowCandV0Reduced is the V0 reduced table to be filled - /// \param rowTrkReduced is the track reduced table to be filled - /// \param rowMcRecV0Reduced is the MC reco D-V0 reduced table to be filled - /// \param rowMcRecTrkReduced is the MC reco D-track reduced table to be filled - /// \param rowCandDmesMlReduced is the ML reduced table to be filled - template - void runDataCreation(Coll const& collision, - CCands const& candsD, - BBachV0s const& bachelorV0s, - BBachTracks const& bachelorTrks, - Tr const& tracks, - TrIU const& tracksIU, - PParticles const& particlesMc, - o2::hf_evsel::HfCollisionRejectionMask hfRejMap, - const float bz, - o2::framework::Service const& pdg, - o2::framework::HistogramRegistry& registry, - o2::base::Propagator::MatCorrType const& matCorr, - o2::vertexing::DCAFitterN<2>& fitter, - DmesCuts const& cfgDmesCuts, - TrkCuts const& cfgSingleTrackCuts, - V0Cuts const& cfgV0Cuts, - QaConfig const& cfgQaPlots, - bool rejectPairsWithCommonDaughter, - TableCollRed& rowCollisionReduced, - TableCandDRed& rowCandDmesReduced, - TableCandV0Red& rowCandV0Reduced, - TableTrkRed& rowTrkReduced, - TableMcRecV0Red& rowMcRecV0Reduced, - TableMcRecTrkRed& rowMcRecTrkReduced, - TableCandDMlRed& rowCandDmesMlReduced) - { - int const indexHfReducedCollision = rowCollisionReduced.lastIndex() + 1; - // std::map where the key is the V0.globalIndex() and - // the value is the V0 index in the table of the selected v0s - std::map selectedV0s; - std::map selectedTracks; - bool fillHfReducedCollision = false; - constexpr bool DoTracks = PairingType == PairingType::TrackOnly || PairingType == PairingType::V0AndTrack; - constexpr bool DoV0s = PairingType == PairingType::V0Only || PairingType == PairingType::V0AndTrack; - // loop on D candidates - for (const auto& candD : candsD) { - // initialize variables depending on D meson type - bool fillHfCandD = false; - std::array secondaryVertexD{}; - std::array prongIdsD{}; - std::array bdtScores = {-1.f, -1.f, -1.f, -1.f, -1.f, -1.f}; - std::vector> charmHadDauTracks{}; - varContainer varUtils; - varUtils.ptD = candD.pt(); - if constexpr (DType == DType::Dstar) { - varUtils.signD = candD.signSoftPi(); - if (varUtils.signD > 0) { - varUtils.invMassD = candD.invMassDstar(); - varUtils.invMassD0 = candD.invMassD0(); - } else { - varUtils.invMassD = candD.invMassAntiDstar(); - varUtils.invMassD0 = candD.invMassD0Bar(); - } - secondaryVertexD[0] = candD.xSecondaryVertexD0(); - secondaryVertexD[1] = candD.ySecondaryVertexD0(); - secondaryVertexD[2] = candD.zSecondaryVertexD0(); - prongIdsD[0] = candD.prong0Id(); - prongIdsD[1] = candD.prong1Id(); - prongIdsD[2] = candD.prongPiId(); - varUtils.pVectorProng0 = candD.pVectorProng0(); - varUtils.pVectorProng1 = candD.pVectorProng1(); - varUtils.pVectorProng2 = candD.pVecSoftPi(); - charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong0Id())); - charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong1Id())); - if constexpr (WithMl) { - std::copy(candD.mlProbDstarToD0Pi().begin(), candD.mlProbDstarToD0Pi().end(), bdtScores.begin()); - } - registry.fill(HIST("hMassVsPtDstarAll"), varUtils.ptD, varUtils.invMassD - varUtils.invMassD0); - } else if constexpr (DType == DType::Dplus) { - auto prong0 = tracksIU.rawIteratorAt(candD.prong0Id()); - varUtils.invMassD = HfHelper::invMassDplusToPiKPi(candD); - secondaryVertexD[0] = candD.xSecondaryVertex(); - secondaryVertexD[1] = candD.ySecondaryVertex(); - secondaryVertexD[2] = candD.zSecondaryVertex(); - prongIdsD[0] = candD.prong0Id(); - prongIdsD[1] = candD.prong1Id(); - prongIdsD[2] = candD.prong2Id(); - varUtils.signD = prong0.sign(); - varUtils.pVectorProng0 = candD.pVectorProng0(); - varUtils.pVectorProng1 = candD.pVectorProng1(); - varUtils.pVectorProng2 = candD.pVectorProng2(); - charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong0Id())); - charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong1Id())); - charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong2Id())); - if constexpr (WithMl) { - std::copy(candD.mlProbDplusToPiKPi().begin(), candD.mlProbDplusToPiKPi().end(), bdtScores.begin()); - } - registry.fill(HIST("hMassVsPtDplusAll"), varUtils.ptD, varUtils.invMassD); - } else if constexpr (DType == DType::D0) { - varUtils.invMassD0 = HfHelper::invMassD0ToPiK(candD); - varUtils.invMassD0Bar = HfHelper::invMassD0barToKPi(candD); - secondaryVertexD[0] = candD.xSecondaryVertex(); - secondaryVertexD[1] = candD.ySecondaryVertex(); - secondaryVertexD[2] = candD.zSecondaryVertex(); - prongIdsD[0] = candD.prong0Id(); - prongIdsD[1] = candD.prong1Id(); - prongIdsD[2] = -1; // D0 does not have a third prong - charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong0Id())); - charmHadDauTracks.push_back(tracksIU.rawIteratorAt(candD.prong1Id())); - varUtils.pVectorProng0 = candD.pVectorProng0(); - varUtils.pVectorProng1 = candD.pVectorProng1(); - varUtils.pVectorProng2 = {0.f, 0.f, 0.f}; // D0 does not have a third prong - if constexpr (WithMl) { - std::copy(candD.mlProbD0().begin(), candD.mlProbD0().end(), bdtScores.begin()); - std::copy(candD.mlProbD0bar().begin(), candD.mlProbD0bar().end(), bdtScores.begin() + 3); - } - if (candD.isSelD0() >= cfgDmesCuts.selectionFlagD0.value) { - registry.fill(HIST("hMassVsPtD0All"), varUtils.ptD, varUtils.invMassD0); - } - if (candD.isSelD0bar() >= cfgDmesCuts.selectionFlagD0Bar.value) { - registry.fill(HIST("hMassVsPtD0BarAll"), varUtils.ptD, varUtils.invMassD0Bar); - } - } // end of dType switch - - // Get single track variables - float chi2TpcDauMax = -1.f; - int nItsClsDauMin = 8, nTpcCrossRowsDauMin = 200; - float chi2TpcSoftPi = -1.f; - int nItsClsSoftPi = 8, nTpcCrossRowsSoftPi = 200; - for (const auto& charmHadTrack : charmHadDauTracks) { - if (charmHadTrack.itsNCls() < nItsClsDauMin) { - nItsClsDauMin = charmHadTrack.itsNCls(); - } - if (charmHadTrack.tpcNClsCrossedRows() < nTpcCrossRowsDauMin) { - nTpcCrossRowsDauMin = charmHadTrack.tpcNClsCrossedRows(); - } - if (charmHadTrack.tpcChi2NCl() > chi2TpcDauMax) { - chi2TpcDauMax = charmHadTrack.tpcChi2NCl(); - } - } - if constexpr (DType == DType::Dstar) { - auto softPi = tracksIU.rawIteratorAt(candD.prongPiId()); - nItsClsSoftPi = softPi.itsNCls(); - nTpcCrossRowsSoftPi = softPi.tpcNClsCrossedRows(); - chi2TpcSoftPi = softPi.tpcChi2NCl(); - charmHadDauTracks.push_back(softPi); - } - // Loop on the bachelor V0s - if constexpr (DoV0s) { - for (const auto& v0 : bachelorV0s) { - auto trackPos = tracksIU.rawIteratorAt(v0.posTrackId()); - auto trackNeg = tracksIU.rawIteratorAt(v0.negTrackId()); - // Apply selsection - auto v0DauTracks = std::array{trackPos, trackNeg}; - candidateV0 candV0; - if (!buildAndSelectV0(collision, prongIdsD, v0DauTracks, cfgV0Cuts, fitter, candV0, rejectPairsWithCommonDaughter)) { - continue; - } - // Get single track variables - float chi2TpcDauV0Max = -1.f; - int nItsClsDauV0Min = 8, nTpcCrossRowsDauV0Min = 200; - for (const auto& v0Track : v0DauTracks) { - if (v0Track.itsNCls() < nItsClsDauV0Min) { - nItsClsDauV0Min = v0Track.itsNCls(); - } - if (v0Track.tpcNClsCrossedRows() < nTpcCrossRowsDauV0Min) { - nTpcCrossRowsDauV0Min = v0Track.tpcNClsCrossedRows(); - } - if (v0Track.tpcChi2NCl() > chi2TpcDauV0Max) { - chi2TpcDauV0Max = v0Track.tpcChi2NCl(); - } - } - // propagate V0 to primary vertex (if enabled) - if (cfgV0Cuts.propagateV0toPV.value) { - std::array const pVecV0Orig = {candV0.mom[0], candV0.mom[1], candV0.mom[2]}; - std::array dcaInfo{}; - auto trackParK0 = o2::track::TrackPar(candV0.pos, pVecV0Orig, 0, true); - trackParK0.setPID(o2::track::PID::K0); - trackParK0.setAbsCharge(0); - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParK0, 2.f, matCorr, &dcaInfo); - getPxPyPz(trackParK0, candV0.mom); - } - // compute resonance invariant mass and filling of QA histograms - if (TESTBIT(candV0.v0Type, BachelorType::K0s)) { - registry.fill(HIST("hMassVsPtK0s"), candV0.pT, candV0.mK0Short); - if constexpr (DType == DType::Dstar) { - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom)); - if (varUtils.signD > 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassK0}); - } else { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassK0}); - } - if (!cfgQaPlots.applyCutsForQaHistograms.value || - (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin.value && - varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax.value && - candV0.mK0Short > cfgQaPlots.cutMassK0sMin.value && - candV0.mK0Short < cfgQaPlots.cutMassK0sMax.value)) { - registry.fill(HIST("hMassDstarK0s"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); - } - } else if constexpr (DType == DType::Dplus) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassK0}); - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom)); - if (!cfgQaPlots.applyCutsForQaHistograms.value || - (varUtils.invMassD > cfgQaPlots.cutMassDMin.value && - varUtils.invMassD < cfgQaPlots.cutMassDMax.value && - candV0.mK0Short > cfgQaPlots.cutMassK0sMin.value && - candV0.mK0Short < cfgQaPlots.cutMassK0sMax.value)) { - registry.fill(HIST("hMassDplusK0s"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); - } - } // end of dType switch - } // matched with K0s - bool const isLambda = TESTBIT(candV0.v0Type, BachelorType::Lambda); - bool const isAntiLambda = TESTBIT(candV0.v0Type, BachelorType::AntiLambda); - if (isLambda || isAntiLambda) { - registry.fill(HIST("hMassVsPtLambda"), candV0.pT, candV0.mLambda); - if constexpr (DType == DType::Dstar) { - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom)); - if (varUtils.signD > 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassLambda}); - } else { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassLambda}); - } - if (!cfgQaPlots.applyCutsForQaHistograms.value || - (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin.value && - varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax.value && - candV0.mLambda > cfgQaPlots.cutMassLambdaMin.value && - candV0.mLambda < cfgQaPlots.cutMassLambdaMax.value)) { - registry.fill(HIST("hMassDstarLambda"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); - } - } else if constexpr (DType == DType::Dplus) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassLambda}); - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom)); - if (!cfgQaPlots.applyCutsForQaHistograms.value || - (varUtils.invMassD > cfgQaPlots.cutMassDMin.value && - varUtils.invMassD < cfgQaPlots.cutMassDMax.value && - candV0.mLambda > cfgQaPlots.cutMassLambdaMin.value && - candV0.mLambda < cfgQaPlots.cutMassLambdaMax.value)) { - registry.fill(HIST("hMassDplusLambda"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); - } - } else if constexpr (DType == DType::D0) { - if (isLambda) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassLambda}); - } else { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassLambda}); - } - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, candV0.mom)); - if (!cfgQaPlots.applyCutsForQaHistograms.value || - (((varUtils.invMassD0 > cfgQaPlots.cutMassDMin.value && varUtils.invMassD0 < cfgQaPlots.cutMassDMax.value) || - (varUtils.invMassD0Bar > cfgQaPlots.cutMassDMin.value && varUtils.invMassD0Bar < cfgQaPlots.cutMassDMax.value)) && - candV0.mLambda > cfgQaPlots.cutMassLambdaMin.value && - candV0.mLambda < cfgQaPlots.cutMassLambdaMax.value)) { - if (isLambda) { - registry.fill(HIST("hMassD0Lambda"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0); - } else { - registry.fill(HIST("hMassD0Lambda"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0Bar); - } - } - } // end of dType switch - } // matched with Lambda or AntiLambda - // fill V0 table - // if information on V0 already stored, go to next V0 - if (!selectedV0s.count(v0.globalIndex())) { - rowCandV0Reduced(trackPos.globalIndex(), trackNeg.globalIndex(), - indexHfReducedCollision, - candV0.pos[0], candV0.pos[1], candV0.pos[2], - candV0.momPos[0], candV0.momPos[1], candV0.momPos[2], - candV0.momNeg[0], candV0.momNeg[1], candV0.momNeg[2], - candV0.cosPA, - candV0.dcaV0ToPv, - nItsClsDauV0Min, nTpcCrossRowsDauV0Min, chi2TpcDauV0Max, - candV0.v0Type); - selectedV0s[v0.globalIndex()] = rowCandV0Reduced.lastIndex(); - } - fillHfCandD = true; - // Optional filling of MC Rec table, for now only implemented for Ds1->D*K0s and Ds2*->D+K0s - if constexpr (DoMc) { - auto indexHfCandCharm = rowCandDmesReduced.lastIndex() + 1; - fillMcRecoInfoDV0(particlesMc, candD, v0, tracksIU, indexHfCandCharm, selectedV0s[v0.globalIndex()], pdg, registry, rowMcRecV0Reduced); - } - } // end of loop on V0 candidates - } // end of do V0s - // Loop on the bachelor tracks - if constexpr (DoTracks) { - for (const auto& trackIndex : bachelorTrks) { - auto track = tracks.rawIteratorAt(trackIndex.trackId()); - if (!isTrackSelected(track, prongIdsD, cfgSingleTrackCuts, rejectPairsWithCommonDaughter)) { - continue; - } - // if the track has been reassociated, re-propagate it to PV (minor difference) - auto trackParCovTrack = getTrackParCov(track); - std::array dcaTrack{track.dcaXY(), track.dcaZ()}; - std::array pVecTrack = track.pVector(); - if (track.collisionId() != collision.globalIndex()) { - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParCovTrack, 2.f, matCorr, &dcaTrack); - getPxPyPz(trackParCovTrack, pVecTrack); - } - registry.fill(HIST("hdEdxVsP"), track.p(), track.tpcSignal()); - // compute invariant mass and filling of QA histograms - if constexpr (DType == DType::Dstar) { - // D* pi - if (std::abs(track.tpcNSigmaPi()) < cfgSingleTrackCuts.maxNsigmaTpcPi.value) { - if (varUtils.signD > 0 && track.sign() < 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged}); - } else if (varUtils.signD < 0 && track.sign() > 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged}); - } else { - varUtils.invMassReso = -1.f; // invalid case - } - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); - if (!cfgQaPlots.applyCutsForQaHistograms.value || - (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin.value && - varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax.value)) { - registry.fill(HIST("hMassDstarPi"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); - } - } - if (std::abs(track.tpcNSigmaKa()) < cfgSingleTrackCuts.maxNsigmaTpcKa.value) { - if (varUtils.signD > 0 && track.sign() < 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus}); - } else if (varUtils.signD < 0 && track.sign() > 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus}); - } else { - varUtils.invMassReso = -1.f; // invalid case - } - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); - if (!cfgQaPlots.applyCutsForQaHistograms.value || - (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin.value && - varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax.value)) { - registry.fill(HIST("hMassDstarK"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); - } - } - // D* p - if (std::abs(track.tpcNSigmaPr()) < cfgSingleTrackCuts.maxNsigmaTpcPr.value) { - if (varUtils.signD > 0 && track.sign() > 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton}); - } else if (varUtils.signD < 0 && track.sign() < 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton}); - } else { - varUtils.invMassReso = -1.f; // invalid case - } - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); - if (!cfgQaPlots.applyCutsForQaHistograms.value || - (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin.value && - varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax.value)) { - registry.fill(HIST("hMassDstarProton"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); - } - } - } else if constexpr (DType == DType::Dplus) { - // D+ pi - if (std::abs(track.tpcNSigmaPi()) < cfgSingleTrackCuts.maxNsigmaTpcPi.value) { - if (varUtils.signD * track.sign() < 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged}); - } else { - varUtils.invMassReso = -1.f; // invalid case - } - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); - if (!cfgQaPlots.applyCutsForQaHistograms.value || - (varUtils.invMassD > cfgQaPlots.cutMassDMin.value && - varUtils.invMassD < cfgQaPlots.cutMassDMax.value)) { - registry.fill(HIST("hMassDplusPi"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); - } - } - // D+ K - if (std::abs(track.tpcNSigmaKa()) < cfgSingleTrackCuts.maxNsigmaTpcKa.value) { - if (varUtils.signD * track.sign() < 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus}); - } else { - varUtils.invMassReso = -1.f; // invalid case - } - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); - if (!cfgQaPlots.applyCutsForQaHistograms.value || - (varUtils.invMassD > cfgQaPlots.cutMassDMin.value && - varUtils.invMassD < cfgQaPlots.cutMassDMax.value)) { - registry.fill(HIST("hMassDplusK"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); - } - } - // D+ pr - if (std::abs(track.tpcNSigmaPr()) < cfgSingleTrackCuts.maxNsigmaTpcPr.value) { - if (varUtils.signD * track.sign() < 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton}); - } else { - varUtils.invMassReso = -1.f; // invalid case - } - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); - if (!cfgQaPlots.applyCutsForQaHistograms.value || - (varUtils.invMassD > cfgQaPlots.cutMassDMin.value && - varUtils.invMassD < cfgQaPlots.cutMassDMax.value)) { - registry.fill(HIST("hMassDplusProton"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); - } - } - } else if constexpr (DType == DType::D0) { - // D0 pi - if (std::abs(track.tpcNSigmaPi()) < cfgSingleTrackCuts.maxNsigmaTpcPi.value) { - if (track.sign() > 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged}); - } else { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged}); - } - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack)); - if (!cfgQaPlots.applyCutsForQaHistograms.value || - ((varUtils.invMassD0 > cfgQaPlots.cutMassDMin.value && - varUtils.invMassD0 < cfgQaPlots.cutMassDMax.value) || - (varUtils.invMassD0Bar > cfgQaPlots.cutMassDMin.value && - varUtils.invMassD0Bar < cfgQaPlots.cutMassDMax.value))) { - if (track.sign() > 0) { - registry.fill(HIST("hMassD0Pi"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0); - } else { - registry.fill(HIST("hMassD0Pi"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0Bar); - } - } - } - // D0 K - if (std::abs(track.tpcNSigmaKa()) < cfgSingleTrackCuts.maxNsigmaTpcKa.value) { - if (track.sign() > 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassKPlus}); - } else { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassKPlus}); - } - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack)); - if (!cfgQaPlots.applyCutsForQaHistograms.value || - ((varUtils.invMassD0 > cfgQaPlots.cutMassDMin.value && - varUtils.invMassD0 < cfgQaPlots.cutMassDMax.value) || - (varUtils.invMassD0Bar > cfgQaPlots.cutMassDMin.value && - varUtils.invMassD0Bar < cfgQaPlots.cutMassDMax.value))) { - if (track.sign() > 0) { - registry.fill(HIST("hMassD0K"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0); - } else { - registry.fill(HIST("hMassD0K"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0Bar); - } - } - } - // D0 p - if (std::abs(track.tpcNSigmaPr()) < cfgSingleTrackCuts.maxNsigmaTpcPr.value) { - if (track.sign() > 0) { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassProton}); - } else { - varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, pVecTrack}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassProton}); - } - varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack)); - if (!cfgQaPlots.applyCutsForQaHistograms.value || - ((varUtils.invMassD0 > cfgQaPlots.cutMassDMin.value && - varUtils.invMassD0 < cfgQaPlots.cutMassDMax.value) || - (varUtils.invMassD0Bar > cfgQaPlots.cutMassDMin.value && - varUtils.invMassD0Bar < cfgQaPlots.cutMassDMax.value))) { - if (track.sign() > 0) { - registry.fill(HIST("hMassD0Proton"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0); - } else { - registry.fill(HIST("hMassD0Proton"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0Bar); - } - } - } - } // end of DType switch - // fill track table - if (!selectedTracks.count(track.globalIndex())) { - rowTrkReduced(track.globalIndex(), - indexHfReducedCollision, - track.px(), track.py(), track.pz(), track.sign(), - track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr(), - track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr(), - track.hasTOF(), track.hasTPC(), track.itsNCls(), track.tpcNClsCrossedRows(), track.tpcChi2NCl()); - selectedTracks[track.globalIndex()] = rowTrkReduced.lastIndex(); - } - fillHfCandD = true; - if constexpr (DoMc) { - auto indexHfCandCharm = rowCandDmesReduced.lastIndex() + 1; - fillMcRecoInfoDTrack(particlesMc, candD, track, tracks, indexHfCandCharm, selectedTracks[track.globalIndex()], pdg, registry, rowMcRecTrkReduced); - } - } // end of loop on bachelor tracks - } // end of do tracks - // fill D candidate table - if (fillHfCandD) { // fill candDplus table only once per D candidate, only if at least one V0 is found - if constexpr (DType == DType::Dplus) { - rowCandDmesReduced(prongIdsD[0], prongIdsD[1], prongIdsD[2], - indexHfReducedCollision, - secondaryVertexD[0], secondaryVertexD[1], secondaryVertexD[2], - candD.pxProng0(), candD.pyProng0(), candD.pzProng0(), - candD.pxProng1(), candD.pyProng1(), candD.pzProng1(), - varUtils.pVectorProng2[0], varUtils.pVectorProng2[1], varUtils.pVectorProng2[2], - nItsClsDauMin, nTpcCrossRowsDauMin, chi2TpcDauMax, varUtils.signD); - if constexpr (WithMl) { - rowCandDmesMlReduced(bdtScores[0], bdtScores[1], bdtScores[2], bdtScores[3], bdtScores[4], bdtScores[5]); - } - } else if constexpr (DType == DType::D0) { - uint8_t selFlagD0 = {BIT(D0Sel::SelectedD0) | BIT(D0Sel::SelectedD0Bar)}; - if (candD.isSelD0() < cfgDmesCuts.selectionFlagD0.value) { - CLRBIT(selFlagD0, D0Sel::SelectedD0); - } - if (candD.isSelD0bar() < cfgDmesCuts.selectionFlagD0Bar.value) { - CLRBIT(selFlagD0, D0Sel::SelectedD0Bar); - } - rowCandDmesReduced(prongIdsD[0], prongIdsD[1], - indexHfReducedCollision, - secondaryVertexD[0], secondaryVertexD[1], secondaryVertexD[2], - candD.pxProng0(), candD.pyProng0(), candD.pzProng0(), - candD.pxProng1(), candD.pyProng1(), candD.pzProng1(), - nItsClsDauMin, nTpcCrossRowsDauMin, chi2TpcDauMax, - selFlagD0); - if constexpr (WithMl) { - rowCandDmesMlReduced(bdtScores[0], bdtScores[1], bdtScores[2], bdtScores[3], bdtScores[4], bdtScores[5]); - } - } else if constexpr (DType == DType::Dstar) { - rowCandDmesReduced(prongIdsD[0], prongIdsD[1], prongIdsD[2], - indexHfReducedCollision, - secondaryVertexD[0], secondaryVertexD[1], secondaryVertexD[2], - candD.pxProng0(), candD.pyProng0(), candD.pzProng0(), - candD.pxProng1(), candD.pyProng1(), candD.pzProng1(), - varUtils.pVectorProng2[0], varUtils.pVectorProng2[1], varUtils.pVectorProng2[2], - nItsClsDauMin, nTpcCrossRowsDauMin, chi2TpcDauMax, - nItsClsSoftPi, nTpcCrossRowsSoftPi, chi2TpcSoftPi, - varUtils.signD); - if constexpr (WithMl) { - rowCandDmesMlReduced(bdtScores[0], bdtScores[1], bdtScores[2], bdtScores[3], bdtScores[4], bdtScores[5]); - } - } - fillHfReducedCollision = true; - if constexpr (DType == DType::Dstar) { - registry.fill(HIST("hMassVsPtDstarPaired"), candD.pt(), varUtils.invMassD - varUtils.invMassD0); - } else if constexpr (DType == DType::Dplus) { - registry.fill(HIST("hMassVsPtDplusPaired"), candD.pt(), varUtils.invMassD); - } else if constexpr (DType == DType::D0) { - if (candD.isSelD0() >= cfgDmesCuts.selectionFlagD0.value) { - registry.fill(HIST("hMassVsPtD0Paired"), varUtils.ptD, varUtils.invMassD0); - } - if (candD.isSelD0bar() >= cfgDmesCuts.selectionFlagD0Bar.value) { - registry.fill(HIST("hMassVsPtD0BarPaired"), varUtils.ptD, varUtils.invMassD0Bar); - } - } - } - } // candsD loop - registry.fill(HIST("hEvents"), 1 + Event::Processed); - if (!fillHfReducedCollision) { - registry.fill(HIST("hEvents"), 1 + Event::NoDV0Selected); - return; - } - registry.fill(HIST("hEvents"), 1 + Event::DV0Selected); - // fill collision table if it contains a DPi pair a minima - rowCollisionReduced(collision.posX(), collision.posY(), collision.posZ(), collision.numContrib(), hfRejMap, bz); - } // end of runDataCreation function - - - // Function for derived data creation - /// \tparam dType is the D meson type (Dstar, Dplus or D0) - /// \param mcParticles is the MC particle table - /// \param collInfos is the reco collision table with MC info - /// \param mcCollisions is the MC collision table - /// \param hfEvSelMc is the HF event selection util object from MC - /// \param rejectCollisionsWithBadEvSel is the flag to not store collisions rejected by event selection - /// \param registry is the histogram registry - /// \param pdg is the O2DatabasePDG service - /// \param rowHfResoMcGenReduced is the MC gen reduced table - template - void runMcGen(McParticles const& mcParticles, - McParticlesPerMcColl const& mcParticlesPerMcCollision, - CCs const& collInfos, - CollPerMcColl const& colPerMcCollision, - McCollisions const& mcCollisions, - o2::hf_evsel::HfEventSelectionMc& hfEvSelMc, - bool rejectCollisionsWithBadEvSel, - o2::framework::HistogramRegistry& registry, - o2::framework::Service const& pdg, - TableMcGenRed& rowHfResoMcGenReduced, - BCsInfo const&) - { - bool const doV0s = (PairingType == PairingType::V0Only || PairingType == PairingType::V0AndTrack); - bool const doTracks = (PairingType == PairingType::TrackOnly || PairingType == PairingType::V0AndTrack); - for (const auto& mcCollision : mcCollisions) { - // Slice the particles table to get the particles for the current MC collision - const auto mcParticlesPerMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, mcCollision.globalIndex()); - // Slice the collisions table to get the collision info for the current MC collision - float centrality{-1.f}; - o2::hf_evsel::HfCollisionRejectionMask rejectionMask{}; - int const nSplitColl = 0; - const auto collSlice = collInfos.sliceBy(colPerMcCollision, mcCollision.globalIndex()); - rejectionMask = hfEvSelMc.getHfMcCollisionRejectionMask(mcCollision, collSlice, centrality); - hfEvSelMc.fillHistograms(mcCollision, rejectionMask, nSplitColl); - if (rejectCollisionsWithBadEvSel && rejectionMask != 0) { - // at least one event selection not satisfied --> reject all gen particles from this collision - continue; - } - for (const auto& particle : mcParticlesPerMcColl) { - int8_t sign{0}; - int8_t flag{0}; - int8_t signD{0}; - int8_t signBach{0}; - int8_t origin{0}; - bool matchedReso{false}, matchedD{false}, matchedV0Tr{false}; - std::vector idxBhadMothers{}; - if constexpr (DType == DType::Dstar) { - if (doV0s) { - // D* K0s - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarK0s) { - matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kDStar), +kK0}, true, &sign, 1); - if (matchedReso) { - flag = sign * decayChannelFlag; - auto candV0MC = mcParticles.rawIteratorAt(particle.daughtersIds().back()); - matchedV0Tr = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candV0MC, kK0, std::array{+kPiPlus, -kPiPlus}, true, &signBach, 2); - break; - } - } - } - if (doTracks && !matchedReso) { - // D*+ pi- - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarPi) { - matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kDStar), -static_cast(kPiPlus)}, true, &sign, 1); - if (matchedReso) { - flag = sign * decayChannelFlag; - matchedV0Tr = true; - break; - } - } - } - if (matchedReso && matchedV0Tr) { - auto candDstarMC = mcParticles.rawIteratorAt(particle.daughtersIds().front()); - matchedD = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candDstarMC, o2::constants::physics::Pdg::kDStar, std::array{static_cast(o2::constants::physics::Pdg::kD0), +static_cast(kPiPlus)}, true, &signD, 1); - if (matchedD) { - auto candD0MC = mcParticles.rawIteratorAt(candDstarMC.daughtersIds().front()); - matchedD = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candD0MC, o2::constants::physics::Pdg::kD0, std::array{-kKPlus, +kPiPlus}, true, &signD, 2); - } - } - } else if constexpr (DType == DType::Dplus) { - if (doV0s) { - // D+ K0s - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusK0s) { - matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kDPlus), +kK0}, true, &sign, 1); - if (matchedReso) { - flag = sign * decayChannelFlag; - auto candV0MC = mcParticles.rawIteratorAt(particle.daughtersIds().back()); - matchedV0Tr = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candV0MC, kK0, std::array{+kPiPlus, -kPiPlus}, true, &signBach, 2); - break; - } - } - if (!matchedReso) { - // D+ lambda - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusLambda) { - matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kDPlus), +kLambda0}, true, &sign, 1); - if (matchedReso) { - flag = sign * decayChannelFlag; - auto candV0MC = mcParticles.rawIteratorAt(particle.daughtersIds().back()); - matchedV0Tr = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candV0MC, kLambda0, std::array{+kProton, -kPiPlus}, true, &signBach, 1); - break; - } - } - } - } - if (doTracks && !matchedReso) { - // D+ pi- - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusPi) { - matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kDPlus), -static_cast(kPiPlus)}, true, &sign, 1); - if (matchedReso) { - flag = sign * decayChannelFlag; - matchedV0Tr = true; - break; - } - } - } - if (matchedReso && matchedV0Tr) { - auto candDplusMC = mcParticles.rawIteratorAt(particle.daughtersIds().front()); - matchedD = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candDplusMC, o2::constants::physics::Pdg::kDPlus, std::array{+kPiPlus, -kKPlus, +kPiPlus}, true, &signD, 2); - } - } else if constexpr (DType == DType::D0) { - if (doV0s) { - // D0 Lambda - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Lambda) { - matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kD0), +kLambda0}, true, &sign, 1); - if (matchedReso) { - flag = sign * decayChannelFlag; - auto candV0MC = mcParticles.rawIteratorAt(particle.daughtersIds().back()); - matchedV0Tr = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candV0MC, kLambda0, std::array{+kProton, -kPiPlus}, true, &signBach, 1); - break; - } - } - } - if (doTracks && !matchedReso) { - // D0 pi+ - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Pi) { - matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kD0), +static_cast(kPiPlus)}, true, &sign, 1); - if (matchedReso) { - flag = sign * decayChannelFlag; - matchedV0Tr = true; - break; - } - } - // D0 K+ - if (!matchedReso) { - for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Kplus) { - matchedReso = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, particle, pdgCodeReso, std::array{static_cast(o2::constants::physics::Pdg::kD0), +static_cast(kKPlus)}, true, &sign, 1); - if (matchedReso) { - flag = sign * decayChannelFlag; - matchedV0Tr = true; - break; - } - } - } - } - if (matchedReso && matchedV0Tr) { - auto candD0MC = mcParticles.rawIteratorAt(particle.daughtersIds().front()); - matchedD = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candD0MC, o2::constants::physics::Pdg::kD0, std::array{-kKPlus, +kPiPlus}, true, &signD, 2); - } - } - if (matchedReso && matchedD && matchedV0Tr) { - origin = RecoDecay::getCharmHadronOrigin(mcParticlesPerMcColl, particle, false, &idxBhadMothers); - registry.fill(HIST("hMCGenOrigin"), origin); - auto ptParticle = particle.pt(); - auto invMassGen = computeInvMassGen(mcParticles, particle.globalIndex(), pdg); - auto yParticle = RecoDecay::y(particle.pVector(), invMassGen); - auto etaParticle = particle.eta(); - - std::array ptProngs{}; - std::array yProngs{}; - std::array etaProngs{}; - int counter = 0; - for (const auto& daught : particle.template daughters_as()) { - ptProngs[counter] = daught.pt(); - etaProngs[counter] = daught.eta(); - yProngs[counter] = RecoDecay::y(daught.pVector(), pdg->Mass(daught.pdgCode())); - counter++; - } - registry.fill(HIST("hMCGenCounter"), flag, ptParticle); - rowHfResoMcGenReduced(flag, origin, ptParticle, yParticle, etaParticle, - ptProngs[0], yProngs[0], etaProngs[0], - ptProngs[1], yProngs[1], etaProngs[1], - invMassGen, rejectionMask); - } + std::array ptProngs{}; + std::array yProngs{}; + std::array etaProngs{}; + int counter = 0; + for (const auto& daught : particle.template daughters_as()) { + ptProngs[counter] = daught.pt(); + etaProngs[counter] = daught.eta(); + yProngs[counter] = RecoDecay::y(daught.pVector(), pdg->Mass(daught.pdgCode())); + counter++; } + registry.fill(HIST("hMCGenCounter"), flag, ptParticle); + rowHfResoMcGenReduced(flag, origin, ptParticle, yParticle, etaParticle, + ptProngs[0], yProngs[0], etaProngs[0], + ptProngs[1], yProngs[1], etaProngs[1], + invMassGen, rejectionMask); } } - } // namespace hf_charm_reso + } +} +} // namespace hf_charm_reso } // namespace o2::analysis #endif // PWGHF_D2H_CORE_DATACREATIONCHARMRESO_H_ diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx index afdbb6bb978..ea8e46717fb 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx @@ -79,7 +79,6 @@ using namespace o2::constants::physics; using namespace o2::framework; using namespace o2::framework::expressions; - /// Creation of D-V0 pairs struct HfDataCreatorCharmResoToD0Reduced { diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDplusReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDplusReduced.cxx index 74bbb1fbfc6..bf307f1241d 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDplusReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDplusReduced.cxx @@ -79,7 +79,6 @@ using namespace o2::constants::physics; using namespace o2::framework; using namespace o2::framework::expressions; - /// Creation of D-V0 pairs struct HfDataCreatorCharmResoToDplusReduced { diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDstarReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDstarReduced.cxx index a3b65badc8a..424fe4df603 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDstarReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDstarReduced.cxx @@ -79,7 +79,6 @@ using namespace o2::constants::physics; using namespace o2::framework; using namespace o2::framework::expressions; - /// Creation of D-V0 pairs struct HfDataCreatorCharmResoToDstarReduced { From c11d6c743b904c801e79e2b283d2d76e09647761 Mon Sep 17 00:00:00 2001 From: Fabrizio Grosa Date: Mon, 1 Dec 2025 18:58:09 +0100 Subject: [PATCH 03/10] Factor out common code and simplify event selection --- PWGHF/D2H/Core/DataCreationCharmReso.h | 277 +++++++++++++----- .../dataCreatorCharmHadPiReduced.cxx | 123 +++----- .../dataCreatorCharmResoToD0Reduced.cxx | 183 +++--------- .../dataCreatorCharmResoToDplusReduced.cxx | 177 +++-------- .../dataCreatorCharmResoToDstarReduced.cxx | 177 +++-------- .../dataCreatorJpsiHadReduced.cxx | 26 +- PWGHF/D2H/Utils/utilsRedDataFormat.h | 5 +- 7 files changed, 368 insertions(+), 600 deletions(-) diff --git a/PWGHF/D2H/Core/DataCreationCharmReso.h b/PWGHF/D2H/Core/DataCreationCharmReso.h index d2fdac71f21..f50fc24785e 100644 --- a/PWGHF/D2H/Core/DataCreationCharmReso.h +++ b/PWGHF/D2H/Core/DataCreationCharmReso.h @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file utilsCharmReso.h +/// \file DataCreationCharmReso.h /// \brief utility functions for charm-hadron resonance derived data creators /// /// \author Luca Aglietta , UniTO Turin @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -51,69 +52,191 @@ namespace hf_charm_reso { // event types -enum Event : uint8_t { +enum EventType : uint8_t { Processed = 0, NoDV0Selected, DV0Selected, - kNEvent + NEventType }; enum BachelorType : uint8_t { K0s = 0, Lambda, AntiLambda, - Track + Track, + NBachelorTypes }; -enum DType : uint8_t { +enum DMesonType : uint8_t { Dplus = 1, Dstar, - D0 + D0, + NDMesonType }; enum PairingType : uint8_t { V0Only, TrackOnly, - V0AndTrack + V0AndTrack, + NPairingType }; enum D0Sel : uint8_t { SelectedD0 = 0, - SelectedD0Bar + SelectedD0Bar, + ND0Sel }; // Helper structs to pass D and V0 informations -struct candidateV0 { - std::array pos; - std::array mom; - std::array momPos; - std::array momNeg; - float pT; - float cosPA; - float dcaV0ToPv; - float dcaDau; - float alpha; - float eta; - float radius; - float mK0Short; - float mLambda; - uint8_t v0Type; +struct HfResoCandidateV0 { + std::array pos = {0.f, 0.f, 0.f}; + std::array mom = {0.f, 0.f, 0.f}; + std::array momPos = {0.f, 0.f, 0.f}; + std::array momNeg = {0.f, 0.f, 0.f}; + float pT = -1.f; + float cosPA = -2.f; + float dcaV0ToPv = 1000.f; + float dcaDau = 1000.f; + float alpha = -1.f; + float eta = -999.f; + float radius = 0.f; + float mK0Short = 0.f; + float mLambda = 0.f; + uint8_t v0Type = 0u; }; -struct varContainer { - float invMassD; - float ptD; - float invMassD0; - float invMassD0Bar; - float invMassReso; - float ptReso; - int8_t signD; - std::array pVectorProng0; - std::array pVectorProng1; - std::array pVectorProng2; +struct HfResoVarContainer { + float invMassD = 0.f; + float ptD = -1.f; + float invMassD0 = 0.f; + float invMassD0Bar = 0.f; + float invMassReso = 0.f; + float ptReso = -1.f; + int8_t signD = 0; + std::array pVectorProng0 = {0.f, 0.f, 0.f}; + std::array pVectorProng1 = {0.f, 0.f, 0.f}; + std::array pVectorProng2 = {0.f, 0.f, 0.f}; }; +struct HfResoConfigV0Cuts : o2::framework::ConfigurableGroup { + std::string prefix = "v0s"; // JSON group name + o2::framework::Configurable deltaMassK0s{"deltaMassK0s", 0.02, "delta mass cut for K0S"}; + o2::framework::Configurable deltaMassLambda{"deltaMassLambda", 0.01, "delta mass cut for Lambda"}; + o2::framework::Configurable etaMax{"etaMax", 0.8f, "maximum eta"}; + o2::framework::Configurable etaMaxDau{"etaMaxDau", 5.f, "maximum eta V0 daughters"}; + o2::framework::Configurable trackNclusItsCut{"trackNclusItsCut", 0, "Minimum number of ITS clusters for V0 daughter"}; + o2::framework::Configurable trackNCrossedRowsTpc{"trackNCrossedRowsTpc", 50, "Minimum TPC crossed rows"}; + o2::framework::Configurable trackNsharedClusTpc{"trackNsharedClusTpc", 1000, "Maximum number of shared TPC clusters for V0 daughter"}; + o2::framework::Configurable trackFracMaxindableTpcCls{"trackFracMaxindableTpcCls", 0.8f, "Maximum fraction of findable TPC clusters for V0 daughter"}; + o2::framework::Configurable dcaDau{"dcaDau", 1.f, "DCA V0 daughters"}; + o2::framework::Configurable dcaMaxDauToPv{"dcaMaxDauToPv", 0.1f, "Maximum daughter's DCA to PV"}; + o2::framework::Configurable dcaPv{"dcaPv", 1.f, "DCA V0 to PV"}; + o2::framework::Configurable cosPa{"cosPa", 0.99f, "V0 CosPA"}; + o2::framework::Configurable radiusMin{"radiusMin", 0.9f, "Minimum v0 radius accepted"}; + o2::framework::Configurable nSigmaTpc{"nSigmaTpc", 4.f, "Nsigmatpc"}; + o2::framework::Configurable nSigmaTofPr{"nSigmaTofPr", 4.f, "N sigma TOF for protons only"}; + o2::framework::Configurable propagateV0toPV{"propagateV0toPV", false, "Enable or disable V0 propagation to V0"}; +}; + +struct HfResoConfigSingleTrackCuts : o2::framework::ConfigurableGroup { + std::string prefix = "singleTracks"; // JSON group name + o2::framework::Configurable setTrackSelections{"setTrackSelections", 2, "flag to apply track selections: 0=none; 1=global track w/o DCA selection; 2=global track; 3=only ITS quality"}; + o2::framework::Configurable maxEta{"maxEta", 0.8, "maximum pseudorapidity for single tracks to be paired with D mesons"}; + o2::framework::Configurable minPt{"minPt", 0.1, "minimum pT for single tracks to be paired with D mesons"}; + o2::framework::Configurable maxNsigmaTpcPi{"maxNsigmaTpcPi", -1., "maximum pion NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; + o2::framework::Configurable maxNsigmaTpcKa{"maxNsigmaTpcKa", -1., "maximum kaon NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; + o2::framework::Configurable maxNsigmaTpcPr{"maxNsigmaTpcPr", 3., "maximum proton NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; +}; + +struct HfResoConfigQaPlots : o2::framework::ConfigurableGroup { + std::string prefix = "qaPlots"; // JSON group name + o2::framework::Configurable applyCutsForQaHistograms{"applyCutsForQaHistograms", true, "flag to apply cuts to QA histograms"}; + o2::framework::Configurable cutMassDMin{"cutMassDMin", 1.83, "minimum mass for D0 and Dplus candidates"}; + o2::framework::Configurable cutMassDMax{"cutMassDMax", 1.92, "maximum mass for D0 and Dplus candidates"}; + o2::framework::Configurable cutMassDstarMin{"cutMassDstarMin", 0.139, "minimum mass for Dstar candidates"}; + o2::framework::Configurable cutMassDstarMax{"cutMassDstarMax", 0.175, "maximum mass for Dstar candidates"}; + o2::framework::Configurable cutMassK0sMin{"cutMassK0sMin", 0.485, "minimum mass for K0s candidates"}; + o2::framework::Configurable cutMassK0sMax{"cutMassK0sMax", 0.509, "maximum mass for K0s candidates"}; + o2::framework::Configurable cutMassLambdaMin{"cutMassLambdaMin", 1.11, "minimum mass for Lambda candidates"}; + o2::framework::Configurable cutMassLambdaMax{"cutMassLambdaMax", 1.12, "maximum mass for Lambda candidates"}; +}; + +/// Helper method to add histograms to the registry +/// \param registry is the histogram registry +template +void addHistograms(o2::framework::HistogramRegistry& registry) +{ + constexpr uint8_t kNBinsEvents = EventType::NEventType; + std::string labels[kNBinsEvents]; + labels[EventType::Processed] = "processed"; + labels[EventType::NoDV0Selected] = "without DV0 pairs"; + labels[EventType::DV0Selected] = "with DV0 pairs"; + const o2::framework::AxisSpec axisEvents = {kNBinsEvents, 0.5, kNBinsEvents + 0.5, ""}; + registry.add("hEvents", "Events;;entries", o2::framework::HistType::kTH1D, {axisEvents}); + for (auto iBin{0u}; iBin < kNBinsEvents; iBin++) { + registry.get(HIST("hEvents"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); + } + + const o2::framework::AxisSpec axisPt{50, 0.f, 50.f, "#it{p}_{T} (GeV/#it{c})"}; + const o2::framework::AxisSpec axisP{100, 0.f, 10.f, "#it{p} (GeV/#it{c})"}; + const o2::framework::AxisSpec axisDeDx{500, 0.f, 1000.f, ""}; + const o2::framework::AxisSpec axisMassLambda{100, 1.05f, 1.35f, "inv. mass (GeV/#it{c}^{2})"}; + const o2::framework::AxisSpec axisMassKzero{100, 0.35f, 0.65f, "inv. mass (GeV/#it{c}^{2})"}; + const o2::framework::AxisSpec axisDeltaMassToK{500, 0.49, 1.49, "inv. mass (GeV/#it{c}^{2})"}; + const o2::framework::AxisSpec axisDeltaMassToPi{500, 0.13, 1.13, "inv. mass (GeV/#it{c}^{2})"}; + const o2::framework::AxisSpec axisDeltaMassToPr{500, 0.93, 1.93, "inv. mass (GeV/#it{c}^{2})"}; + const o2::framework::AxisSpec axisDeltaMassToLambda{500, 1.05, 2.05, "inv. mass (GeV/#it{c}^{2})"}; + const o2::framework::AxisSpec axisMassDsj{400, 0.49f, 0.89f, ""}; // Ds1 and Ds2Star legacy + + registry.add("hMassVsPtK0s", "K0^{s} candidates;#it{p}_{T} (GeV/#it{c});inv. mass (#pi^{#plus}#pi^{#minus}) (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisMassKzero}}); + registry.add("hMassVsPtLambda", "Lambda candidates;#it{p}_{T} (GeV/#it{c});inv. mass (p #pi^{#minus}) (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisMassLambda}}); + registry.add("hdEdxVsP", "Tracks;#it{p} (GeV/#it{c});d#it{E}/d#it{x};entries", {o2::framework::HistType::kTH2D, {axisP, axisDeDx}}); + + if constexpr (DType == DMesonType::D0) { + const o2::framework::AxisSpec axisMassD0{200, 1.7f, 2.1f, "inv. mass (GeV/#it{c}^{2})"}; + registry.add("hMassVsPtD0All", "D0 candidates (all, regardless the pairing with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisMassD0}}); + registry.add("hMassVsPtD0BarAll", "D0bar candidates (all, regardless the pairing with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisMassD0}}); + registry.add("hMassVsPtD0Paired", "D0 candidates (paired with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisMassD0}}); + registry.add("hMassVsPtD0BarPaired", "D0 candidates (paired with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisMassD0}}); + registry.add("hMassD0Pi", "D0Pi candidates; m_{D^{0}#pi^{+}} - m_{D^{0}} (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisDeltaMassToPi}}); + registry.add("hMassD0K", "D0Kplus candidates; m_{D^{0}K^{+}} - m_{D^{0}} (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisDeltaMassToK}}); + registry.add("hMassD0Proton", "D0Proton candidates; m_{D^{0}p} - m_{D^{0}} (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisDeltaMassToPr}}); + registry.add("hMassD0Lambda", "D0Lambda candidates; m_{D^{0}#Lambda} - m_{D^{0}} (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisDeltaMassToLambda}}); + } else if constexpr (DType == DMesonType::Dplus) { + const o2::framework::AxisSpec axisMassDplus{200, 1.7f, 2.1f, "inv. mass (GeV/#it{c}^{2})"}; + registry.add("hMassVsPtDplusAll", "Dplus candidates (all, regardless the pairing with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisMassDplus}}); + registry.add("hMassVsPtDplusPaired", "Dplus candidates (paired with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisMassDplus}}); + registry.add("hMassDplusK0s", "DplusK0s candidates; m_{D^{+}K^{0}_{S}} (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisDeltaMassToK}}); + registry.add("hMassDplusPi", "DplusPi candidates; m_{D^{+}#pi^{-}} (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisDeltaMassToPi}}); + registry.add("hMassDplusK", "DplusK candidates; m_{D^{+}#pi^{-}} (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisDeltaMassToK}}); + registry.add("hMassDplusProton", "DplusProton candidates; m_{D^{+}p} (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisDeltaMassToPr}}); + registry.add("hMassDplusLambda", "DplusLambda candidates; m_{D^{+}#Lambda} (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisDeltaMassToLambda}}); + } else if constexpr (DType == DMesonType::Dstar) { + const o2::framework::AxisSpec axisMassDstar{200, 0.139f, 0.179f, "delta inv. mass (GeV/#it{c}^{2})"}; // o2-linter: disable=pdg/explicit-mass (false positive) + registry.add("hMassVsPtDstarAll", "Dstar candidates (all, regardless the pairing with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisMassDstar}}); + registry.add("hMassVsPtDstarPaired", "Dstar candidates (paired with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisMassDstar}}); + registry.add("hMassDstarPi", "DstarPi candidates; m_{D^{*+}#pi^{-}} (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisDeltaMassToPi}}); + registry.add("hMassDstarK", "DstarK candidates; m_{D^{*+}#pi^{-}} (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisDeltaMassToK}}); + registry.add("hMassDstarProton", "DstarProton candidates; m_{D^{*}p} (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisDeltaMassToPr}}); + registry.add("hMassDstarK0s", "DstarK0s candidates; m_{D^{*}K^{0}_{S}} (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisDeltaMassToK}}); + registry.add("hMassDstarLambda", "DstarLambda candidates; m_{D^{*}#Lambda} (GeV/#it{c}^{2});entries", {o2::framework::HistType::kTH2D, {axisPt, axisDeltaMassToLambda}}); + } + + if constexpr (DoMc) { + // MC Rec + int const nChannels = hf_decay::hf_cand_reso::DecayChannelMain::NChannelsMain; + registry.add("hMCRecCounter", "Number of Reconstructed MC Matched candidates per channel", {o2::framework::HistType::kTH1D, {{2 * nChannels + 1, -(nChannels + 0.5), nChannels + 0.5}}}); + registry.add("hMCRecDebug", "Debug of MC Reco", {o2::framework::HistType::kTH1D, {{551, -0.5, 550.5}}}); + registry.add("hMCRecOrigin", "Origin of Matched particles", {o2::framework::HistType::kTH1D, {{3, -0.5, 2.5}}}); + registry.add("hMCRecMassGen", "Generated inv. mass of resoncances", {o2::framework::HistType::kTH1D, {{2000, 1.8, 3.8}}}); + registry.add("hMCRecCharmDau", "Charm daughter flag", {o2::framework::HistType::kTH1D, {{57, -28.5, 28.5}}}); + // MC Gen + registry.add("hMCGenCounter", "Number of Generated particles; Decay Channel Flag; pT (GeV/#it{c})", {o2::framework::HistType::kTH2D, {{17, -8.5, 8.5}, {100, 0, 50}}}); + registry.add("hMCGenOrigin", "Origin of Generated particles", {o2::framework::HistType::kTH1D, {{3, -0.5, 2.5}}}); + } +} + /// Basic track quality selections for V0 daughters /// \param Tr is a track /// \param dDaughtersIds are the IDs of the D meson daughter tracks @@ -184,7 +307,7 @@ float calculateDCAStraightToPV(float x, float y, float z, float px, float py, fl /// \param rejectPairsWithCommonDaughter is a flag to activate rejection of pairs sharing a daughter track /// \return a bitmap with mass hypotesis if passes all cuts template -bool buildAndSelectV0(const Coll& collision, const std::array& dDaughtersIds, const std::array& dauTracks, const Cuts& cfgV0Cuts, o2::vertexing::DCAFitterN<2>& fitter, candidateV0& v0, bool rejectPairsWithCommonDaughter) +bool buildAndSelectV0(const Coll& collision, const std::array& dDaughtersIds, const std::array& dauTracks, const Cuts& cfgV0Cuts, o2::vertexing::DCAFitterN<2>& fitter, HfResoCandidateV0& v0, bool rejectPairsWithCommonDaughter) { const auto& trackPos = dauTracks[0]; const auto& trackNeg = dauTracks[1]; @@ -404,8 +527,8 @@ float computeInvMassGen(PParticles const& particlesMc, int indexRec, o2::framewo auto particleReso = particlesMc.iteratorAt(indexRec); auto dau1 = particlesMc.iteratorAt(particleReso.daughtersIds().front()); auto dau2 = particlesMc.iteratorAt(particleReso.daughtersIds().back()); - std::array, 2> pArr = {{{dau1.px(), dau1.py(), dau1.pz()}, {dau2.px(), dau2.py(), dau2.pz()}}}; - std::array mArr = {static_cast(pdg->Mass(dau1.pdgCode())), static_cast(pdg->Mass(dau2.pdgCode()))}; + std::array, 2> pArr = {{{dau1.px(), dau1.py(), dau1.pz()}, {dau2.px(), dau2.py(), dau2.pz()}}}; + std::array mArr = {pdg->Mass(dau1.pdgCode()), pdg->Mass(dau2.pdgCode())}; return static_cast(RecoDecay::m(pArr, mArr)); } @@ -420,7 +543,7 @@ float computeInvMassGen(PParticles const& particlesMc, int indexRec, o2::framewo /// \param pdg is the O2DatabasePDG service /// \param registry is the histogram registry /// \param rowMcRecReduced is the table to be filled -template +template void fillMcRecoInfoDV0(PParticles const& particlesMc, CCand const& candCharmBach, BBachV0 const& bachelorV0, @@ -435,7 +558,7 @@ void fillMcRecoInfoDV0(PParticles const& particlesMc, int8_t sign{0}, nKinkedTracks{0}, origin{0}, flagCharmBach{0}, flagCharmBachInterm{0}, flagV0{0}, flagReso{0}; int indexRec{-1}, debugMcRec{0}; float ptGen{-1.f}, invMassGen{-1.f}; - if constexpr (DType == DType::Dstar) { + if constexpr (DType == DMesonType::Dstar) { vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prongPiId())); @@ -492,7 +615,7 @@ void fillMcRecoInfoDV0(PParticles const& particlesMc, flagCharmBachInterm, debugMcRec, origin, ptGen, invMassGen, nKinkedTracks); - } else if constexpr (DType == DType::Dplus) { + } else if constexpr (DType == DMesonType::Dplus) { vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong2Id())); @@ -557,7 +680,7 @@ void fillMcRecoInfoDV0(PParticles const& particlesMc, flagCharmBachInterm, debugMcRec, origin, ptGen, invMassGen, nKinkedTracks); - } else if constexpr (DType == DType::D0) { + } else if constexpr (DType == DMesonType::D0) { vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); // Check if D0 is matched @@ -621,7 +744,7 @@ void fillMcRecoInfoDV0(PParticles const& particlesMc, /// \param pdg is the O2DatabasePDG service /// \param registry is the histogram registry /// \param rowMcRecReduced is the table to be filled -template +template void fillMcRecoInfoDTrack(PParticles const& particlesMc, CCand const& candCharmBach, BBachTr const& bachelorTrack, @@ -637,7 +760,7 @@ void fillMcRecoInfoDTrack(PParticles const& particlesMc, int indexRec{-1}; uint16_t debugMcRec{0}; float ptGen{-1.f}, invMassGen{-1.f}; - if constexpr (DType == DType::Dstar) { + if constexpr (DType == DMesonType::Dstar) { vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prongPiId())); @@ -680,7 +803,7 @@ void fillMcRecoInfoDTrack(PParticles const& particlesMc, flagCharmBachInterm, debugMcRec, origin, ptGen, invMassGen, nKinkedTracks); - } else if constexpr (DType == DType::Dplus) { + } else if constexpr (DType == DMesonType::Dplus) { vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong2Id())); @@ -731,7 +854,7 @@ void fillMcRecoInfoDTrack(PParticles const& particlesMc, flagCharmBachInterm, debugMcRec, origin, ptGen, invMassGen, nKinkedTracks); - } else if constexpr (DType == DType::D0) { + } else if constexpr (DType == DMesonType::D0) { vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong0Id())); vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prong1Id())); // Check if D0 is matched @@ -823,7 +946,7 @@ void fillMcRecoInfoDTrack(PParticles const& particlesMc, /// \param rowMcRecV0Reduced is the MC reco D-V0 reduced table to be filled /// \param rowMcRecTrkReduced is the MC reco D-track reduced table to be filled /// \param rowCandDmesMlReduced is the ML reduced table to be filled -template +template void runDataCreation(Coll const& collision, CCands const& candsD, BBachV0s const& bachelorV0s, @@ -856,8 +979,8 @@ void runDataCreation(Coll const& collision, std::map selectedV0s; std::map selectedTracks; bool fillHfReducedCollision = false; - constexpr bool DoTracks = PairingType == PairingType::TrackOnly || PairingType == PairingType::V0AndTrack; - constexpr bool DoV0s = PairingType == PairingType::V0Only || PairingType == PairingType::V0AndTrack; + constexpr bool DoTracks = PairType == PairingType::TrackOnly || PairType == PairingType::V0AndTrack; + constexpr bool DoV0s = PairType == PairingType::V0Only || PairType == PairingType::V0AndTrack; // loop on D candidates for (const auto& candD : candsD) { // initialize variables depending on D meson type @@ -866,9 +989,9 @@ void runDataCreation(Coll const& collision, std::array prongIdsD{}; std::array bdtScores = {-1.f, -1.f, -1.f, -1.f, -1.f, -1.f}; std::vector> charmHadDauTracks{}; - varContainer varUtils; + HfResoVarContainer varUtils; varUtils.ptD = candD.pt(); - if constexpr (DType == DType::Dstar) { + if constexpr (DType == DMesonType::Dstar) { varUtils.signD = candD.signSoftPi(); if (varUtils.signD > 0) { varUtils.invMassD = candD.invMassDstar(); @@ -892,7 +1015,7 @@ void runDataCreation(Coll const& collision, std::copy(candD.mlProbDstarToD0Pi().begin(), candD.mlProbDstarToD0Pi().end(), bdtScores.begin()); } registry.fill(HIST("hMassVsPtDstarAll"), varUtils.ptD, varUtils.invMassD - varUtils.invMassD0); - } else if constexpr (DType == DType::Dplus) { + } else if constexpr (DType == DMesonType::Dplus) { auto prong0 = tracksIU.rawIteratorAt(candD.prong0Id()); varUtils.invMassD = HfHelper::invMassDplusToPiKPi(candD); secondaryVertexD[0] = candD.xSecondaryVertex(); @@ -912,7 +1035,7 @@ void runDataCreation(Coll const& collision, std::copy(candD.mlProbDplusToPiKPi().begin(), candD.mlProbDplusToPiKPi().end(), bdtScores.begin()); } registry.fill(HIST("hMassVsPtDplusAll"), varUtils.ptD, varUtils.invMassD); - } else if constexpr (DType == DType::D0) { + } else if constexpr (DType == DMesonType::D0) { varUtils.invMassD0 = HfHelper::invMassD0ToPiK(candD); varUtils.invMassD0Bar = HfHelper::invMassD0barToKPi(candD); secondaryVertexD[0] = candD.xSecondaryVertex(); @@ -954,7 +1077,7 @@ void runDataCreation(Coll const& collision, chi2TpcDauMax = charmHadTrack.tpcChi2NCl(); } } - if constexpr (DType == DType::Dstar) { + if constexpr (DType == DMesonType::Dstar) { auto softPi = tracksIU.rawIteratorAt(candD.prongPiId()); nItsClsSoftPi = softPi.itsNCls(); nTpcCrossRowsSoftPi = softPi.tpcNClsCrossedRows(); @@ -968,7 +1091,7 @@ void runDataCreation(Coll const& collision, auto trackNeg = tracksIU.rawIteratorAt(v0.negTrackId()); // Apply selsection auto v0DauTracks = std::array{trackPos, trackNeg}; - candidateV0 candV0; + HfResoCandidateV0 candV0; if (!buildAndSelectV0(collision, prongIdsD, v0DauTracks, cfgV0Cuts, fitter, candV0, rejectPairsWithCommonDaughter)) { continue; } @@ -999,7 +1122,7 @@ void runDataCreation(Coll const& collision, // compute resonance invariant mass and filling of QA histograms if (TESTBIT(candV0.v0Type, BachelorType::K0s)) { registry.fill(HIST("hMassVsPtK0s"), candV0.pT, candV0.mK0Short); - if constexpr (DType == DType::Dstar) { + if constexpr (DType == DMesonType::Dstar) { varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom)); if (varUtils.signD > 0) { varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassK0}); @@ -1013,7 +1136,7 @@ void runDataCreation(Coll const& collision, candV0.mK0Short < cfgQaPlots.cutMassK0sMax.value)) { registry.fill(HIST("hMassDstarK0s"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); } - } else if constexpr (DType == DType::Dplus) { + } else if constexpr (DType == DMesonType::Dplus) { varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassK0}); varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom)); if (!cfgQaPlots.applyCutsForQaHistograms.value || @@ -1029,7 +1152,7 @@ void runDataCreation(Coll const& collision, bool const isAntiLambda = TESTBIT(candV0.v0Type, BachelorType::AntiLambda); if (isLambda || isAntiLambda) { registry.fill(HIST("hMassVsPtLambda"), candV0.pT, candV0.mLambda); - if constexpr (DType == DType::Dstar) { + if constexpr (DType == DMesonType::Dstar) { varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom)); if (varUtils.signD > 0) { varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassLambda}); @@ -1043,7 +1166,7 @@ void runDataCreation(Coll const& collision, candV0.mLambda < cfgQaPlots.cutMassLambdaMax.value)) { registry.fill(HIST("hMassDstarLambda"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); } - } else if constexpr (DType == DType::Dplus) { + } else if constexpr (DType == DMesonType::Dplus) { varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassLambda}); varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candV0.mom)); if (!cfgQaPlots.applyCutsForQaHistograms.value || @@ -1053,7 +1176,7 @@ void runDataCreation(Coll const& collision, candV0.mLambda < cfgQaPlots.cutMassLambdaMax.value)) { registry.fill(HIST("hMassDplusLambda"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); } - } else if constexpr (DType == DType::D0) { + } else if constexpr (DType == DMesonType::D0) { if (isLambda) { varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, candV0.mom}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassKPlus, o2::constants::physics::MassLambda}); } else { @@ -1112,7 +1235,7 @@ void runDataCreation(Coll const& collision, } registry.fill(HIST("hdEdxVsP"), track.p(), track.tpcSignal()); // compute invariant mass and filling of QA histograms - if constexpr (DType == DType::Dstar) { + if constexpr (DType == DMesonType::Dstar) { // D* pi if (std::abs(track.tpcNSigmaPi()) < cfgSingleTrackCuts.maxNsigmaTpcPi.value) { if (varUtils.signD > 0 && track.sign() < 0) { @@ -1160,7 +1283,7 @@ void runDataCreation(Coll const& collision, registry.fill(HIST("hMassDstarProton"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); } } - } else if constexpr (DType == DType::Dplus) { + } else if constexpr (DType == DMesonType::Dplus) { // D+ pi if (std::abs(track.tpcNSigmaPi()) < cfgSingleTrackCuts.maxNsigmaTpcPi.value) { if (varUtils.signD * track.sign() < 0) { @@ -1203,7 +1326,7 @@ void runDataCreation(Coll const& collision, registry.fill(HIST("hMassDplusProton"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); } } - } else if constexpr (DType == DType::D0) { + } else if constexpr (DType == DMesonType::D0) { // D0 pi if (std::abs(track.tpcNSigmaPi()) < cfgSingleTrackCuts.maxNsigmaTpcPi.value) { if (track.sign() > 0) { @@ -1284,7 +1407,7 @@ void runDataCreation(Coll const& collision, } // end of do tracks // fill D candidate table if (fillHfCandD) { // fill candDplus table only once per D candidate, only if at least one V0 is found - if constexpr (DType == DType::Dplus) { + if constexpr (DType == DMesonType::Dplus) { rowCandDmesReduced(prongIdsD[0], prongIdsD[1], prongIdsD[2], indexHfReducedCollision, secondaryVertexD[0], secondaryVertexD[1], secondaryVertexD[2], @@ -1295,7 +1418,7 @@ void runDataCreation(Coll const& collision, if constexpr (WithMl) { rowCandDmesMlReduced(bdtScores[0], bdtScores[1], bdtScores[2], bdtScores[3], bdtScores[4], bdtScores[5]); } - } else if constexpr (DType == DType::D0) { + } else if constexpr (DType == DMesonType::D0) { uint8_t selFlagD0 = {BIT(D0Sel::SelectedD0) | BIT(D0Sel::SelectedD0Bar)}; if (candD.isSelD0() < cfgDmesCuts.selectionFlagD0.value) { CLRBIT(selFlagD0, D0Sel::SelectedD0); @@ -1313,7 +1436,7 @@ void runDataCreation(Coll const& collision, if constexpr (WithMl) { rowCandDmesMlReduced(bdtScores[0], bdtScores[1], bdtScores[2], bdtScores[3], bdtScores[4], bdtScores[5]); } - } else if constexpr (DType == DType::Dstar) { + } else if constexpr (DType == DMesonType::Dstar) { rowCandDmesReduced(prongIdsD[0], prongIdsD[1], prongIdsD[2], indexHfReducedCollision, secondaryVertexD[0], secondaryVertexD[1], secondaryVertexD[2], @@ -1328,11 +1451,11 @@ void runDataCreation(Coll const& collision, } } fillHfReducedCollision = true; - if constexpr (DType == DType::Dstar) { + if constexpr (DType == DMesonType::Dstar) { registry.fill(HIST("hMassVsPtDstarPaired"), candD.pt(), varUtils.invMassD - varUtils.invMassD0); - } else if constexpr (DType == DType::Dplus) { + } else if constexpr (DType == DMesonType::Dplus) { registry.fill(HIST("hMassVsPtDplusPaired"), candD.pt(), varUtils.invMassD); - } else if constexpr (DType == DType::D0) { + } else if constexpr (DType == DMesonType::D0) { if (candD.isSelD0() >= cfgDmesCuts.selectionFlagD0.value) { registry.fill(HIST("hMassVsPtD0Paired"), varUtils.ptD, varUtils.invMassD0); } @@ -1342,12 +1465,12 @@ void runDataCreation(Coll const& collision, } } } // candsD loop - registry.fill(HIST("hEvents"), 1 + Event::Processed); + registry.fill(HIST("hEvents"), 1 + EventType::Processed); if (!fillHfReducedCollision) { - registry.fill(HIST("hEvents"), 1 + Event::NoDV0Selected); + registry.fill(HIST("hEvents"), 1 + EventType::NoDV0Selected); return; } - registry.fill(HIST("hEvents"), 1 + Event::DV0Selected); + registry.fill(HIST("hEvents"), 1 + EventType::DV0Selected); // fill collision table if it contains a DPi pair a minima rowCollisionReduced(collision.posX(), collision.posY(), collision.posZ(), collision.numContrib(), hfRejMap, bz); } // end of runDataCreation function @@ -1362,7 +1485,7 @@ void runDataCreation(Coll const& collision, /// \param registry is the histogram registry /// \param pdg is the O2DatabasePDG service /// \param rowHfResoMcGenReduced is the MC gen reduced table -template +template void runMcGen(McParticles const& mcParticles, McParticlesPerMcColl const& mcParticlesPerMcCollision, CCs const& collInfos, @@ -1375,8 +1498,8 @@ void runMcGen(McParticles const& mcParticles, TableMcGenRed& rowHfResoMcGenReduced, BCsInfo const&) { - bool const doV0s = (PairingType == PairingType::V0Only || PairingType == PairingType::V0AndTrack); - bool const doTracks = (PairingType == PairingType::TrackOnly || PairingType == PairingType::V0AndTrack); + bool const doV0s = (PairType == PairingType::V0Only || PairType == PairingType::V0AndTrack); + bool const doTracks = (PairType == PairingType::TrackOnly || PairType == PairingType::V0AndTrack); for (const auto& mcCollision : mcCollisions) { // Slice the particles table to get the particles for the current MC collision const auto mcParticlesPerMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, mcCollision.globalIndex()); @@ -1399,7 +1522,7 @@ void runMcGen(McParticles const& mcParticles, int8_t origin{0}; bool matchedReso{false}, matchedD{false}, matchedV0Tr{false}; std::vector idxBhadMothers{}; - if constexpr (DType == DType::Dstar) { + if constexpr (DType == DMesonType::Dstar) { if (doV0s) { // D* K0s for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarK0s) { @@ -1431,7 +1554,7 @@ void runMcGen(McParticles const& mcParticles, matchedD = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candD0MC, o2::constants::physics::Pdg::kD0, std::array{-kKPlus, +kPiPlus}, true, &signD, 2); } } - } else if constexpr (DType == DType::Dplus) { + } else if constexpr (DType == DMesonType::Dplus) { if (doV0s) { // D+ K0s for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDplusK0s) { @@ -1471,7 +1594,7 @@ void runMcGen(McParticles const& mcParticles, auto candDplusMC = mcParticles.rawIteratorAt(particle.daughtersIds().front()); matchedD = RecoDecay::isMatchedMCGen(mcParticlesPerMcColl, candDplusMC, o2::constants::physics::Pdg::kDPlus, std::array{+kPiPlus, -kKPlus, +kPiPlus}, true, &signD, 2); } - } else if constexpr (DType == DType::D0) { + } else if constexpr (DType == DMesonType::D0) { if (doV0s) { // D0 Lambda for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToD0Lambda) { diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx index a9d569cb32c..9687c440a2f 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx @@ -1023,11 +1023,16 @@ struct HfDataCreatorCharmHadPiReduced { TTracks const&, PParticles const& particlesMc, uint64_t const& indexCollisionMaxNumContrib, - BBCs const&) + BBCs const&, + int& zvtxColl, + int& sel8Coll, + int& zvtxAndSel8Coll, + int& zvtxAndSel8CollAndSoftTrig, + int& allSelColl) { registry.fill(HIST("hEvents"), 1 + Event::Processed); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (configs.skipRejectedCollisions && hfRejMap != 0) { return; } @@ -1760,12 +1765,10 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsDplusPerCollision, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -1790,12 +1793,10 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsDplusPerCollisionWithMl, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -1820,12 +1821,10 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsDplusPerCollision, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -1850,12 +1849,10 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsDplusPerCollisionWithMl, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -1881,12 +1878,10 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsDstarPerCollision, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -1912,12 +1907,10 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsDstarPerCollisionWithMl, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -1943,12 +1936,10 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsDstarPerCollision, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -1974,12 +1965,10 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsDstarPerCollisionWithMl, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -2004,12 +1993,10 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsDsPerCollision, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -2034,12 +2021,10 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsDsPerCollisionWithMl, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -2064,12 +2049,10 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsDsPerCollision, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -2094,12 +2077,10 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsDsPerCollisionWithMl, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -2124,12 +2105,10 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsD0PerCollision, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -2154,12 +2133,10 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsD0PerCollisionWithMl, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -2184,12 +2161,10 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsD0PerCollision, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -2214,12 +2189,10 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsD0PerCollisionWithMl, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -2244,12 +2217,10 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsLcPerCollision, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -2274,12 +2245,10 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsLcPerCollisionWithMl, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -2309,14 +2278,12 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsDplusPerCollision, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); auto collsSameMcCollision = collisions.sliceBy(preslices.colPerMcCollision, collision.mcCollisionId()); int64_t const indexCollisionMaxNumContrib = getIndexCollisionMaxNumContrib(collsSameMcCollision); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -2346,14 +2313,12 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsDplusPerCollisionWithMl, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); auto collsSameMcCollision = collisions.sliceBy(preslices.colPerMcCollision, collision.mcCollisionId()); int64_t const indexCollisionMaxNumContrib = getIndexCollisionMaxNumContrib(collsSameMcCollision); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -2384,14 +2349,12 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsDstarPerCollision, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); auto collsSameMcCollision = collisions.sliceBy(preslices.colPerMcCollision, collision.mcCollisionId()); int64_t const indexCollisionMaxNumContrib = getIndexCollisionMaxNumContrib(collsSameMcCollision); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -2422,14 +2385,12 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsDstarPerCollisionWithMl, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); auto collsSameMcCollision = collisions.sliceBy(preslices.colPerMcCollision, collision.mcCollisionId()); int64_t const indexCollisionMaxNumContrib = getIndexCollisionMaxNumContrib(collsSameMcCollision); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -2459,14 +2420,12 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsDsPerCollision, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); auto collsSameMcCollision = collisions.sliceBy(preslices.colPerMcCollision, collision.mcCollisionId()); int64_t const indexCollisionMaxNumContrib = getIndexCollisionMaxNumContrib(collsSameMcCollision); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -2496,14 +2455,12 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsDsPerCollisionWithMl, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); auto collsSameMcCollision = collisions.sliceBy(preslices.colPerMcCollision, collision.mcCollisionId()); int64_t const indexCollisionMaxNumContrib = getIndexCollisionMaxNumContrib(collsSameMcCollision); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -2533,14 +2490,12 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsD0PerCollision, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); auto collsSameMcCollision = collisions.sliceBy(preslices.colPerMcCollision, collision.mcCollisionId()); int64_t const indexCollisionMaxNumContrib = getIndexCollisionMaxNumContrib(collsSameMcCollision); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -2570,14 +2525,12 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsD0PerCollisionWithMl, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); auto collsSameMcCollision = collisions.sliceBy(preslices.colPerMcCollision, collision.mcCollisionId()); int64_t const indexCollisionMaxNumContrib = getIndexCollisionMaxNumContrib(collsSameMcCollision); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -2607,14 +2560,12 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsLcPerCollision, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); auto collsSameMcCollision = collisions.sliceBy(preslices.colPerMcCollision, collision.mcCollisionId()); int64_t const indexCollisionMaxNumContrib = getIndexCollisionMaxNumContrib(collsSameMcCollision); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -2644,14 +2595,12 @@ struct HfDataCreatorCharmHadPiReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsCThisColl = candsC.sliceBy(preslices.candsLcPerCollisionWithMl, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(preslices.trackIndicesPerCollision, thisCollId); auto collsSameMcCollision = collisions.sliceBy(preslices.colPerMcCollision, collision.mcCollisionId()); int64_t const indexCollisionMaxNumContrib = getIndexCollisionMaxNumContrib(collsSameMcCollision); - runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs); + runDataCreation(collision, candsCThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions tables.hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx index ea8e46717fb..a02424025cf 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx @@ -102,52 +102,12 @@ struct HfDataCreatorCharmResoToD0Reduced { Configurable selectionFlagD0{"selectionFlagD0", 1, "Selection Flag for D0"}; Configurable selectionFlagD0Bar{"selectionFlagD0Bar", 1, "Selection Flag for D0bar"}; } cfgDmesCuts; - // selection V0 - struct : ConfigurableGroup { - std::string prefix = "v0s"; - Configurable deltaMassK0s{"deltaMassK0s", 0.02, "delta mass cut for K0S"}; - Configurable deltaMassLambda{"deltaMassLambda", 0.01, "delta mass cut for Lambda"}; - Configurable etaMax{"etaMax", 0.8f, "maximum eta"}; - Configurable etaMaxDau{"etaMaxDau", 5.f, "maximum eta V0 daughters"}; - Configurable trackNclusItsCut{"trackNclusItsCut", 0, "Minimum number of ITS clusters for V0 daughter"}; - Configurable trackNCrossedRowsTpc{"trackNCrossedRowsTpc", 50, "Minimum TPC crossed rows"}; - Configurable trackNsharedClusTpc{"trackNsharedClusTpc", 1000, "Maximum number of shared TPC clusters for V0 daughter"}; - Configurable trackFracMaxindableTpcCls{"trackFracMaxindableTpcCls", 0.8f, "Maximum fraction of findable TPC clusters for V0 daughter"}; - Configurable dcaDau{"dcaDau", 1.f, "DCA V0 daughters"}; - Configurable dcaMaxDauToPv{"dcaMaxDauToPv", 0.1f, "Maximum daughter's DCA to PV"}; - Configurable dcaPv{"dcaPv", 1.f, "DCA V0 to PV"}; - Configurable cosPa{"cosPa", 0.99f, "V0 CosPA"}; - Configurable radiusMin{"radiusMin", 0.9f, "Minimum v0 radius accepted"}; - Configurable nSigmaTpc{"nSigmaTpc", 4.f, "Nsigmatpc"}; - Configurable nSigmaTofPr{"nSigmaTofPr", 4.f, "N sigma TOF for protons only"}; - Configurable propagateV0toPV{"propagateV0toPV", false, "Enable or disable V0 propagation to V0"}; - } cfgV0Cuts; - + HfResoConfigV0Cuts cfgV0Cuts; // selection single tracks - struct : ConfigurableGroup { - std::string prefix = "singleTracks"; - Configurable setTrackSelections{"setTrackSelections", 2, "flag to apply track selections: 0=none; 1=global track w/o DCA selection; 2=global track; 3=only ITS quality"}; - Configurable maxEta{"maxEta", 0.8, "maximum pseudorapidity for single tracks to be paired with D mesons"}; - Configurable minPt{"minPt", 0.1, "minimum pT for single tracks to be paired with D mesons"}; - Configurable maxNsigmaTpcPi{"maxNsigmaTpcPi", -1., "maximum pion NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; - Configurable maxNsigmaTpcKa{"maxNsigmaTpcKa", -1., "maximum kaon NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; - Configurable maxNsigmaTpcPr{"maxNsigmaTpcPr", 3., "maximum proton NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; - } cfgSingleTrackCuts; - + HfResoConfigSingleTrackCuts cfgSingleTrackCuts; // QA histograms - struct : ConfigurableGroup { - std::string prefix = "qaPlots"; - Configurable applyCutsForQaHistograms{"applyCutsForQaHistograms", true, "flag to apply cuts to QA histograms"}; - Configurable cutMassDstarMin{"cutMassDstarMin", 0.143, "minimum mass for Dstar candidates"}; - Configurable cutMassDstarMax{"cutMassDstarMax", 0.155, "maximum mass for Dstar candidates"}; - Configurable cutMassDMin{"cutMassDMin", 1.83, "minimum mass for D0 and Dplus candidates"}; - Configurable cutMassDMax{"cutMassDMax", 1.92, "maximum mass for D0 and Dplus candidates"}; - Configurable cutMassK0sMin{"cutMassK0sMin", 0.485, "minimum mass for K0s candidates"}; - Configurable cutMassK0sMax{"cutMassK0sMax", 0.509, "maximum mass for K0s candidates"}; - Configurable cutMassLambdaMin{"cutMassLambdaMin", 1.11, "minimum mass for Lambda candidates"}; - Configurable cutMassLambdaMax{"cutMassLambdaMax", 1.12, "maximum mass for Lambda candidates"}; - } cfgQaPlots; + HfResoConfigQaPlots cfgQaPlots; // other configurables Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; @@ -198,57 +158,18 @@ struct HfDataCreatorCharmResoToD0Reduced { PresliceUnsorted colPerMcCollision = aod::mccollisionlabel::mcCollisionId; HistogramRegistry registry{"registry"}; + OutputObj zorroSummary{"zorroSummary"}; void init(InitContext& initContext) { + // histograms - constexpr int kNBinsEvents = kNEvent; - std::string labels[kNBinsEvents]; - labels[Event::Processed] = "processed"; - labels[Event::NoDV0Selected] = "without DV0 pairs"; - labels[Event::DV0Selected] = "with DV0 pairs"; - static const AxisSpec axisEvents = {kNBinsEvents, 0.5, kNBinsEvents + 0.5, ""}; - registry.add("hEvents", "Events;;entries", HistType::kTH1D, {axisEvents}); - for (int iBin = 0; iBin < kNBinsEvents; iBin++) { - registry.get(HIST("hEvents"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); - } - - const AxisSpec axisPt{50, 0.f, 50.f, "#it{p}_{T} (GeV/#it{c})"}; - const AxisSpec axisP{100, 0.f, 10.f, "#it{p} (GeV/#it{c})"}; - const AxisSpec axisDeDx{500, 0.f, 1000.f, ""}; - const AxisSpec axisMassD0{200, 1.7f, 2.1f, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisMassDplus{200, 1.7f, 2.1f, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisMassDstar{200, 0.139f, 0.179f, "delta inv. mass (GeV/#it{c}^{2})"}; // o2-linter: disable=pdg/explicit-mass (false positive) - const AxisSpec axisMassLambda{100, 1.05f, 1.35f, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisMassKzero{100, 0.35f, 0.65f, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisDeltaMassToK{500, 0.49, 1.49, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisDeltaMassToPi{500, 0.13, 1.13, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisDeltaMassToPr{500, 0.93, 1.93, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisDeltaMassToLambda{500, 1.05, 2.05, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisMassDsj{400, 0.49f, 0.89f, ""}; // Ds1 and Ds2Star legacy - registry.add("hMassVsPtK0s", "K0^{s} candidates;#it{p}_{T} (GeV/#it{c});inv. mass (#pi^{#plus}#pi^{#minus}) (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassKzero}}); - registry.add("hMassVsPtLambda", "Lambda candidates;#it{p}_{T} (GeV/#it{c});inv. mass (p #pi^{#minus}) (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassLambda}}); - registry.add("hdEdxVsP", "Tracks;#it{p} (GeV/#it{c});d#it{E}/d#it{x};entries", {HistType::kTH2D, {axisP, axisDeDx}}); - registry.add("hMassVsPtD0All", "D0 candidates (all, regardless the pairing with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassD0}}); - registry.add("hMassVsPtD0BarAll", "D0bar candidates (all, regardless the pairing with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassD0}}); - registry.add("hMassVsPtD0Paired", "D0 candidates (paired with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassD0}}); - registry.add("hMassVsPtD0BarPaired", "D0 candidates (paired with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassD0}}); - registry.add("hMassD0Pi", "D0Pi candidates; m_{D^{0}#pi^{+}} - m_{D^{0}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPi}}); - registry.add("hMassD0K", "D0Kplus candidates; m_{D^{0}K^{+}} - m_{D^{0}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToK}}); - registry.add("hMassD0Proton", "D0Proton candidates; m_{D^{0}p} - m_{D^{0}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPr}}); - registry.add("hMassD0Lambda", "D0Lambda candidates; m_{D^{0}#Lambda} - m_{D^{0}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToLambda}}); if (doprocessD0V0MC || doprocessD0TrackMC || doprocessD0V0AndTrackMC || doprocessD0V0MCWithMl || doprocessD0TrackMCWithMl || doprocessD0V0AndTrackMCWithMl) { - // MC Rec - int const nChannels = hf_decay::hf_cand_reso::DecayChannelMain::NChannelsMain; - registry.add("hMCRecCounter", "Number of Reconstructed MC Matched candidates per channel", {HistType::kTH1D, {{2 * nChannels + 1, -(nChannels + 0.5), nChannels + 0.5}}}); - registry.add("hMCRecDebug", "Debug of MC Reco", {HistType::kTH1D, {{551, -0.5, 550.5}}}); - registry.add("hMCRecOrigin", "Origin of Matched particles", {HistType::kTH1D, {{3, -0.5, 2.5}}}); - registry.add("hMCRecMassGen", "Generated inv. mass of resoncances", {HistType::kTH1D, {{2000, 1.8, 3.8}}}); - registry.add("hMCRecCharmDau", "Charm daughter flag", {HistType::kTH1D, {{57, -28.5, 28.5}}}); - // MC Gen - registry.add("hMCGenCounter", "Number of Generated particles; Decay Channel Flag; pT [GeV/c]", {HistType::kTH2D, {{17, -8.5, 8.5}, {100, 0, 50}}}); - registry.add("hMCGenOrigin", "Origin of Generated particles", {HistType::kTH1D, {{3, -0.5, 2.5}}}); + addHistograms(registry); + } else { + addHistograms(registry); } + // Configure CCDB access ccdb->setURL(ccdbUrl.value); ccdb->setCaching(true); @@ -270,7 +191,7 @@ struct HfDataCreatorCharmResoToD0Reduced { fitter.setWeightedFinalPCA(false); // init HF event selection helper - hfEvSel.init(registry); + hfEvSel.init(registry, zorroSummary); const auto& workflows = initContext.services().get(); for (const DeviceSpec& device : workflows.devices) { @@ -298,9 +219,7 @@ struct HfDataCreatorCharmResoToD0Reduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -315,7 +234,7 @@ struct HfDataCreatorCharmResoToD0Reduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsD0.sliceBy(candsD0PerCollision, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, dummyTable, dummyTable, dummyTable, dummyTable); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, dummyTable, dummyTable, dummyTable, dummyTable); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -335,9 +254,7 @@ struct HfDataCreatorCharmResoToD0Reduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -352,7 +269,7 @@ struct HfDataCreatorCharmResoToD0Reduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsD0.sliceBy(candsD0PerCollision, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, dummyTable, hfTrackNoParam, dummyTable, dummyTable, dummyTable); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, dummyTable, hfTrackNoParam, dummyTable, dummyTable, dummyTable); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -374,9 +291,7 @@ struct HfDataCreatorCharmResoToD0Reduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -392,7 +307,7 @@ struct HfDataCreatorCharmResoToD0Reduced { auto candsDThisColl = candsD0.sliceBy(candsD0PerCollision, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, hfTrackNoParam, dummyTable, dummyTable, dummyTable); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, hfTrackNoParam, dummyTable, dummyTable, dummyTable); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -414,9 +329,7 @@ struct HfDataCreatorCharmResoToD0Reduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -431,7 +344,7 @@ struct HfDataCreatorCharmResoToD0Reduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsD0.sliceBy(candsD0PerCollisionWithMl, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, dummyTable, dummyTable, dummyTable, hfCandD2PrMl); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, dummyTable, dummyTable, dummyTable, hfCandD2PrMl); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -451,9 +364,7 @@ struct HfDataCreatorCharmResoToD0Reduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -468,7 +379,7 @@ struct HfDataCreatorCharmResoToD0Reduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsD0.sliceBy(candsD0PerCollisionWithMl, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, dummyTable, hfTrackNoParam, dummyTable, dummyTable, hfCandD2PrMl); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, dummyTable, hfTrackNoParam, dummyTable, dummyTable, hfCandD2PrMl); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -490,9 +401,7 @@ struct HfDataCreatorCharmResoToD0Reduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -508,7 +417,7 @@ struct HfDataCreatorCharmResoToD0Reduced { auto candsDThisColl = candsD0.sliceBy(candsD0PerCollisionWithMl, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, hfTrackNoParam, dummyTable, dummyTable, hfCandD2PrMl); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, hfTrackNoParam, dummyTable, dummyTable, hfCandD2PrMl); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -533,9 +442,7 @@ struct HfDataCreatorCharmResoToD0Reduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -550,9 +457,9 @@ struct HfDataCreatorCharmResoToD0Reduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsD0.sliceBy(candsD0PerCollision, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, dummyTable, rowHf2PrV0McRecReduced, dummyTable, dummyTable); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, dummyTable, rowHf2PrV0McRecReduced, dummyTable, dummyTable); } - runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } @@ -574,9 +481,7 @@ struct HfDataCreatorCharmResoToD0Reduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -591,9 +496,9 @@ struct HfDataCreatorCharmResoToD0Reduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsD0.sliceBy(candsD0PerCollision, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, dummyTable, hfTrackNoParam, dummyTable, rowHf2PrTrkMcRecReduced, dummyTable); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, dummyTable, hfTrackNoParam, dummyTable, rowHf2PrTrkMcRecReduced, dummyTable); } - runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } @@ -617,9 +522,7 @@ struct HfDataCreatorCharmResoToD0Reduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -635,9 +538,9 @@ struct HfDataCreatorCharmResoToD0Reduced { auto candsDThisColl = candsD0.sliceBy(candsD0PerCollision, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, hfTrackNoParam, rowHf2PrV0McRecReduced, rowHf2PrTrkMcRecReduced, dummyTable); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, hfTrackNoParam, rowHf2PrV0McRecReduced, rowHf2PrTrkMcRecReduced, dummyTable); } - runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } @@ -660,9 +563,7 @@ struct HfDataCreatorCharmResoToD0Reduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -677,9 +578,9 @@ struct HfDataCreatorCharmResoToD0Reduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsD0.sliceBy(candsD0PerCollisionWithMl, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, dummyTable, rowHf2PrV0McRecReduced, dummyTable, hfCandD2PrMl); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, dummyTable, rowHf2PrV0McRecReduced, dummyTable, hfCandD2PrMl); } - runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } @@ -701,9 +602,7 @@ struct HfDataCreatorCharmResoToD0Reduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -718,9 +617,9 @@ struct HfDataCreatorCharmResoToD0Reduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsD0.sliceBy(candsD0PerCollisionWithMl, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, dummyTable, hfTrackNoParam, dummyTable, rowHf2PrTrkMcRecReduced, hfCandD2PrMl); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, dummyTable, hfTrackNoParam, dummyTable, rowHf2PrTrkMcRecReduced, hfCandD2PrMl); } - runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } @@ -743,9 +642,7 @@ struct HfDataCreatorCharmResoToD0Reduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -761,9 +658,9 @@ struct HfDataCreatorCharmResoToD0Reduced { auto candsDThisColl = candsD0.sliceBy(candsD0PerCollisionWithMl, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, hfTrackNoParam, rowHf2PrV0McRecReduced, rowHf2PrTrkMcRecReduced, hfCandD2PrMl); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD2Pr, hfCandV0, hfTrackNoParam, rowHf2PrV0McRecReduced, rowHf2PrTrkMcRecReduced, hfCandD2PrMl); } - runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDplusReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDplusReduced.cxx index bf307f1241d..29b2038dc7e 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDplusReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDplusReduced.cxx @@ -103,48 +103,11 @@ struct HfDataCreatorCharmResoToDplusReduced { } cfgDmesCuts; // selection V0 - struct : ConfigurableGroup { - std::string prefix = "v0s"; - Configurable deltaMassK0s{"deltaMassK0s", 0.02, "delta mass cut for K0S"}; - Configurable deltaMassLambda{"deltaMassLambda", 0.01, "delta mass cut for Lambda"}; - Configurable etaMax{"etaMax", 0.8f, "maximum eta"}; - Configurable etaMaxDau{"etaMaxDau", 5.f, "maximum eta V0 daughters"}; - Configurable trackNclusItsCut{"trackNclusItsCut", 0, "Minimum number of ITS clusters for V0 daughter"}; - Configurable trackNCrossedRowsTpc{"trackNCrossedRowsTpc", 50, "Minimum TPC crossed rows"}; - Configurable trackNsharedClusTpc{"trackNsharedClusTpc", 1000, "Maximum number of shared TPC clusters for V0 daughter"}; - Configurable trackFracMaxindableTpcCls{"trackFracMaxindableTpcCls", 0.8f, "Maximum fraction of findable TPC clusters for V0 daughter"}; - Configurable dcaDau{"dcaDau", 1.f, "DCA V0 daughters"}; - Configurable dcaMaxDauToPv{"dcaMaxDauToPv", 0.1f, "Maximum daughter's DCA to PV"}; - Configurable dcaPv{"dcaPv", 1.f, "DCA V0 to PV"}; - Configurable cosPa{"cosPa", 0.99f, "V0 CosPA"}; - Configurable radiusMin{"radiusMin", 0.9f, "Minimum v0 radius accepted"}; - Configurable nSigmaTpc{"nSigmaTpc", 4.f, "Nsigmatpc"}; - Configurable nSigmaTofPr{"nSigmaTofPr", 4.f, "N sigma TOF for protons only"}; - Configurable propagateV0toPV{"propagateV0toPV", false, "Enable or disable V0 propagation to V0"}; - } cfgV0Cuts; - + HfResoConfigV0Cuts cfgV0Cuts; // selection single tracks - struct : ConfigurableGroup { - std::string prefix = "singleTracks"; - Configurable setTrackSelections{"setTrackSelections", 2, "flag to apply track selections: 0=none; 1=global track w/o DCA selection; 2=global track; 3=only ITS quality"}; - Configurable maxEta{"maxEta", 0.8, "maximum pseudorapidity for single tracks to be paired with D mesons"}; - Configurable minPt{"minPt", 0.1, "minimum pT for single tracks to be paired with D mesons"}; - Configurable maxNsigmaTpcPi{"maxNsigmaTpcPi", -1., "maximum pion NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; - Configurable maxNsigmaTpcKa{"maxNsigmaTpcKa", -1., "maximum kaon NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; - Configurable maxNsigmaTpcPr{"maxNsigmaTpcPr", 3., "maximum proton NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; - } cfgSingleTrackCuts; - + HfResoConfigSingleTrackCuts cfgSingleTrackCuts; // QA histograms - struct : ConfigurableGroup { - std::string prefix = "qaPlots"; - Configurable applyCutsForQaHistograms{"applyCutsForQaHistograms", true, "flag to apply cuts to QA histograms"}; - Configurable cutMassDMin{"cutMassDMin", 1.83, "minimum mass for D0 and Dplus candidates"}; - Configurable cutMassDMax{"cutMassDMax", 1.92, "maximum mass for D0 and Dplus candidates"}; - Configurable cutMassK0sMin{"cutMassK0sMin", 0.485, "minimum mass for K0s candidates"}; - Configurable cutMassK0sMax{"cutMassK0sMax", 0.509, "maximum mass for K0s candidates"}; - Configurable cutMassLambdaMin{"cutMassLambdaMin", 1.11, "minimum mass for Lambda candidates"}; - Configurable cutMassLambdaMax{"cutMassLambdaMax", 1.12, "maximum mass for Lambda candidates"}; - } cfgQaPlots; + HfResoConfigQaPlots cfgQaPlots; // other configurables Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; @@ -195,55 +158,17 @@ struct HfDataCreatorCharmResoToDplusReduced { PresliceUnsorted colPerMcCollision = aod::mccollisionlabel::mcCollisionId; HistogramRegistry registry{"registry"}; + OutputObj zorroSummary{"zorroSummary"}; void init(InitContext& initContext) { // histograms - constexpr int kNBinsEvents = kNEvent; - std::string labels[kNBinsEvents]; - labels[Event::Processed] = "processed"; - labels[Event::NoDV0Selected] = "without DV0 pairs"; - labels[Event::DV0Selected] = "with DV0 pairs"; - static const AxisSpec axisEvents = {kNBinsEvents, 0.5, kNBinsEvents + 0.5, ""}; - registry.add("hEvents", "Events;;entries", HistType::kTH1D, {axisEvents}); - for (int iBin = 0; iBin < kNBinsEvents; iBin++) { - registry.get(HIST("hEvents"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); - } - - const AxisSpec axisPt{50, 0.f, 50.f, "#it{p}_{T} (GeV/#it{c})"}; - const AxisSpec axisP{100, 0.f, 10.f, "#it{p} (GeV/#it{c})"}; - const AxisSpec axisDeDx{500, 0.f, 1000.f, ""}; - const AxisSpec axisMassD0{200, 1.7f, 2.1f, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisMassDplus{200, 1.7f, 2.1f, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisMassLambda{100, 1.05f, 1.35f, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisMassKzero{100, 0.35f, 0.65f, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisDeltaMassToK{500, 0.49, 1.49, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisDeltaMassToPi{500, 0.13, 1.13, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisDeltaMassToPr{500, 0.93, 1.93, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisDeltaMassToLambda{500, 1.05, 2.05, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisMassDsj{400, 0.49f, 0.89f, ""}; // Ds1 and Ds2Star legacy - registry.add("hMassVsPtK0s", "K0^{s} candidates;#it{p}_{T} (GeV/#it{c});inv. mass (#pi^{#plus}#pi^{#minus}) (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassKzero}}); - registry.add("hMassVsPtLambda", "Lambda candidates;#it{p}_{T} (GeV/#it{c});inv. mass (p #pi^{#minus}) (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassLambda}}); - registry.add("hdEdxVsP", "Tracks;#it{p} (GeV/#it{c});d#it{E}/d#it{x};entries", {HistType::kTH2D, {axisP, axisDeDx}}); - registry.add("hMassVsPtDplusAll", "Dplus candidates (all, regardless the pairing with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDplus}}); - registry.add("hMassVsPtDplusPaired", "Dplus candidates (paired with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDplus}}); - registry.add("hMassDplusK0s", "DplusK0s candidates; m_{D^{+}K^{0}_{S}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToK}}); - registry.add("hMassDplusPi", "DplusPi candidates; m_{D^{+}#pi^{-}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPi}}); - registry.add("hMassDplusK", "DplusK candidates; m_{D^{+}#pi^{-}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToK}}); - registry.add("hMassDplusProton", "DplusProton candidates; m_{D^{+}p} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPr}}); - registry.add("hMassDplusLambda", "DplusLambda candidates; m_{D^{+}#Lambda} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToLambda}}); if (doprocessDplusV0MC || doprocessDplusTrackMC || doprocessDplusV0AndTrackMC || doprocessDplusV0MCWithMl || doprocessDplusTrackMCWithMl || doprocessDplusV0AndTrackMCWithMl) { - // MC Rec - int const nChannels = hf_decay::hf_cand_reso::DecayChannelMain::NChannelsMain; - registry.add("hMCRecCounter", "Number of Reconstructed MC Matched candidates per channel", {HistType::kTH1D, {{2 * nChannels + 1, -(nChannels + 0.5), nChannels + 0.5}}}); - registry.add("hMCRecDebug", "Debug of MC Reco", {HistType::kTH1D, {{551, -0.5, 550.5}}}); - registry.add("hMCRecOrigin", "Origin of Matched particles", {HistType::kTH1D, {{3, -0.5, 2.5}}}); - registry.add("hMCRecMassGen", "Generated inv. mass of resoncances", {HistType::kTH1D, {{2000, 1.8, 3.8}}}); - registry.add("hMCRecCharmDau", "Charm daughter flag", {HistType::kTH1D, {{57, -28.5, 28.5}}}); - // MC Gen - registry.add("hMCGenCounter", "Number of Generated particles; Decay Channel Flag; pT [GeV/c]", {HistType::kTH2D, {{17, -8.5, 8.5}, {100, 0, 50}}}); - registry.add("hMCGenOrigin", "Origin of Generated particles", {HistType::kTH1D, {{3, -0.5, 2.5}}}); + addHistograms(registry); + } else { + addHistograms(registry); } + // Configure CCDB access ccdb->setURL(ccdbUrl.value); ccdb->setCaching(true); @@ -265,7 +190,7 @@ struct HfDataCreatorCharmResoToDplusReduced { fitter.setWeightedFinalPCA(false); // init HF event selection helper - hfEvSel.init(registry); + hfEvSel.init(registry, zorroSummary); const auto& workflows = initContext.services().get(); for (const DeviceSpec& device : workflows.devices) { @@ -293,9 +218,7 @@ struct HfDataCreatorCharmResoToDplusReduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -310,7 +233,7 @@ struct HfDataCreatorCharmResoToDplusReduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, dummyTable, dummyTable, dummyTable, dummyTable); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, dummyTable, dummyTable, dummyTable, dummyTable); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -330,9 +253,7 @@ struct HfDataCreatorCharmResoToDplusReduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -347,7 +268,7 @@ struct HfDataCreatorCharmResoToDplusReduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, dummyTable, hfTrackNoParam, dummyTable, dummyTable, dummyTable); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, dummyTable, hfTrackNoParam, dummyTable, dummyTable, dummyTable); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -369,9 +290,7 @@ struct HfDataCreatorCharmResoToDplusReduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -387,7 +306,7 @@ struct HfDataCreatorCharmResoToDplusReduced { auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, hfTrackNoParam, dummyTable, dummyTable, dummyTable); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, hfTrackNoParam, dummyTable, dummyTable, dummyTable); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -409,9 +328,7 @@ struct HfDataCreatorCharmResoToDplusReduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -426,7 +343,7 @@ struct HfDataCreatorCharmResoToDplusReduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollisionWithMl, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, dummyTable, dummyTable, dummyTable, hfCandD3PrMl); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, dummyTable, dummyTable, dummyTable, hfCandD3PrMl); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -446,9 +363,7 @@ struct HfDataCreatorCharmResoToDplusReduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -463,7 +378,7 @@ struct HfDataCreatorCharmResoToDplusReduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollisionWithMl, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, dummyTable, hfTrackNoParam, dummyTable, dummyTable, hfCandD3PrMl); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, dummyTable, hfTrackNoParam, dummyTable, dummyTable, hfCandD3PrMl); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -485,9 +400,7 @@ struct HfDataCreatorCharmResoToDplusReduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -503,7 +416,7 @@ struct HfDataCreatorCharmResoToDplusReduced { auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollisionWithMl, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, hfTrackNoParam, dummyTable, dummyTable, hfCandD3PrMl); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, hfTrackNoParam, dummyTable, dummyTable, hfCandD3PrMl); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -527,9 +440,7 @@ struct HfDataCreatorCharmResoToDplusReduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -544,9 +455,9 @@ struct HfDataCreatorCharmResoToDplusReduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, dummyTable, rowHf3PrV0McRecReduced, dummyTable, dummyTable); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, dummyTable, rowHf3PrV0McRecReduced, dummyTable, dummyTable); } - runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } @@ -568,9 +479,7 @@ struct HfDataCreatorCharmResoToDplusReduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -585,9 +494,9 @@ struct HfDataCreatorCharmResoToDplusReduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, dummyTable, hfTrackNoParam, dummyTable, rowHf3PrTrkMcRecReduced, dummyTable); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, dummyTable, hfTrackNoParam, dummyTable, rowHf3PrTrkMcRecReduced, dummyTable); } - runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } @@ -611,9 +520,7 @@ struct HfDataCreatorCharmResoToDplusReduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -629,9 +536,9 @@ struct HfDataCreatorCharmResoToDplusReduced { auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, hfTrackNoParam, rowHf3PrV0McRecReduced, rowHf3PrTrkMcRecReduced, dummyTable); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, hfTrackNoParam, rowHf3PrV0McRecReduced, rowHf3PrTrkMcRecReduced, dummyTable); } - runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } @@ -654,9 +561,7 @@ struct HfDataCreatorCharmResoToDplusReduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -671,9 +576,9 @@ struct HfDataCreatorCharmResoToDplusReduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollisionWithMl, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, dummyTable, rowHf3PrV0McRecReduced, dummyTable, hfCandD3PrMl); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, dummyTable, rowHf3PrV0McRecReduced, dummyTable, hfCandD3PrMl); } - runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } @@ -695,9 +600,7 @@ struct HfDataCreatorCharmResoToDplusReduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -712,9 +615,9 @@ struct HfDataCreatorCharmResoToDplusReduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollisionWithMl, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, dummyTable, hfTrackNoParam, dummyTable, rowHf3PrTrkMcRecReduced, hfCandD3PrMl); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, dummyTable, hfTrackNoParam, dummyTable, rowHf3PrTrkMcRecReduced, hfCandD3PrMl); } - runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } @@ -737,9 +640,7 @@ struct HfDataCreatorCharmResoToDplusReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -755,9 +656,9 @@ struct HfDataCreatorCharmResoToDplusReduced { auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollisionWithMl, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, hfTrackNoParam, rowHf3PrV0McRecReduced, rowHf3PrTrkMcRecReduced, hfCandD3PrMl); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandD3Pr, hfCandV0, hfTrackNoParam, rowHf3PrV0McRecReduced, rowHf3PrTrkMcRecReduced, hfCandD3PrMl); } - runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDstarReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDstarReduced.cxx index 424fe4df603..a69c9751059 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDstarReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDstarReduced.cxx @@ -101,50 +101,12 @@ struct HfDataCreatorCharmResoToDstarReduced { std::string prefix = "dmesons"; Configurable selectionFlagDstarToD0Pi{"selectionFlagDstarToD0Pi", true, "Selection Flag for D* decay to D0 & Pi"}; } cfgDmesCuts; - // selection V0 - struct : ConfigurableGroup { - std::string prefix = "v0s"; - Configurable deltaMassK0s{"deltaMassK0s", 0.02, "delta mass cut for K0S"}; - Configurable deltaMassLambda{"deltaMassLambda", 0.01, "delta mass cut for Lambda"}; - Configurable etaMax{"etaMax", 0.8f, "maximum eta"}; - Configurable etaMaxDau{"etaMaxDau", 5.f, "maximum eta V0 daughters"}; - Configurable trackNclusItsCut{"trackNclusItsCut", 0, "Minimum number of ITS clusters for V0 daughter"}; - Configurable trackNCrossedRowsTpc{"trackNCrossedRowsTpc", 50, "Minimum TPC crossed rows"}; - Configurable trackNsharedClusTpc{"trackNsharedClusTpc", 1000, "Maximum number of shared TPC clusters for V0 daughter"}; - Configurable trackFracMaxindableTpcCls{"trackFracMaxindableTpcCls", 0.8f, "Maximum fraction of findable TPC clusters for V0 daughter"}; - Configurable dcaDau{"dcaDau", 1.f, "DCA V0 daughters"}; - Configurable dcaMaxDauToPv{"dcaMaxDauToPv", 0.1f, "Maximum daughter's DCA to PV"}; - Configurable dcaPv{"dcaPv", 1.f, "DCA V0 to PV"}; - Configurable cosPa{"cosPa", 0.99f, "V0 CosPA"}; - Configurable radiusMin{"radiusMin", 0.9f, "Minimum v0 radius accepted"}; - Configurable nSigmaTpc{"nSigmaTpc", 4.f, "Nsigmatpc"}; - Configurable nSigmaTofPr{"nSigmaTofPr", 4.f, "N sigma TOF for protons only"}; - Configurable propagateV0toPV{"propagateV0toPV", false, "Enable or disable V0 propagation to V0"}; - } cfgV0Cuts; - + HfResoConfigV0Cuts cfgV0Cuts; // selection single tracks - struct : ConfigurableGroup { - std::string prefix = "singleTracks"; - Configurable setTrackSelections{"setTrackSelections", 2, "flag to apply track selections: 0=none; 1=global track w/o DCA selection; 2=global track; 3=only ITS quality"}; - Configurable maxEta{"maxEta", 0.8, "maximum pseudorapidity for single tracks to be paired with D mesons"}; - Configurable minPt{"minPt", 0.1, "minimum pT for single tracks to be paired with D mesons"}; - Configurable maxNsigmaTpcPi{"maxNsigmaTpcPi", -1., "maximum pion NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; - Configurable maxNsigmaTpcKa{"maxNsigmaTpcKa", -1., "maximum kaon NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; - Configurable maxNsigmaTpcPr{"maxNsigmaTpcPr", 3., "maximum proton NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; - } cfgSingleTrackCuts; - + HfResoConfigSingleTrackCuts cfgSingleTrackCuts; // QA histograms - struct : ConfigurableGroup { - std::string prefix = "qaPlots"; - Configurable applyCutsForQaHistograms{"applyCutsForQaHistograms", true, "flag to apply cuts to QA histograms"}; - Configurable cutMassDstarMin{"cutMassDstarMin", 0.143, "minimum mass for Dstar candidates"}; - Configurable cutMassDstarMax{"cutMassDstarMax", 0.155, "maximum mass for Dstar candidates"}; - Configurable cutMassK0sMin{"cutMassK0sMin", 0.485, "minimum mass for K0s candidates"}; - Configurable cutMassK0sMax{"cutMassK0sMax", 0.509, "maximum mass for K0s candidates"}; - Configurable cutMassLambdaMin{"cutMassLambdaMin", 1.11, "minimum mass for Lambda candidates"}; - Configurable cutMassLambdaMax{"cutMassLambdaMax", 1.12, "maximum mass for Lambda candidates"}; - } cfgQaPlots; + HfResoConfigQaPlots cfgQaPlots; // other configurables Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; @@ -195,54 +157,17 @@ struct HfDataCreatorCharmResoToDstarReduced { PresliceUnsorted colPerMcCollision = aod::mccollisionlabel::mcCollisionId; HistogramRegistry registry{"registry"}; + OutputObj zorroSummary{"zorroSummary"}; void init(InitContext& initContext) { // histograms - constexpr int kNBinsEvents = kNEvent; - std::string labels[kNBinsEvents]; - labels[Event::Processed] = "processed"; - labels[Event::NoDV0Selected] = "without DV0 pairs"; - labels[Event::DV0Selected] = "with DV0 pairs"; - static const AxisSpec axisEvents = {kNBinsEvents, 0.5, kNBinsEvents + 0.5, ""}; - registry.add("hEvents", "Events;;entries", HistType::kTH1D, {axisEvents}); - for (int iBin = 0; iBin < kNBinsEvents; iBin++) { - registry.get(HIST("hEvents"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); - } - - const AxisSpec axisPt{50, 0.f, 50.f, "#it{p}_{T} (GeV/#it{c})"}; - const AxisSpec axisP{100, 0.f, 10.f, "#it{p} (GeV/#it{c})"}; - const AxisSpec axisDeDx{500, 0.f, 1000.f, ""}; - const AxisSpec axisMassDstar{200, 0.139f, 0.179f, "delta inv. mass (GeV/#it{c}^{2})"}; // o2-linter: disable=pdg/explicit-mass (false positive) - const AxisSpec axisMassLambda{100, 1.05f, 1.35f, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisMassKzero{100, 0.35f, 0.65f, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisDeltaMassToK{500, 0.49, 1.49, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisDeltaMassToPi{500, 0.13, 1.13, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisDeltaMassToPr{500, 0.93, 1.93, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisDeltaMassToLambda{500, 1.05, 2.05, "inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec axisMassDsj{400, 0.49f, 0.89f, ""}; // Ds1 and Ds2Star legacy - registry.add("hMassVsPtK0s", "K0^{s} candidates;#it{p}_{T} (GeV/#it{c});inv. mass (#pi^{#plus}#pi^{#minus}) (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassKzero}}); - registry.add("hMassVsPtLambda", "Lambda candidates;#it{p}_{T} (GeV/#it{c});inv. mass (p #pi^{#minus}) (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassLambda}}); - registry.add("hdEdxVsP", "Tracks;#it{p} (GeV/#it{c});d#it{E}/d#it{x};entries", {HistType::kTH2D, {axisP, axisDeDx}}); - registry.add("hMassVsPtDstarAll", "Dstar candidates (all, regardless the pairing with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDstar}}); - registry.add("hMassVsPtDstarPaired", "Dstar candidates (paired with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDstar}}); - registry.add("hMassDstarPi", "DstarPi candidates; m_{D^{*+}#pi^{-}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPi}}); - registry.add("hMassDstarK", "DstarK candidates; m_{D^{*+}#pi^{-}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToK}}); - registry.add("hMassDstarProton", "DstarProton candidates; m_{D^{*}p} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPr}}); - registry.add("hMassDstarK0s", "DstarK0s candidates; m_{D^{*}K^{0}_{S}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToK}}); - registry.add("hMassDstarLambda", "DstarLambda candidates; m_{D^{*}#Lambda} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToLambda}}); if (doprocessDstarV0MC || doprocessDstarTrackMC || doprocessDstarV0AndTrackMC || doprocessDstarV0MCWithMl || doprocessDstarTrackMCWithMl || doprocessDstarV0AndTrackMCWithMl) { - // MC Rec - int const nChannels = hf_decay::hf_cand_reso::DecayChannelMain::NChannelsMain; - registry.add("hMCRecCounter", "Number of Reconstructed MC Matched candidates per channel", {HistType::kTH1D, {{2 * nChannels + 1, -(nChannels + 0.5), nChannels + 0.5}}}); - registry.add("hMCRecDebug", "Debug of MC Reco", {HistType::kTH1D, {{551, -0.5, 550.5}}}); - registry.add("hMCRecOrigin", "Origin of Matched particles", {HistType::kTH1D, {{3, -0.5, 2.5}}}); - registry.add("hMCRecMassGen", "Generated inv. mass of resoncances", {HistType::kTH1D, {{2000, 1.8, 3.8}}}); - registry.add("hMCRecCharmDau", "Charm daughter flag", {HistType::kTH1D, {{57, -28.5, 28.5}}}); - // MC Gen - registry.add("hMCGenCounter", "Number of Generated particles; Decay Channel Flag; pT [GeV/c]", {HistType::kTH2D, {{17, -8.5, 8.5}, {100, 0, 50}}}); - registry.add("hMCGenOrigin", "Origin of Generated particles", {HistType::kTH1D, {{3, -0.5, 2.5}}}); + addHistograms(registry); + } else { + addHistograms(registry); } + // Configure CCDB access ccdb->setURL(ccdbUrl.value); ccdb->setCaching(true); @@ -264,7 +189,7 @@ struct HfDataCreatorCharmResoToDstarReduced { fitter.setWeightedFinalPCA(false); // init HF event selection helper - hfEvSel.init(registry); + hfEvSel.init(registry, zorroSummary); const auto& workflows = initContext.services().get(); for (const DeviceSpec& device : workflows.devices) { @@ -292,9 +217,7 @@ struct HfDataCreatorCharmResoToDstarReduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -310,7 +233,7 @@ struct HfDataCreatorCharmResoToDstarReduced { auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, dummyTable, dummyTable, dummyTable, dummyTable); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, dummyTable, dummyTable, dummyTable, dummyTable); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -330,9 +253,7 @@ struct HfDataCreatorCharmResoToDstarReduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -348,7 +269,7 @@ struct HfDataCreatorCharmResoToDstarReduced { auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, dummyTable, hfTrackNoParam, dummyTable, dummyTable, dummyTable); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, dummyTable, hfTrackNoParam, dummyTable, dummyTable, dummyTable); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -370,9 +291,7 @@ struct HfDataCreatorCharmResoToDstarReduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -388,7 +307,7 @@ struct HfDataCreatorCharmResoToDstarReduced { auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, hfTrackNoParam, dummyTable, dummyTable, dummyTable); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, hfTrackNoParam, dummyTable, dummyTable, dummyTable); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -410,9 +329,7 @@ struct HfDataCreatorCharmResoToDstarReduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -427,7 +344,7 @@ struct HfDataCreatorCharmResoToDstarReduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollisionWithMl, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, dummyTable, dummyTable, dummyTable, hfCandD3PrMl); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, dummyTable, dummyTable, dummyTable, hfCandD3PrMl); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -447,9 +364,7 @@ struct HfDataCreatorCharmResoToDstarReduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -464,7 +379,7 @@ struct HfDataCreatorCharmResoToDstarReduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollisionWithMl, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, dummyTable, hfTrackNoParam, dummyTable, dummyTable, hfCandD3PrMl); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, dummyTable, hfTrackNoParam, dummyTable, dummyTable, hfCandD3PrMl); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -486,9 +401,7 @@ struct HfDataCreatorCharmResoToDstarReduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -504,7 +417,7 @@ struct HfDataCreatorCharmResoToDstarReduced { auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollisionWithMl, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, hfTrackNoParam, dummyTable, dummyTable, hfCandD3PrMl); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, nullptr, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, hfTrackNoParam, dummyTable, dummyTable, hfCandD3PrMl); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -529,9 +442,7 @@ struct HfDataCreatorCharmResoToDstarReduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -546,9 +457,9 @@ struct HfDataCreatorCharmResoToDstarReduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, dummyTable, rowHfDstarV0McRecReduced, dummyTable, dummyTable); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, dummyTable, rowHfDstarV0McRecReduced, dummyTable, dummyTable); } - runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } @@ -570,9 +481,7 @@ struct HfDataCreatorCharmResoToDstarReduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -587,9 +496,9 @@ struct HfDataCreatorCharmResoToDstarReduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, dummyTable, hfTrackNoParam, dummyTable, rowHfDstarTrkMcRecReduced, dummyTable); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, dummyTable, hfTrackNoParam, dummyTable, rowHfDstarTrkMcRecReduced, dummyTable); } - runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } @@ -613,9 +522,7 @@ struct HfDataCreatorCharmResoToDstarReduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -631,9 +538,9 @@ struct HfDataCreatorCharmResoToDstarReduced { auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, hfTrackNoParam, rowHfDstarV0McRecReduced, rowHfDstarTrkMcRecReduced, dummyTable); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, hfTrackNoParam, rowHfDstarV0McRecReduced, rowHfDstarTrkMcRecReduced, dummyTable); } - runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } @@ -656,9 +563,7 @@ struct HfDataCreatorCharmResoToDstarReduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -673,9 +578,9 @@ struct HfDataCreatorCharmResoToDstarReduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollisionWithMl, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, dummyTable, rowHfDstarV0McRecReduced, dummyTable, hfCandD3PrMl); + runDataCreation(collision, candsDThisColl, v0sThisColl, nullptr, tracksIU, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, dummyTable, rowHfDstarV0McRecReduced, dummyTable, hfCandD3PrMl); } - runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } @@ -697,9 +602,7 @@ struct HfDataCreatorCharmResoToDstarReduced { int allSelColl{0}; int dummyTable{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -714,9 +617,9 @@ struct HfDataCreatorCharmResoToDstarReduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollisionWithMl, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, dummyTable, hfTrackNoParam, dummyTable, rowHfDstarTrkMcRecReduced, hfCandD3PrMl); + runDataCreation(collision, candsDThisColl, nullptr, trackIdsThisColl, tracks, tracks, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, dummyTable, hfTrackNoParam, dummyTable, rowHfDstarTrkMcRecReduced, hfCandD3PrMl); } - runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } @@ -739,9 +642,7 @@ struct HfDataCreatorCharmResoToDstarReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { continue; } @@ -757,9 +658,9 @@ struct HfDataCreatorCharmResoToDstarReduced { auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollisionWithMl, thisCollId); auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, hfTrackNoParam, rowHfDstarV0McRecReduced, rowHfDstarTrkMcRecReduced, hfCandD3PrMl); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, particlesMc, hfRejMap, bz, pdg, registry, matCorr, fitter, cfgDmesCuts, cfgSingleTrackCuts, cfgV0Cuts, cfgQaPlots, rejectPairsWithCommonDaughter, hfReducedCollision, hfCandDstar, hfCandV0, hfTrackNoParam, rowHfDstarV0McRecReduced, rowHfDstarTrkMcRecReduced, hfCandD3PrMl); } - runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); + runMcGen(particlesMc, mcParticlesPerMcCollision, collInfos, colPerMcCollision, mcCollisions, hfEvSelMc, rejectCollisionsWithBadEvSel, registry, pdg, rowHfResoMcGenReduced, bcs); // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } diff --git a/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx index 8a2b53b9380..826b7c97b95 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx @@ -725,12 +725,16 @@ struct HfDataCreatorJpsiHadReduced { TTracks const&, PParticles const& particlesMc, uint64_t const& indexCollisionMaxNumContrib, - BBCs const&) + BBCs const&, + int& zvtxColl, + int& sel8Coll, + int& zvtxAndSel8Coll, + int& zvtxAndSel8CollAndSoftTrig, + int& allSelColl) { registry.fill(HIST("hEvents"), 1 + Event::Processed); - float centrality = -1.f; - const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); if (skipRejectedCollisions && hfRejMap != 0) { return; } @@ -1125,12 +1129,10 @@ struct HfDataCreatorJpsiHadReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsJpsiThisColl = candsJpsi.sliceBy(candsJpsiPerCollision, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsJpsiThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs); + runDataCreation(collision, candsJpsiThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -1155,12 +1157,10 @@ struct HfDataCreatorJpsiHadReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsJpsiThisColl = candsJpsi.sliceBy(candsJpsiPerCollision, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsJpsiThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs); + runDataCreation(collision, candsJpsiThisColl, trackIdsThisCollision, tracks, tracks, -1, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -1187,14 +1187,12 @@ struct HfDataCreatorJpsiHadReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsJpsiThisColl = candsJpsi.sliceBy(candsJpsiPerCollision, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); auto collsSameMcCollision = collisions.sliceBy(colPerMcCollision, collision.mcCollisionId()); int64_t const indexCollisionMaxNumContrib = getIndexCollisionMaxNumContrib(collsSameMcCollision); - runDataCreation(collision, candsJpsiThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs); + runDataCreation(collision, candsJpsiThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); @@ -1224,14 +1222,12 @@ struct HfDataCreatorJpsiHadReduced { int zvtxAndSel8CollAndSoftTrig{0}; int allSelColl{0}; for (const auto& collision : collisions) { - o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsJpsiThisColl = candsJpsi.sliceBy(candsJpsiPerCollision, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); auto collsSameMcCollision = collisions.sliceBy(colPerMcCollision, collision.mcCollisionId()); int64_t const indexCollisionMaxNumContrib = getIndexCollisionMaxNumContrib(collsSameMcCollision); - runDataCreation(collision, candsJpsiThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs); + runDataCreation(collision, candsJpsiThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); diff --git a/PWGHF/D2H/Utils/utilsRedDataFormat.h b/PWGHF/D2H/Utils/utilsRedDataFormat.h index b188bee7645..d5ff2e46fec 100644 --- a/PWGHF/D2H/Utils/utilsRedDataFormat.h +++ b/PWGHF/D2H/Utils/utilsRedDataFormat.h @@ -34,10 +34,10 @@ namespace o2::hf_evsel /// \tparam centEstimator centrality estimator /// \param collision collision to test against the selection criteria template -void checkEvSel(Coll const& collision, o2::hf_evsel::HfEventSelection& hfEvSel, int& zvtxColl, int& sel8Coll, int& zvtxAndSel8Coll, int& zvtxAndSel8CollAndSoftTrig, int& allSelColl, o2::framework::Service const& ccdb, o2::framework::HistogramRegistry& registry) +o2::hf_evsel::HfCollisionRejectionMask getEvSel(Coll const& collision, o2::hf_evsel::HfEventSelection& hfEvSel, int& zvtxColl, int& sel8Coll, int& zvtxAndSel8Coll, int& zvtxAndSel8CollAndSoftTrig, int& allSelColl, o2::framework::Service const& ccdb, o2::framework::HistogramRegistry& registry) { float centrality{-1.f}; - const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const o2::hf_evsel::HfCollisionRejectionMask rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); if (!TESTBIT(rejectionMask, o2::hf_evsel::EventRejection::Trigger)) { sel8Coll++; } @@ -53,6 +53,7 @@ void checkEvSel(Coll const& collision, o2::hf_evsel::HfEventSelection& hfEvSel, if (rejectionMask == 0) { allSelColl++; } + return rejectionMask; } } // namespace o2::hf_evsel From 4f93246db35ec3b1cd27749c7c75a2be5cdff4e9 Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Mon, 1 Dec 2025 17:58:52 +0000 Subject: [PATCH 04/10] Please consider the following formatting changes --- PWGHF/D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx index a02424025cf..3b2f55af516 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx @@ -162,7 +162,7 @@ struct HfDataCreatorCharmResoToD0Reduced { void init(InitContext& initContext) { - + // histograms if (doprocessD0V0MC || doprocessD0TrackMC || doprocessD0V0AndTrackMC || doprocessD0V0MCWithMl || doprocessD0TrackMCWithMl || doprocessD0V0AndTrackMCWithMl) { addHistograms(registry); From f2d7a9dc8b5a4a45d355fd06ea431ea86dadef4d Mon Sep 17 00:00:00 2001 From: Fabrizio Grosa Date: Mon, 1 Dec 2025 19:02:40 +0100 Subject: [PATCH 05/10] Silence linter false positives --- PWGHF/D2H/Core/DataCreationCharmReso.h | 12 ++++++------ .../TableProducer/dataCreatorCharmHadPiReduced.cxx | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/PWGHF/D2H/Core/DataCreationCharmReso.h b/PWGHF/D2H/Core/DataCreationCharmReso.h index f50fc24785e..3558c85d893 100644 --- a/PWGHF/D2H/Core/DataCreationCharmReso.h +++ b/PWGHF/D2H/Core/DataCreationCharmReso.h @@ -152,12 +152,12 @@ struct HfResoConfigSingleTrackCuts : o2::framework::ConfigurableGroup { struct HfResoConfigQaPlots : o2::framework::ConfigurableGroup { std::string prefix = "qaPlots"; // JSON group name o2::framework::Configurable applyCutsForQaHistograms{"applyCutsForQaHistograms", true, "flag to apply cuts to QA histograms"}; - o2::framework::Configurable cutMassDMin{"cutMassDMin", 1.83, "minimum mass for D0 and Dplus candidates"}; - o2::framework::Configurable cutMassDMax{"cutMassDMax", 1.92, "maximum mass for D0 and Dplus candidates"}; - o2::framework::Configurable cutMassDstarMin{"cutMassDstarMin", 0.139, "minimum mass for Dstar candidates"}; - o2::framework::Configurable cutMassDstarMax{"cutMassDstarMax", 0.175, "maximum mass for Dstar candidates"}; - o2::framework::Configurable cutMassK0sMin{"cutMassK0sMin", 0.485, "minimum mass for K0s candidates"}; - o2::framework::Configurable cutMassK0sMax{"cutMassK0sMax", 0.509, "maximum mass for K0s candidates"}; + o2::framework::Configurable cutMassDMin{"cutMassDMin", 1.83, "minimum mass for D0 and Dplus candidates"}; // o2-linter: disable=pdg/explicit-mass (false positive) + o2::framework::Configurable cutMassDMax{"cutMassDMax", 1.92, "maximum mass for D0 and Dplus candidates"}; // o2-linter: disable=pdg/explicit-mass (false positive) + o2::framework::Configurable cutMassDstarMin{"cutMassDstarMin", 0.139, "minimum mass for Dstar candidates"}; // o2-linter: disable=pdg/explicit-mass (false positive) + o2::framework::Configurable cutMassDstarMax{"cutMassDstarMax", 0.175, "maximum mass for Dstar candidates"}; // o2-linter: disable=pdg/explicit-mass (false positive) + o2::framework::Configurable cutMassK0sMin{"cutMassK0sMin", 0.485, "minimum mass for K0s candidates"}; // o2-linter: disable=pdg/explicit-mass (false positive) + o2::framework::Configurable cutMassK0sMax{"cutMassK0sMax", 0.509, "maximum mass for K0s candidates"}; // o2-linter: disable=pdg/explicit-mass (false positive) o2::framework::Configurable cutMassLambdaMin{"cutMassLambdaMin", 1.11, "minimum mass for Lambda candidates"}; o2::framework::Configurable cutMassLambdaMax{"cutMassLambdaMax", 1.12, "maximum mass for Lambda candidates"}; }; diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx index 9687c440a2f..ec0c6de9a63 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx @@ -987,7 +987,7 @@ struct HfDataCreatorCharmHadPiReduced { RecoDecay::getDaughters(particlesMc.rawIteratorAt(indexRec), &arrDaughDstarIndex, std::array{0}, 1); if (arrDaughDstarIndex.size() == NDaughtersDstar) { bool matchD0{false}; - for (const int iProng : arrDaughDstarIndex) { + for (const int iProng : arrDaughDstarIndex) { // o2-linter: disable=const-ref-in-for-loop (it is preferable to copy values in case of simple variables) auto daughI = particlesMc.rawIteratorAt(iProng); if (std::abs(daughI.pdgCode()) == Pdg::kD0) { matchD0 = RecoDecay::isMatchedMCGen(particlesMc, daughI, +Pdg::kD0, std::array{+kPiPlus, -kKPlus}, true, &signD, 2); From cf80ea2e36661d1126df4ec86ebc52f7cea31fef Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Mon, 1 Dec 2025 18:03:35 +0000 Subject: [PATCH 06/10] Please consider the following formatting changes --- PWGHF/D2H/Core/DataCreationCharmReso.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/PWGHF/D2H/Core/DataCreationCharmReso.h b/PWGHF/D2H/Core/DataCreationCharmReso.h index 3558c85d893..b86dbd4ca47 100644 --- a/PWGHF/D2H/Core/DataCreationCharmReso.h +++ b/PWGHF/D2H/Core/DataCreationCharmReso.h @@ -152,12 +152,12 @@ struct HfResoConfigSingleTrackCuts : o2::framework::ConfigurableGroup { struct HfResoConfigQaPlots : o2::framework::ConfigurableGroup { std::string prefix = "qaPlots"; // JSON group name o2::framework::Configurable applyCutsForQaHistograms{"applyCutsForQaHistograms", true, "flag to apply cuts to QA histograms"}; - o2::framework::Configurable cutMassDMin{"cutMassDMin", 1.83, "minimum mass for D0 and Dplus candidates"}; // o2-linter: disable=pdg/explicit-mass (false positive) - o2::framework::Configurable cutMassDMax{"cutMassDMax", 1.92, "maximum mass for D0 and Dplus candidates"}; // o2-linter: disable=pdg/explicit-mass (false positive) + o2::framework::Configurable cutMassDMin{"cutMassDMin", 1.83, "minimum mass for D0 and Dplus candidates"}; // o2-linter: disable=pdg/explicit-mass (false positive) + o2::framework::Configurable cutMassDMax{"cutMassDMax", 1.92, "maximum mass for D0 and Dplus candidates"}; // o2-linter: disable=pdg/explicit-mass (false positive) o2::framework::Configurable cutMassDstarMin{"cutMassDstarMin", 0.139, "minimum mass for Dstar candidates"}; // o2-linter: disable=pdg/explicit-mass (false positive) o2::framework::Configurable cutMassDstarMax{"cutMassDstarMax", 0.175, "maximum mass for Dstar candidates"}; // o2-linter: disable=pdg/explicit-mass (false positive) - o2::framework::Configurable cutMassK0sMin{"cutMassK0sMin", 0.485, "minimum mass for K0s candidates"}; // o2-linter: disable=pdg/explicit-mass (false positive) - o2::framework::Configurable cutMassK0sMax{"cutMassK0sMax", 0.509, "maximum mass for K0s candidates"}; // o2-linter: disable=pdg/explicit-mass (false positive) + o2::framework::Configurable cutMassK0sMin{"cutMassK0sMin", 0.485, "minimum mass for K0s candidates"}; // o2-linter: disable=pdg/explicit-mass (false positive) + o2::framework::Configurable cutMassK0sMax{"cutMassK0sMax", 0.509, "maximum mass for K0s candidates"}; // o2-linter: disable=pdg/explicit-mass (false positive) o2::framework::Configurable cutMassLambdaMin{"cutMassLambdaMin", 1.11, "minimum mass for Lambda candidates"}; o2::framework::Configurable cutMassLambdaMax{"cutMassLambdaMax", 1.12, "maximum mass for Lambda candidates"}; }; From 4cd7bb99f533590d241e6ed2be8ad4b0d990d655 Mon Sep 17 00:00:00 2001 From: Fabrizio Grosa Date: Tue, 2 Dec 2025 14:01:54 +0100 Subject: [PATCH 07/10] Implement Vit's comments --- PWGHF/D2H/Core/DataCreationCharmReso.h | 38 +++++++++++++++----------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/PWGHF/D2H/Core/DataCreationCharmReso.h b/PWGHF/D2H/Core/DataCreationCharmReso.h index b86dbd4ca47..58e13003b75 100644 --- a/PWGHF/D2H/Core/DataCreationCharmReso.h +++ b/PWGHF/D2H/Core/DataCreationCharmReso.h @@ -87,6 +87,12 @@ enum D0Sel : uint8_t { ND0Sel }; +enum TrackSel : uint8_t { + GlobalTrack = 0, + GlobalTrackWoDca, + QualityTrackITS +}; + // Helper structs to pass D and V0 informations struct HfResoCandidateV0 { @@ -152,12 +158,12 @@ struct HfResoConfigSingleTrackCuts : o2::framework::ConfigurableGroup { struct HfResoConfigQaPlots : o2::framework::ConfigurableGroup { std::string prefix = "qaPlots"; // JSON group name o2::framework::Configurable applyCutsForQaHistograms{"applyCutsForQaHistograms", true, "flag to apply cuts to QA histograms"}; - o2::framework::Configurable cutMassDMin{"cutMassDMin", 1.83, "minimum mass for D0 and Dplus candidates"}; // o2-linter: disable=pdg/explicit-mass (false positive) - o2::framework::Configurable cutMassDMax{"cutMassDMax", 1.92, "maximum mass for D0 and Dplus candidates"}; // o2-linter: disable=pdg/explicit-mass (false positive) + o2::framework::Configurable cutMassDMin{"cutMassDMin", 1.83, "minimum mass for D0 and Dplus candidates"}; + o2::framework::Configurable cutMassDMax{"cutMassDMax", 1.92, "maximum mass for D0 and Dplus candidates"}; o2::framework::Configurable cutMassDstarMin{"cutMassDstarMin", 0.139, "minimum mass for Dstar candidates"}; // o2-linter: disable=pdg/explicit-mass (false positive) - o2::framework::Configurable cutMassDstarMax{"cutMassDstarMax", 0.175, "maximum mass for Dstar candidates"}; // o2-linter: disable=pdg/explicit-mass (false positive) - o2::framework::Configurable cutMassK0sMin{"cutMassK0sMin", 0.485, "minimum mass for K0s candidates"}; // o2-linter: disable=pdg/explicit-mass (false positive) - o2::framework::Configurable cutMassK0sMax{"cutMassK0sMax", 0.509, "maximum mass for K0s candidates"}; // o2-linter: disable=pdg/explicit-mass (false positive) + o2::framework::Configurable cutMassDstarMax{"cutMassDstarMax", 0.175, "maximum mass for Dstar candidates"}; + o2::framework::Configurable cutMassK0sMin{"cutMassK0sMin", 0.485, "minimum mass for K0s candidates"}; + o2::framework::Configurable cutMassK0sMax{"cutMassK0sMax", 0.509, "maximum mass for K0s candidates"}; o2::framework::Configurable cutMassLambdaMin{"cutMassLambdaMin", 1.11, "minimum mass for Lambda candidates"}; o2::framework::Configurable cutMassLambdaMax{"cutMassLambdaMax", 1.12, "maximum mass for Lambda candidates"}; }; @@ -167,14 +173,14 @@ struct HfResoConfigQaPlots : o2::framework::ConfigurableGroup { template void addHistograms(o2::framework::HistogramRegistry& registry) { - constexpr uint8_t kNBinsEvents = EventType::NEventType; - std::string labels[kNBinsEvents]; + constexpr uint8_t NumBinsEvents = EventType::NEventType; + std::string labels[NumBinsEvents]; labels[EventType::Processed] = "processed"; labels[EventType::NoDV0Selected] = "without DV0 pairs"; labels[EventType::DV0Selected] = "with DV0 pairs"; - const o2::framework::AxisSpec axisEvents = {kNBinsEvents, 0.5, kNBinsEvents + 0.5, ""}; + const o2::framework::AxisSpec axisEvents = {NumBinsEvents, 0.5, NumBinsEvents + 0.5, ""}; registry.add("hEvents", "Events;;entries", o2::framework::HistType::kTH1D, {axisEvents}); - for (auto iBin{0u}; iBin < kNBinsEvents; iBin++) { + for (auto iBin{0u}; iBin < NumBinsEvents; iBin++) { registry.get(HIST("hEvents"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); } @@ -275,7 +281,7 @@ bool selectV0Daughter(Tr const& track, const std::array& dDaughtersIds, /// \return alphaAP float alphaAP(std::array const& momV0, std::array const& momDau0, std::array const& momDau1) { - float const momTot = std::sqrt(std::pow(momV0[0], 2.) + std::pow(momV0[1], 2.) + std::pow(momV0[2], 2.)); + float const momTot = std::hypot(momV0[0], momV0[1], momV0[2]); float const lQlPos = (momDau0[0] * momV0[0] + momDau0[1] * momV0[1] + momDau0[2] * momV0[2]) / momTot; float const lQlNeg = (momDau1[0] * momV0[0] + momDau1[1] * momV0[1] + momDau1[2] * momV0[2]) / momTot; return (lQlPos - lQlNeg) / (lQlPos + lQlNeg); @@ -294,7 +300,7 @@ float alphaAP(std::array const& momV0, std::array const& mom /// \return the DCA float calculateDCAStraightToPV(float x, float y, float z, float px, float py, float pz, float pvX, float pvY, float pvZ) { - return std::sqrt((std::pow((pvY - y) * pz - (pvZ - z) * py, 2) + std::pow((pvX - x) * pz - (pvZ - z) * px, 2) + std::pow((pvX - x) * py - (pvY - y) * px, 2)) / (px * px + py * py + pz * pz)); + return std::hypot((pvY - y) * pz - (pvZ - z) * py, (pvX - x) * pz - (pvZ - z) * px, (pvX - x) * py - (pvY - y) * px) / (px * px + py * py + pz * pz); } /// Basic selection of V0 candidates @@ -440,17 +446,17 @@ bool isTrackSelected(const Tr& track, const std::array& dDaughtersIds, c return false; } switch (cfgSingleTrackCuts.setTrackSelections.value) { - case 1: - if (!track.isGlobalTrackWoDCA()) { + case TrackSel::GlobalTrack: + if (!track.isGlobalTrack()) { return false; } break; - case 2: - if (!track.isGlobalTrack()) { + case TrackSel::GlobalTrackWoDca: + if (!track.isGlobalTrackWoDCA()) { return false; } break; - case 3: + case TrackSel::QualityTrackITS: if (!track.isQualityTrackITS()) { return false; } From 7ea0caff08cabf5d3692b90d21a593e6a6e02c10 Mon Sep 17 00:00:00 2001 From: Fabrizio Grosa Date: Tue, 2 Dec 2025 14:37:15 +0100 Subject: [PATCH 08/10] Make linter happy also for warnings --- PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx | 8 ++++---- .../D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx | 2 +- .../TableProducer/dataCreatorCharmResoToDplusReduced.cxx | 2 +- PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx index ec0c6de9a63..7b0d5dcd524 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx @@ -340,14 +340,14 @@ struct HfDataCreatorCharmHadPiReduced { runNumber = 0; // histograms - constexpr int kNBinsEvents = kNEvent; - std::string labels[kNBinsEvents]; + constexpr int NumBinsEvents = kNEvent; + std::string labels[NumBinsEvents]; labels[Event::Processed] = "processed"; labels[Event::NoCharmHadPiSelected] = "without CharmHad-Pi pairs"; labels[Event::CharmHadPiSelected] = "with CharmHad-Pi pairs"; - static const AxisSpec axisEvents = {kNBinsEvents, 0.5, kNBinsEvents + 0.5, ""}; + static const AxisSpec axisEvents = {NumBinsEvents, 0.5, NumBinsEvents + 0.5, ""}; registry.add("hEvents", "Events;;entries", HistType::kTH1F, {axisEvents}); - for (int iBin = 0; iBin < kNBinsEvents; iBin++) { + for (int iBin = 0; iBin < NumBinsEvents; iBin++) { registry.get(HIST("hEvents"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); } diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx index 3b2f55af516..d317ac34d84 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file dataCreatorCharmResoReduced.cxx +/// \file dataCreatorCharmResoToD0Reduced.cxx /// \brief Creation of D0 V0 and D0 track pairs /// /// \author Luca Aglietta , UniTO Turin diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDplusReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDplusReduced.cxx index 29b2038dc7e..7e333353ed3 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDplusReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDplusReduced.cxx @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file dataCreatorCharmResoReduced.cxx +/// \file dataCreatorCharmResoToDplusReduced.cxx /// \brief Creation of D+ V0 and D+ track pairs /// /// \author Luca Aglietta , UniTO Turin diff --git a/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx index 826b7c97b95..1acf613cd60 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx @@ -264,14 +264,14 @@ struct HfDataCreatorJpsiHadReduced { registry.get(HIST("hSelectionsJpsi"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); } - constexpr int kNBinsEvents = NEvent; - std::string labelsEvents[kNBinsEvents]; + constexpr int NumBinsEvents = NEvent; + std::string labelsEvents[NumBinsEvents]; labelsEvents[Event::Processed] = "processed"; labelsEvents[Event::NoCharmHadPiSelected] = "without CharmHad-Pi pairs"; labelsEvents[Event::CharmHadPiSelected] = "with CharmHad-Pi pairs"; - static const AxisSpec axisEvents = {kNBinsEvents, 0.5, kNBinsEvents + 0.5, ""}; + static const AxisSpec axisEvents = {NumBinsEvents, 0.5, NumBinsEvents + 0.5, ""}; registry.add("hEvents", "Events;;entries", HistType::kTH1F, {axisEvents}); - for (int iBin = 0; iBin < kNBinsEvents; iBin++) { + for (int iBin = 0; iBin < NumBinsEvents; iBin++) { registry.get(HIST("hEvents"))->GetXaxis()->SetBinLabel(iBin + 1, labelsEvents[iBin].data()); } From 27b13d0d9a839cc1a60f7e3b1bc94a33572804f7 Mon Sep 17 00:00:00 2001 From: Fabrizio Grosa Date: Tue, 2 Dec 2025 14:38:33 +0100 Subject: [PATCH 09/10] Make linter happy also for warnings --- PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx index 1acf613cd60..83f20beee84 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx @@ -252,15 +252,15 @@ struct HfDataCreatorJpsiHadReduced { } // Set up the histogram registry - constexpr int kNBinsSelections = 2 + aod::SelectionStep::RecoPID; - std::string labels[kNBinsSelections]; + constexpr int NumBinsEvents = 2 + aod::SelectionStep::RecoPID; + std::string labels[NumBinsEvents]; labels[0] = "No selection"; labels[1 + aod::SelectionStep::RecoSkims] = "Skims selection"; labels[1 + aod::SelectionStep::RecoTopol] = "Skims & Topological selections"; labels[1 + aod::SelectionStep::RecoPID] = "Skims & Topological & PID selections"; - static const AxisSpec axisSelections = {kNBinsSelections, 0.5, kNBinsSelections + 0.5, ""}; + static const AxisSpec axisSelections = {NumBinsEvents, 0.5, NumBinsEvents + 0.5, ""}; registry.add("hSelectionsJpsi", "J/Psi selection;;#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {axisSelections, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - for (int iBin = 0; iBin < kNBinsSelections; ++iBin) { + for (int iBin = 0; iBin < NumBinsEvents; ++iBin) { registry.get(HIST("hSelectionsJpsi"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); } From bc1cc43c92e7dc7570e8ce1377e592e6a80e39ab Mon Sep 17 00:00:00 2001 From: Fabrizio Grosa Date: Tue, 2 Dec 2025 16:23:54 +0100 Subject: [PATCH 10/10] Fix typo --- PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx index 83f20beee84..c730becfef8 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx @@ -252,15 +252,15 @@ struct HfDataCreatorJpsiHadReduced { } // Set up the histogram registry - constexpr int NumBinsEvents = 2 + aod::SelectionStep::RecoPID; - std::string labels[NumBinsEvents]; + constexpr int NumBinsSelections = 2 + aod::SelectionStep::RecoPID; + std::string labels[NumBinsSelections]; labels[0] = "No selection"; labels[1 + aod::SelectionStep::RecoSkims] = "Skims selection"; labels[1 + aod::SelectionStep::RecoTopol] = "Skims & Topological selections"; labels[1 + aod::SelectionStep::RecoPID] = "Skims & Topological & PID selections"; - static const AxisSpec axisSelections = {NumBinsEvents, 0.5, NumBinsEvents + 0.5, ""}; + static const AxisSpec axisSelections = {NumBinsSelections, 0.5, NumBinsSelections + 0.5, ""}; registry.add("hSelectionsJpsi", "J/Psi selection;;#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {axisSelections, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - for (int iBin = 0; iBin < NumBinsEvents; ++iBin) { + for (int iBin = 0; iBin < NumBinsSelections; ++iBin) { registry.get(HIST("hSelectionsJpsi"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); }