diff --git a/PWGHF/D2H/Core/DataCreationCharmReso.h b/PWGHF/D2H/Core/DataCreationCharmReso.h new file mode 100644 index 00000000000..58e13003b75 --- /dev/null +++ b/PWGHF/D2H/Core/DataCreationCharmReso.h @@ -0,0 +1,1673 @@ +// 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 DataCreationCharmReso.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/utilsEvSelHf.h" +#include "PWGHF/Utils/utilsMcMatching.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 +#include + +namespace o2::analysis +{ +namespace hf_charm_reso +{ + +// event types +enum EventType : uint8_t { + Processed = 0, + NoDV0Selected, + DV0Selected, + NEventType +}; + +enum BachelorType : uint8_t { + K0s = 0, + Lambda, + AntiLambda, + Track, + NBachelorTypes +}; + +enum DMesonType : uint8_t { + Dplus = 1, + Dstar, + D0, + NDMesonType +}; + +enum PairingType : uint8_t { + V0Only, + TrackOnly, + V0AndTrack, + NPairingType +}; + +enum D0Sel : uint8_t { + SelectedD0 = 0, + SelectedD0Bar, + ND0Sel +}; + +enum TrackSel : uint8_t { + GlobalTrack = 0, + GlobalTrackWoDca, + QualityTrackITS +}; + +// Helper structs to pass D and V0 informations + +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 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-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"}; +}; + +/// Helper method to add histograms to the registry +/// \param registry is the histogram registry +template +void addHistograms(o2::framework::HistogramRegistry& registry) +{ + 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 = {NumBinsEvents, 0.5, NumBinsEvents + 0.5, ""}; + registry.add("hEvents", "Events;;entries", o2::framework::HistType::kTH1D, {axisEvents}); + for (auto iBin{0u}; iBin < NumBinsEvents; 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 +/// \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::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); +} + +/// 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::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 +/// \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, HfResoCandidateV0& 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 TrackSel::GlobalTrack: + if (!track.isGlobalTrack()) { + return false; + } + break; + case TrackSel::GlobalTrackWoDca: + if (!track.isGlobalTrackWoDCA()) { + return false; + } + break; + case TrackSel::QualityTrackITS: + 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 = {pdg->Mass(dau1.pdgCode()), 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 == DMesonType::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 == DMesonType::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 == DMesonType::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 == DMesonType::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 == DMesonType::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 == DMesonType::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 = 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 + 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{}; + HfResoVarContainer varUtils; + varUtils.ptD = candD.pt(); + if constexpr (DType == DMesonType::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 == DMesonType::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 == DMesonType::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 == DMesonType::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}; + HfResoCandidateV0 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 == 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}); + } 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 == 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 || + (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 == 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}); + } 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 == 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 || + (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 == 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 { + 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 == DMesonType::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 == DMesonType::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 == DMesonType::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 == DMesonType::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 == DMesonType::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 == DMesonType::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 == DMesonType::Dstar) { + registry.fill(HIST("hMassVsPtDstarPaired"), candD.pt(), varUtils.invMassD - varUtils.invMassD0); + } else if constexpr (DType == DMesonType::Dplus) { + registry.fill(HIST("hMassVsPtDplusPaired"), candD.pt(), varUtils.invMassD); + } else if constexpr (DType == DMesonType::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 + EventType::Processed); + if (!fillHfReducedCollision) { + registry.fill(HIST("hEvents"), 1 + EventType::NoDV0Selected); + return; + } + 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 + +// 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 = (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()); + // 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 == DMesonType::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 == DMesonType::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 == DMesonType::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/dataCreatorCharmHadPiReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx index a9d569cb32c..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()); } @@ -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); @@ -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/dataCreatorCharmResoReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmResoReduced.cxx deleted file mode 100644 index 5dd72be0c9e..00000000000 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmResoReduced.cxx +++ /dev/null @@ -1,2723 +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/ZorroSummary.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"}; - 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}}); - - 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, zorroSummary); - - 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..d317ac34d84 --- /dev/null +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToD0Reduced.cxx @@ -0,0 +1,673 @@ +// 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 dataCreatorCharmResoToD0Reduced.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 + HfResoConfigV0Cuts cfgV0Cuts; + // selection single tracks + HfResoConfigSingleTrackCuts cfgSingleTrackCuts; + // QA histograms + 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)"}; + 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"}; + OutputObj zorroSummary{"zorroSummary"}; + + void init(InitContext& initContext) + { + + // histograms + if (doprocessD0V0MC || doprocessD0TrackMC || doprocessD0V0AndTrackMC || doprocessD0V0MCWithMl || doprocessD0TrackMCWithMl || doprocessD0V0AndTrackMCWithMl) { + addHistograms(registry); + } else { + addHistograms(registry); + } + + // 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, zorroSummary); + + 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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..7e333353ed3 --- /dev/null +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDplusReduced.cxx @@ -0,0 +1,671 @@ +// 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 dataCreatorCharmResoToDplusReduced.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 + HfResoConfigV0Cuts cfgV0Cuts; + // selection single tracks + HfResoConfigSingleTrackCuts cfgSingleTrackCuts; + // QA histograms + 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)"}; + 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"}; + OutputObj zorroSummary{"zorroSummary"}; + + void init(InitContext& initContext) + { + // histograms + if (doprocessDplusV0MC || doprocessDplusTrackMC || doprocessDplusV0AndTrackMC || doprocessDplusV0MCWithMl || doprocessDplusTrackMCWithMl || doprocessDplusV0AndTrackMCWithMl) { + addHistograms(registry); + } else { + addHistograms(registry); + } + + // 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, zorroSummary); + + 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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..a69c9751059 --- /dev/null +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmResoToDstarReduced.cxx @@ -0,0 +1,673 @@ +// 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 + HfResoConfigV0Cuts cfgV0Cuts; + // selection single tracks + HfResoConfigSingleTrackCuts cfgSingleTrackCuts; + // QA histograms + 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)"}; + 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"}; + OutputObj zorroSummary{"zorroSummary"}; + + void init(InitContext& initContext) + { + // histograms + if (doprocessDstarV0MC || doprocessDstarTrackMC || doprocessDstarV0AndTrackMC || doprocessDstarV0MCWithMl || doprocessDstarTrackMCWithMl || doprocessDstarV0AndTrackMCWithMl) { + addHistograms(registry); + } else { + addHistograms(registry); + } + + // 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, zorroSummary); + + 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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) { + const auto hfRejMap = o2::hf_evsel::getEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, 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)}; +} diff --git a/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx index 8a2b53b9380..c730becfef8 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx @@ -252,26 +252,26 @@ struct HfDataCreatorJpsiHadReduced { } // Set up the histogram registry - constexpr int kNBinsSelections = 2 + aod::SelectionStep::RecoPID; - std::string labels[kNBinsSelections]; + 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 = {kNBinsSelections, 0.5, kNBinsSelections + 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 < kNBinsSelections; ++iBin) { + for (int iBin = 0; iBin < NumBinsSelections; ++iBin) { 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()); } @@ -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