From 86db460b0feedc19288d57922c9d6d52c8a58523 Mon Sep 17 00:00:00 2001 From: Henrik Fribert Date: Mon, 18 May 2026 13:05:11 +0200 Subject: [PATCH] TrackerPID improved plotting and LUT handling --- .../TableProducer/OTF/onTheFlyTrackerPid.cxx | 265 +++++++++++------- 1 file changed, 164 insertions(+), 101 deletions(-) diff --git a/ALICE3/TableProducer/OTF/onTheFlyTrackerPid.cxx b/ALICE3/TableProducer/OTF/onTheFlyTrackerPid.cxx index fdb0e72afe2..7fbcc3e234b 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTrackerPid.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTrackerPid.cxx @@ -87,32 +87,27 @@ static constexpr size_t kMaxValidHitsForTruncation56 = 3; static constexpr size_t kMaxValidHitsForTruncation34 = 2; static constexpr size_t kMaxValidHitsForTruncation12 = 1; -// Constants for LUT binning -// To do: Include in LUT header or similar -static constexpr int kLUTEtaBins = 50; -static constexpr float kLUTEtaMin = -2.5f; -static constexpr float kLUTEtaMax = 2.5f; -static constexpr int kLUTPtBins = 500; -static constexpr float kLUTPtMin = 0.0f; -static constexpr float kLUTPtMax = 10.0f; - class ToTLUT { public: - explicit ToTLUT(int maxLayers, float analysisEtaMinVal = 0.0f, float analysisEtaMaxVal = 1.0f, float analysisPtMinVal = 0.0f, float analysisPtMaxVal = 10.0f) + explicit ToTLUT(int maxLayers, + int etaBins, float etaMin, float etaMax, + int pBins, float pMin, float pMax, + float analysisEtaMinVal = 0.0f, float analysisEtaMaxVal = 1.0f, + float analysisPMinVal = 0.0f, float analysisPMaxVal = 10.0f) : mMaxLayers(maxLayers), mAnalysisEtaMin(analysisEtaMinVal), mAnalysisEtaMax(analysisEtaMaxVal), - mAnalysisPtMin(analysisPtMinVal), - mAnalysisPtMax(analysisPtMaxVal), - mEtaBins(kLUTEtaBins), - mEtaMin(kLUTEtaMin), - mEtaMax(kLUTEtaMax), - mPtBins(kLUTPtBins), - mPtMin(kLUTPtMin), - mPtMax(kLUTPtMax), - mEtaBinWidth((kLUTEtaMax - kLUTEtaMin) / kLUTEtaBins), - mPtBinWidth((kLUTPtMax - kLUTPtMin) / kLUTPtBins) + mAnalysisPMin(analysisPMinVal), + mAnalysisPMax(analysisPMaxVal), + mEtaBins(etaBins), + mEtaMin(etaMin), + mEtaMax(etaMax), + mPBins(pBins), + mPMin(pMin), + mPMax(pMax), + mEtaBinWidth((etaMax - etaMin) / etaBins), + mPBinWidth((pMax - pMin) / pBins) { mPdgToIndexMap.reserve(10); mIndexToPdgMap.reserve(10); @@ -174,7 +169,7 @@ class ToTLUT mPdgToIndexMap[pdg] = currentPdgIdx; mIndexToPdgMap.push_back(pdg); - size_t totalSize = (currentPdgIdx + 1) * mMaxLayers * mEtaBins * mPtBins; + size_t totalSize = (currentPdgIdx + 1) * mMaxLayers * mEtaBins * mPBins; if (mLUTHistogramFlat.size() < totalSize) { mLUTHistogramFlat.resize(totalSize, nullptr); } @@ -193,28 +188,30 @@ class ToTLUT continue; } - for (int ptBin = 0; ptBin < mPtBins; ++ptBin) { - float ptMinBin = mPtMin + ptBin * mPtBinWidth; - float ptMaxBin = ptMinBin + mPtBinWidth; - float ptCenter = (ptMinBin + ptMaxBin) / 2.0f; + for (int pBin = 0; pBin < mPBins; ++pBin) { + float pMinBin = mPMin + pBin * mPBinWidth; + float pMaxBin = pMinBin + mPBinWidth; + float pCenter = (pMinBin + pMaxBin) / 2.0f; - if (ptCenter < mAnalysisPtMin || ptCenter >= mAnalysisPtMax) { + if (pCenter < mAnalysisPMin || pCenter >= mAnalysisPMax) { continue; } - TString histName = Form("tot_%d_barrel%d_eta%.2f-%.2f_pt%.2f-%.2f", pdg, layer, etaMinBin, etaMaxBin, ptMinBin, ptMaxBin); + TString histName = Form("tot_%d_barrel%d_eta%.2f-%.2f_p%.2f-%.2f", pdg, layer, etaMinBin, etaMaxBin, pMinBin, pMaxBin); TH1F* histFromFile = dynamic_cast(f->Get(histName)); if (histFromFile) { TH1F* clonedHist = static_cast(histFromFile->Clone()); clonedHist->SetDirectory(nullptr); - size_t flatIdx = getFlatIndex(currentPdgIdx, layer, etaBin, ptBin); + size_t flatIdx = getFlatIndex(currentPdgIdx, layer, etaBin, pBin); mLUTHistogramFlat[flatIdx] = clonedHist; } else { - size_t flatIdx = getFlatIndex(currentPdgIdx, layer, etaBin, ptBin); + size_t flatIdx = getFlatIndex(currentPdgIdx, layer, etaBin, pBin); mLUTHistogramFlat[flatIdx] = nullptr; - success = false; + if (layer >= kMinLayerForTruncation) { + success = false; + } } } } @@ -225,14 +222,14 @@ class ToTLUT return success; } - TH1F* getHistogramForSampling(int pdgIdx, int layer, int etaBin, int ptBin) const + TH1F* getHistogramForSampling(int pdgIdx, int layer, int etaBin, int pBin) const { if (pdgIdx < 0 || static_cast(pdgIdx) >= getNumPdgTypes() || layer < 0 || layer >= mMaxLayers || - etaBin < 0 || etaBin >= mEtaBins || ptBin < 0 || ptBin >= mPtBins) { + etaBin < 0 || etaBin >= mEtaBins || pBin < 0 || pBin >= mPBins) { return nullptr; } - size_t flatIdx = getFlatIndex(pdgIdx, layer, etaBin, ptBin); + size_t flatIdx = getFlatIndex(pdgIdx, layer, etaBin, pBin); return (flatIdx < mLUTHistogramFlat.size()) ? mLUTHistogramFlat[flatIdx] : nullptr; } @@ -251,15 +248,15 @@ class ToTLUT return std::min(static_cast((clampedEta - mEtaMin) / mEtaBinWidth), mEtaBins - 1); } - inline int getPtBin(float pt) const + inline int getPBin(float p) const { - const float clampedPt = std::max(mPtMin, std::min(pt, mPtMax - 1e-6f)); - return std::min(static_cast((clampedPt - mPtMin) / mPtBinWidth), mPtBins - 1); + const float clampedP = std::max(mPMin, std::min(p, mPMax - 1e-6f)); + return std::min(static_cast((clampedP - mPMin) / mPBinWidth), mPBins - 1); } - inline size_t getFlatIndex(int pdgIdx, int layer, int etaBin, int ptBin) const + inline size_t getFlatIndex(int pdgIdx, int layer, int etaBin, int pBin) const { - return ((pdgIdx * mMaxLayers + layer) * mEtaBins + etaBin) * mPtBins + ptBin; + return ((pdgIdx * mMaxLayers + layer) * mEtaBins + etaBin) * mPBins + pBin; } size_t getNumPdgTypes() const @@ -275,17 +272,17 @@ class ToTLUT int mMaxLayers; float mAnalysisEtaMin; float mAnalysisEtaMax; - float mAnalysisPtMin; - float mAnalysisPtMax; + float mAnalysisPMin; + float mAnalysisPMax; int mEtaBins; float mEtaMin; float mEtaMax; - int mPtBins; - float mPtMin; - float mPtMax; + int mPBins; + float mPMin; + float mPMax; float mEtaBinWidth; - float mPtBinWidth; + float mPBinWidth; private: o2::ccdb::BasicCCDBManager* mCcdbManager = nullptr; @@ -295,6 +292,8 @@ static constexpr int kNumHypothesisParticles = 9; std::array, kNumHypothesisParticles>, kNumHypothesisParticles> h2dBarrelNsigmaTrue; std::array, kNumHypothesisParticles> h2dHitsPerTrackVsP; std::array, kNumHypothesisParticles> h2dToTvsPperParticle; +std::array, kNumHypothesisParticles> h2dHitsPerTrackVsPLin; +std::array, kNumHypothesisParticles> h2dToTvsPperParticleLin; struct OnTheFlyTrackerPid { @@ -393,22 +392,42 @@ struct OnTheFlyTrackerPid { HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - Configurable lutTotEl{"lutTotEl", "ccdb:Users/h/hfribert/ToT_LUTs/PDG_11", "ToT LUT for electrons"}; - Configurable lutTotMu{"lutTotMu", "ccdb:Users/h/hfribert/ToT_LUTs/PDG_13", "ToT LUT for muons"}; - Configurable lutTotPi{"lutTotPi", "ccdb:Users/h/hfribert/ToT_LUTs/PDG_211", "ToT LUT for pions"}; - Configurable lutTotKa{"lutTotKa", "ccdb:Users/h/hfribert/ToT_LUTs/PDG_321", "ToT LUT for kaons"}; - Configurable lutTotPr{"lutTotPr", "ccdb:Users/h/hfribert/ToT_LUTs/PDG_2212", "ToT LUT for protons"}; - Configurable lutTotDe{"lutTotDe", "ccdb:Users/h/hfribert/ToT_LUTs/PDG_1000010020", "ToT LUT for deuteron"}; - Configurable lutTotTr{"lutTotTr", "ccdb:Users/h/hfribert/ToT_LUTs/PDG_1000010030", "ToT LUT for triton"}; - Configurable lutTotHe{"lutTotHe", "ccdb:Users/h/hfribert/ToT_LUTs/PDG_1000020030", "ToT LUT for helium-3"}; - Configurable lutTotAl{"lutTotAl", "ccdb:Users/h/hfribert/ToT_LUTs/PDG_1000020040", "ToT LUT for alphas"}; + Configurable lutTotEl{"lutTotEl", "ccdb:Users/h/hfribert/ToT_LUTs_ALMIRA/Scale1/PDG_11", "ToT LUT for electrons"}; + Configurable lutTotMu{"lutTotMu", "ccdb:Users/h/hfribert/ToT_LUTs_ALMIRA/Scale1/PDG_13", "ToT LUT for muons"}; + Configurable lutTotPi{"lutTotPi", "ccdb:Users/h/hfribert/ToT_LUTs_ALMIRA/Scale1/PDG_211", "ToT LUT for pions"}; + Configurable lutTotKa{"lutTotKa", "ccdb:Users/h/hfribert/ToT_LUTs_ALMIRA/Scale1/PDG_321", "ToT LUT for kaons"}; + Configurable lutTotPr{"lutTotPr", "ccdb:Users/h/hfribert/ToT_LUTs_ALMIRA/Scale1/PDG_2212", "ToT LUT for protons"}; + Configurable lutTotDe{"lutTotDe", "ccdb:Users/h/hfribert/ToT_LUTs_ALMIRA/Scale1/PDG_1000010020", "ToT LUT for deuteron"}; + Configurable lutTotTr{"lutTotTr", "ccdb:Users/h/hfribert/ToT_LUTs_ALMIRA/Scale1/PDG_1000010030", "ToT LUT for triton"}; + Configurable lutTotHe{"lutTotHe", "ccdb:Users/h/hfribert/ToT_LUTs_ALMIRA/Scale1/PDG_1000020030", "ToT LUT for helium-3"}; + Configurable lutTotAl{"lutTotAl", "ccdb:Users/h/hfribert/ToT_LUTs_ALMIRA/Scale1/PDG_1000020040", "ToT LUT for alphas"}; Configurable maxBarrelLayers{"maxBarrelLayers", 11, "Maximum number of barrel layers"}; Configurable numLogBins{"numLogBins", 200, "Number of logarithmic momentum bins"}; Configurable analysisEtaMin{"analysisEtaMin", 0.0f, "Minimum |eta| for LUT loading optimization"}; Configurable analysisEtaMax{"analysisEtaMax", 1.0f, "Maximum |eta| for LUT loading optimization"}; - Configurable analysisPtMin{"analysisPtMin", 0.0f, "Minimum pT (GeV/c) for LUT loading optimization"}; - Configurable analysisPtMax{"analysisPtMax", 10.0f, "Maximum pT (GeV/c) for LUT loading optimization"}; + Configurable analysisPMin{"analysisPMin", 0.0f, "Minimum |p| (GeV/c) for LUT loading optimization"}; + Configurable analysisPMax{"analysisPMax", 10.0f, "Maximum |p| (GeV/c) for LUT loading optimization"}; + + // LUT binning (has to match LUTs) + Configurable lutEtaBins{"lutEtaBins", 50, "Number of eta bins in the LUT"}; + Configurable lutEtaMin{"lutEtaMin", -2.5f, "Minimum eta in the LUT"}; + Configurable lutEtaMax{"lutEtaMax", 2.5f, "Maximum eta in the LUT"}; + Configurable lutPBins{"lutPBins", 500, "Number of momentum bins in the LUT"}; + Configurable lutPMin{"lutPMin", 0.0f, "Minimum momentum in the LUT (GeV/c)"}; + Configurable lutPMax{"lutPMax", 10.0f, "Maximum momentum in the LUT (GeV/c)"}; + + // ToT histogram axis + Configurable totHistBins{"totHistBins", 600, "Number of bins on the ToT axis"}; + Configurable totHistMin{"totHistMin", 0.0f, "Minimum of the ToT axis (#mus/10#mum)"}; + Configurable totHistMax{"totHistMax", 10.0f, "Maximum of the ToT axis (#mus/10#mum)"}; + + // Momentum axis binning choice + Configurable enableLogPBins{"enableLogPBins", true, "Enable logarithmic momentum binning for ToT vs p histograms"}; + Configurable enableLinearPBins{"enableLinearPBins", false, "Enable linear momentum binning for ToT vs p histograms"}; + Configurable numLinearBins{"numLinearBins", 500, "Number of linear momentum bins"}; + Configurable linearPMin{"linearPMin", 0.0f, "Minimum momentum for linear-binned histograms (GeV/c)"}; + Configurable linearPMax{"linearPMax", 10.0f, "Maximum momentum for linear-binned histograms (GeV/c)"}; std::vector mLogBins; @@ -442,7 +461,11 @@ struct OnTheFlyTrackerPid { << "). Please adjust maxBarrelLayers."; } - mToTLUT = std::make_unique(maxBarrelLayers.value, analysisEtaMin.value, analysisEtaMax.value, analysisPtMin.value, analysisPtMax.value); + mToTLUT = std::make_unique(maxBarrelLayers.value, + lutEtaBins.value, lutEtaMin.value, lutEtaMax.value, + lutPBins.value, lutPMin.value, lutPMax.value, + analysisEtaMin.value, analysisEtaMax.value, + analysisPMin.value, analysisPMax.value); mToTLUT->setCcdbManager(ccdb.operator->()); @@ -472,17 +495,30 @@ struct OnTheFlyTrackerPid { mLogBins.push_back(std::pow(10, logMin + i * dLog)); } - const AxisSpec axisMomentum{mLogBins, "#it{p/z} (GeV/#it{c})"}; - const AxisSpec axisToT{600, 0., 300., "ToT (#mus/10#mum)"}; + const AxisSpec axisToT{totHistBins.value, static_cast(totHistMin.value), static_cast(totHistMax.value), "ToT (#mus/10#mum)"}; const AxisSpec axisNsigma{200, -10., 10., "N#sigma"}; const AxisSpec axisLayer{maxBarrelLayers.value, -0.5, static_cast(maxBarrelLayers.value) - 0.5, "Layer"}; const AxisSpec axisHitsPerTrack{maxBarrelLayers.value + 1, -0.5, static_cast(maxBarrelLayers.value) + 0.5, "# Hits per track"}; - histos.add("hToTvsP", "ToT vs #it{p/z}; #it{p/z} (GeV/#it{c}); ToT (#mus/10#mum)", kTH2F, {axisMomentum, axisToT}); - histos.add("hToTvsPt", "ToT vs #it{p}; #it{p} (GeV/#it{c}); ToT (#mus/10#mum)", kTH2F, {mLogBins, axisToT}); + if (!enableLogPBins.value && !enableLinearPBins.value) { + LOG(fatal) << "At least one of enableLogPBins or enableLinearPBins must be true."; + } + histos.add("hHitLayers", "Number of hits on each detector layer;Layer;Counts", kTH1F, {axisLayer}); histos.add("hHitMultiplicity", "Hit multiplicity along the track; # Hits per track;Counts", kTH1F, {axisHitsPerTrack}); + if (enableLogPBins.value) { + const AxisSpec axisMomentumLog{mLogBins, "#it{p/z} (GeV/#it{c})"}; + histos.add("hToTvsP", "ToT vs #it{p/z}; #it{p/z} (GeV/#it{c}); ToT (#mus/10#mum)", kTH2F, {axisMomentumLog, axisToT}); + histos.add("hToTvsMom", "ToT vs #it{p}; #it{p} (GeV/#it{c}); ToT (#mus/10#mum)", kTH2F, {mLogBins, axisToT}); + } + + if (enableLinearPBins.value) { + const AxisSpec axisMomentumLin{numLinearBins.value, static_cast(linearPMin.value), static_cast(linearPMax.value), "#it{p/z} (GeV/#it{c})"}; + histos.add("hToTvsPLin", "ToT vs #it{p/z} (linear); #it{p/z} (GeV/#it{c}); ToT (#mus/10#mum)", kTH2F, {axisMomentumLin, axisToT}); + histos.add("hToTvsMomLin", "ToT vs #it{p} (linear); #it{p} (GeV/#it{c}); ToT (#mus/10#mum)", kTH2F, {axisMomentumLin, axisToT}); + } + std::vector> particleInfo = { {11, "Elec"}, {13, "Muon"}, {211, "Pion"}, {321, "Kaon"}, {2212, "Prot"}, {1000010020, "Deut"}, {1000010030, "Trit"}, {1000020030, "He3"}, {1000020040, "Al"}}; @@ -508,39 +544,55 @@ struct OnTheFlyTrackerPid { else if (trueName == "Al") trueNamePretty = "#it{^{4}He}"; - std::string hitsVsPName = "HitsPerTrack/hHitsPerTrackVsP_" + trueName; - std::string hitsVsPTitle = "N_hits vs #it{p/z} for " + trueNamePretty + "; #it{p/z} (GeV/#it{c}); N_hits"; - h2dHitsPerTrackVsP[iTrue] = histos.add(hitsVsPName.c_str(), hitsVsPTitle.c_str(), kTH2F, {axisMomentum, axisHitsPerTrack}); - - std::string totVsPName = "ToTvsP/hToTvsP_" + trueName; - std::string totVsPTitle = "ToT vs #it{p/z} for " + trueNamePretty + "; #it{p/z} (GeV/#it{c}); ToT (#mus/10#mum)"; - h2dToTvsPperParticle[iTrue] = histos.add(totVsPName.c_str(), totVsPTitle.c_str(), kTH2F, {axisMomentum, axisToT}); - - for (size_t iHyp = 0; iHyp < particleInfo.size(); ++iHyp) { - std::string hypName = particleInfo[iHyp].second; - std::string hypNamePretty = hypName; // Fallback - if (hypName == "Elec") - hypNamePretty = "#it{e}"; - else if (hypName == "Muon") - hypNamePretty = "#it{#mu}"; - else if (hypName == "Pion") - hypNamePretty = "#it{#pi}"; - else if (hypName == "Kaon") - hypNamePretty = "#it{K}"; - else if (hypName == "Prot") - hypNamePretty = "#it{p}"; - else if (hypName == "Deut") - hypNamePretty = "#it{d}"; - else if (hypName == "Trit") - hypNamePretty = "#it{t}"; - else if (hypName == "He3") - hypNamePretty = "#it{^{3}He}"; - else if (hypName == "Al") - hypNamePretty = "#it{^{4}He}"; - - std::string histName = "NSigma/BarrelNsigmaTrue" + trueName + "Vs" + hypName + "Hypothesis"; - std::string histTitle = "Nsigma (True " + trueNamePretty + " vs Hyp " + hypNamePretty + "); #it{p/z} (GeV/#it{c}); N#sigma"; - h2dBarrelNsigmaTrue[iTrue][iHyp] = histos.add(histName.c_str(), histTitle.c_str(), kTH2F, {axisMomentum, axisNsigma}); + if (enableLogPBins.value) { + const AxisSpec axisMomentumLog{mLogBins, "#it{p/z} (GeV/#it{c})"}; + + std::string hitsVsPName = "HitsPerTrack/hHitsPerTrackVsP_" + trueName; + std::string hitsVsPTitle = "N_hits vs #it{p/z} for " + trueNamePretty + "; #it{p/z} (GeV/#it{c}); N_hits"; + h2dHitsPerTrackVsP[iTrue] = histos.add(hitsVsPName.c_str(), hitsVsPTitle.c_str(), kTH2F, {axisMomentumLog, axisHitsPerTrack}); + + std::string totVsPName = "ToTvsP/hToTvsP_" + trueName; + std::string totVsPTitle = "ToT vs #it{p/z} for " + trueNamePretty + "; #it{p/z} (GeV/#it{c}); ToT (#mus/10#mum)"; + h2dToTvsPperParticle[iTrue] = histos.add(totVsPName.c_str(), totVsPTitle.c_str(), kTH2F, {axisMomentumLog, axisToT}); + + for (size_t iHyp = 0; iHyp < particleInfo.size(); ++iHyp) { + std::string hypName = particleInfo[iHyp].second; + std::string hypNamePretty = hypName; // Fallback + if (hypName == "Elec") + hypNamePretty = "#it{e}"; + else if (hypName == "Muon") + hypNamePretty = "#it{#mu}"; + else if (hypName == "Pion") + hypNamePretty = "#it{#pi}"; + else if (hypName == "Kaon") + hypNamePretty = "#it{K}"; + else if (hypName == "Prot") + hypNamePretty = "#it{p}"; + else if (hypName == "Deut") + hypNamePretty = "#it{d}"; + else if (hypName == "Trit") + hypNamePretty = "#it{t}"; + else if (hypName == "He3") + hypNamePretty = "#it{^{3}He}"; + else if (hypName == "Al") + hypNamePretty = "#it{^{4}He}"; + + std::string histName = "NSigma/BarrelNsigmaTrue" + trueName + "Vs" + hypName + "Hypothesis"; + std::string histTitle = "Nsigma (True " + trueNamePretty + " vs Hyp " + hypNamePretty + "); #it{p/z} (GeV/#it{c}); N#sigma"; + h2dBarrelNsigmaTrue[iTrue][iHyp] = histos.add(histName.c_str(), histTitle.c_str(), kTH2F, {axisMomentumLog, axisNsigma}); + } + } + + if (enableLinearPBins.value) { + const AxisSpec axisMomentumLin{numLinearBins.value, static_cast(linearPMin.value), static_cast(linearPMax.value), "#it{p/z} (GeV/#it{c})"}; + + std::string hitsVsPLinName = "HitsPerTrackLin/hHitsPerTrackVsPLin_" + trueName; + std::string hitsVsPLinTitle = "N_hits vs #it{p/z} for " + trueNamePretty + " (linear); #it{p/z} (GeV/#it{c}); N_hits"; + h2dHitsPerTrackVsPLin[iTrue] = histos.add(hitsVsPLinName.c_str(), hitsVsPLinTitle.c_str(), kTH2F, {axisMomentumLin, axisHitsPerTrack}); + + std::string totVsPLinName = "ToTvsPLin/hToTvsPLin_" + trueName; + std::string totVsPLinTitle = "ToT vs #it{p/z} for " + trueNamePretty + " (linear); #it{p/z} (GeV/#it{c}); ToT (#mus/10#mum)"; + h2dToTvsPperParticleLin[iTrue] = histos.add(totVsPLinName.c_str(), totVsPLinTitle.c_str(), kTH2F, {axisMomentumLin, axisToT}); } } } @@ -581,7 +633,6 @@ struct OnTheFlyTrackerPid { continue; } - const float pt = mcParticle.pt(); const float p = mcParticle.p(); const float eta = mcParticle.eta(); const int truePdgCode = std::abs(mcParticle.pdgCode()); @@ -602,7 +653,7 @@ struct OnTheFlyTrackerPid { continue; } - const int binnedPt = mToTLUT->getPtBin(pt); + const int binnedP = mToTLUT->getPBin(p); const int binnedEta = mToTLUT->getEtaBin(std::abs(eta)); uint16_t hitMap = 0; @@ -629,13 +680,18 @@ struct OnTheFlyTrackerPid { } histos.fill(HIST("hHitMultiplicity"), nHitLayers); - h2dHitsPerTrackVsP[truePdgIdx]->Fill(rigidity, nHitLayers); + if (enableLogPBins.value) { + h2dHitsPerTrackVsP[truePdgIdx]->Fill(rigidity, nHitLayers); + } + if (enableLinearPBins.value) { + h2dHitsPerTrackVsPLin[truePdgIdx]->Fill(rigidity, nHitLayers); + } std::vector validToTs; for (int layer = kMinLayerForTruncation; layer < maxBarrelLayers.value; ++layer) { if ((hitMap >> layer) & 0x1) { - TH1F* totHist = mToTLUT->getHistogramForSampling(truePdgIdx, layer, binnedEta, binnedPt); + TH1F* totHist = mToTLUT->getHistogramForSampling(truePdgIdx, layer, binnedEta, binnedP); if (totHist && totHist->GetEntries() > 1) { float sampledToT = totHist->GetRandom(); @@ -665,14 +721,21 @@ struct OnTheFlyTrackerPid { } truncatedMeanToT = sum / static_cast(nUse); - histos.fill(HIST("hToTvsPt"), p, truncatedMeanToT); - histos.fill(HIST("hToTvsP"), rigidity, truncatedMeanToT); - h2dToTvsPperParticle[truePdgIdx]->Fill(rigidity, truncatedMeanToT); + if (enableLogPBins.value) { + histos.fill(HIST("hToTvsMom"), p, truncatedMeanToT); + histos.fill(HIST("hToTvsP"), rigidity, truncatedMeanToT); + h2dToTvsPperParticle[truePdgIdx]->Fill(rigidity, truncatedMeanToT); + } + if (enableLinearPBins.value) { + histos.fill(HIST("hToTvsMomLin"), p, truncatedMeanToT); + histos.fill(HIST("hToTvsPLin"), rigidity, truncatedMeanToT); + h2dToTvsPperParticleLin[truePdgIdx]->Fill(rigidity, truncatedMeanToT); + } } nSigmaValues.fill(999.f); - if (truncatedMeanToT > 0) { + if (enableLogPBins.value && truncatedMeanToT > 0) { for (size_t iHyp = 0; iHyp < mHypothesisPdgCodes.size(); ++iHyp) { int hypPdgCode = mHypothesisPdgCodes[iHyp]; int hypPdgIdx = mToTLUT->getPdgIndex(hypPdgCode);