File indexing completed on 2025-12-05 09:16:43
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsExamples/Validation/EffPlotTool.hpp"
0010
0011 #include "Acts/Utilities/VectorHelpers.hpp"
0012 #include "Acts/Utilities/Zip.hpp"
0013 #include "ActsExamples/EventData/SimParticle.hpp"
0014
0015 #include <format>
0016 #include <limits>
0017
0018 #include <TEfficiency.h>
0019
0020 using Acts::VectorHelpers::eta;
0021 using Acts::VectorHelpers::perp;
0022 using Acts::VectorHelpers::phi;
0023
0024 namespace ActsExamples {
0025
0026 EffPlotTool::EffPlotTool(const EffPlotTool::Config& cfg,
0027 Acts::Logging::Level lvl)
0028 : m_cfg(cfg), m_logger(Acts::getDefaultLogger("EffPlotTool", lvl)) {}
0029
0030 void EffPlotTool::book(Cache& cache) const {
0031 const PlotHelpers::Binning& bEta = m_cfg.varBinning.at("Eta");
0032 const PlotHelpers::Binning& bPhi = m_cfg.varBinning.at("Phi");
0033 const PlotHelpers::Binning& bPt = m_cfg.varBinning.at("Pt");
0034 const PlotHelpers::Binning& bLogPt = m_cfg.varBinning.at("LogPt");
0035 const PlotHelpers::Binning& bLowPt = m_cfg.varBinning.at("LowPt");
0036 const PlotHelpers::Binning& bD0 = m_cfg.varBinning.at("D0");
0037 const PlotHelpers::Binning& bZ0 = m_cfg.varBinning.at("Z0");
0038 const PlotHelpers::Binning& bDeltaR = m_cfg.varBinning.at("DeltaR");
0039 const PlotHelpers::Binning& bProdR = m_cfg.varBinning.at("prodR");
0040
0041 ACTS_DEBUG("Initialize the histograms for efficiency plots");
0042
0043 const std::string ptCutStr =
0044 std::format("pT > {} GeV/c", m_cfg.minTruthPt / Acts::UnitConstants::GeV);
0045
0046
0047 cache.trackEff_vs_eta = PlotHelpers::bookEff(
0048 "trackeff_vs_eta",
0049 std::format("Tracking efficiency with {};Truth #eta;Efficiency",
0050 ptCutStr),
0051 bEta);
0052
0053 cache.trackEff_vs_phi = PlotHelpers::bookEff(
0054 "trackeff_vs_phi",
0055 std::format("Tracking efficiency with {};Truth #phi;Efficiency",
0056 ptCutStr),
0057 bPhi);
0058
0059 cache.trackEff_vs_pT = PlotHelpers::bookEff(
0060 "trackeff_vs_pT", "Tracking efficiency;Truth pT [GeV/c];Efficiency", bPt);
0061
0062 cache.trackEff_vs_LogPt = PlotHelpers::bookEff(
0063 "trackeff_vs_LogPt", "Tracking efficiency;Truth pT [GeV/c];Efficiency",
0064 bLogPt);
0065
0066 cache.trackEff_vs_LowPt = PlotHelpers::bookEff(
0067 "trackeff_vs_LowPt", "Tracking efficiency;Truth pT [GeV/c];Efficiency",
0068 bLowPt);
0069
0070 cache.trackEff_vs_d0 = PlotHelpers::bookEff(
0071 "trackeff_vs_d0",
0072 std::format("Tracking efficiency with {};Truth d_0 [mm];Efficiency",
0073 ptCutStr),
0074 bD0);
0075
0076 cache.trackEff_vs_z0 = PlotHelpers::bookEff(
0077 "trackeff_vs_z0",
0078 std::format("Tracking efficiency with {};Truth z_0 [mm];Efficiency",
0079 ptCutStr),
0080 bZ0);
0081
0082 cache.trackEff_vs_DeltaR = PlotHelpers::bookEff(
0083 "trackeff_vs_DeltaR",
0084 std::format(
0085 "Tracking efficiency with {};Closest track #Delta R;Efficiency",
0086 ptCutStr),
0087 bDeltaR);
0088
0089 cache.trackEff_vs_prodR = PlotHelpers::bookEff(
0090 "trackeff_vs_prodR",
0091 std::format(
0092 "Tracking efficiency with {};Production radius [mm];Efficiency",
0093 ptCutStr),
0094 bProdR);
0095
0096
0097 cache.trackEff_vs_eta_phi = PlotHelpers::bookEff(
0098 "trackeff_vs_eta_phi",
0099 std::format(
0100 "Tracking efficiency with {};Truth #eta;Truth #phi;Efficiency",
0101 ptCutStr),
0102 bEta, bPhi);
0103
0104 cache.trackEff_vs_eta_pt = PlotHelpers::bookEff(
0105 "trackeff_vs_eta_pt",
0106 "Tracking efficiency;Truth #eta;Truth pT [GeV/c];Efficiency", bEta, bPt);
0107
0108
0109 for (const auto& [i, ptRange] : Acts::enumerate(m_cfg.truthPtRangesForEta)) {
0110 const std::string name = std::format("trackeff_vs_eta_ptRange_{}", i);
0111 const std::string title = std::format(
0112 "Tracking efficiency with pT in [{}, {}] GeV/c;Truth #eta;Efficiency",
0113 ptRange.first / Acts::UnitConstants::GeV,
0114 ptRange.second / Acts::UnitConstants::GeV);
0115 cache.trackEff_vs_eta_inPtRanges.push_back(
0116 PlotHelpers::bookEff(name, title, bEta));
0117 }
0118
0119 for (const auto& [i, absEtaRange] :
0120 Acts::enumerate(m_cfg.truthAbsEtaRangesForPt)) {
0121 const std::string name = std::format("trackeff_vs_pT_absEtaRange_{}", i);
0122 const std::string title = std::format(
0123 "Tracking efficiency with |#eta| in [{}, {}];Truth pT "
0124 "[GeV/c];Efficiency",
0125 absEtaRange.first, absEtaRange.second);
0126 cache.trackEff_vs_pT_inAbsEtaRanges.push_back(
0127 PlotHelpers::bookEff(name, title, bPt));
0128 }
0129 }
0130
0131 void EffPlotTool::clear(Cache& cache) const {
0132 ACTS_DEBUG("Clear the histograms for efficiency plots.");
0133
0134 delete cache.trackEff_vs_eta;
0135 delete cache.trackEff_vs_phi;
0136 delete cache.trackEff_vs_pT;
0137 delete cache.trackEff_vs_LogPt;
0138 delete cache.trackEff_vs_LowPt;
0139 delete cache.trackEff_vs_d0;
0140 delete cache.trackEff_vs_z0;
0141 delete cache.trackEff_vs_DeltaR;
0142 delete cache.trackEff_vs_prodR;
0143
0144 delete cache.trackEff_vs_eta_phi;
0145 delete cache.trackEff_vs_eta_pt;
0146
0147 for (TEfficiency* eff : cache.trackEff_vs_eta_inPtRanges) {
0148 delete eff;
0149 }
0150 for (TEfficiency* eff : cache.trackEff_vs_pT_inAbsEtaRanges) {
0151 delete eff;
0152 }
0153 }
0154
0155 void EffPlotTool::write(const Cache& cache) const {
0156 ACTS_DEBUG("Write the plots to output file.");
0157
0158 cache.trackEff_vs_eta->Write();
0159 for (const TEfficiency* eff : cache.trackEff_vs_eta_inPtRanges) {
0160 eff->Write();
0161 }
0162 cache.trackEff_vs_eta_phi->Write();
0163 cache.trackEff_vs_eta_pt->Write();
0164 cache.trackEff_vs_phi->Write();
0165 cache.trackEff_vs_pT->Write();
0166 for (const TEfficiency* eff : cache.trackEff_vs_pT_inAbsEtaRanges) {
0167 eff->Write();
0168 }
0169 cache.trackEff_vs_LogPt->Write();
0170 cache.trackEff_vs_LowPt->Write();
0171 cache.trackEff_vs_d0->Write();
0172 cache.trackEff_vs_z0->Write();
0173 cache.trackEff_vs_DeltaR->Write();
0174 cache.trackEff_vs_prodR->Write();
0175 }
0176
0177 void EffPlotTool::fill(const Acts::GeometryContext& gctx, Cache& cache,
0178 const SimParticleState& truthParticle,
0179 const double deltaR, const bool status) const {
0180 constexpr double nan = std::numeric_limits<double>::quiet_NaN();
0181
0182 const auto intersection =
0183 m_cfg.beamline
0184 ->intersect(gctx, truthParticle.position(), truthParticle.direction())
0185 .closest();
0186 Acts::Vector2 d0z0{nan, nan};
0187 if (intersection.isValid()) {
0188 auto localRes = m_cfg.beamline->globalToLocal(gctx, intersection.position(),
0189 truthParticle.direction());
0190 if (localRes.ok()) {
0191 d0z0 = localRes.value();
0192 }
0193 }
0194
0195 const double t_phi = phi(truthParticle.direction());
0196 const double t_eta = eta(truthParticle.direction());
0197 const double t_absEta = std::abs(t_eta);
0198 const double t_pT = truthParticle.transverseMomentum();
0199 const double t_d0 = d0z0.x();
0200 const double t_z0 = d0z0.y();
0201 const double t_deltaR = deltaR;
0202 const double t_prodR = perp(truthParticle.position());
0203
0204
0205 if (t_pT >= m_cfg.minTruthPt) {
0206 PlotHelpers::fillEff(cache.trackEff_vs_eta, t_eta, status);
0207 PlotHelpers::fillEff(cache.trackEff_vs_phi, t_phi, status);
0208 PlotHelpers::fillEff(cache.trackEff_vs_d0, t_d0, status);
0209 PlotHelpers::fillEff(cache.trackEff_vs_z0, t_z0, status);
0210 PlotHelpers::fillEff(cache.trackEff_vs_DeltaR, t_deltaR, status);
0211 PlotHelpers::fillEff(cache.trackEff_vs_prodR, t_prodR, status);
0212
0213 PlotHelpers::fillEff(cache.trackEff_vs_eta_phi, t_eta, t_phi, status);
0214 }
0215
0216
0217 PlotHelpers::fillEff(cache.trackEff_vs_pT, t_pT, status);
0218 PlotHelpers::fillEff(cache.trackEff_vs_LogPt, t_pT, status);
0219 PlotHelpers::fillEff(cache.trackEff_vs_LowPt, t_pT, status);
0220 PlotHelpers::fillEff(cache.trackEff_vs_eta_pt, t_eta, t_pT, status);
0221
0222
0223 for (const auto& [ptRange, eff] :
0224 Acts::zip(m_cfg.truthPtRangesForEta, cache.trackEff_vs_eta_inPtRanges)) {
0225 if (t_pT >= ptRange.first && t_pT < ptRange.second) {
0226 PlotHelpers::fillEff(eff, t_eta, status);
0227 }
0228 }
0229
0230
0231 for (const auto& [absEtaRange, eff] : Acts::zip(
0232 m_cfg.truthAbsEtaRangesForPt, cache.trackEff_vs_pT_inAbsEtaRanges)) {
0233 if (t_absEta >= absEtaRange.first && t_absEta < absEtaRange.second) {
0234 PlotHelpers::fillEff(eff, t_pT, status);
0235 }
0236 }
0237 }
0238
0239 }