ATLAS Offline Software
Loading...
Searching...
No Matches
TauCalibrateLC.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
9
10#include "TFile.h"
11#include "TF1.h"
12#include "TH1D.h"
13#include <utility>
14
15#define GeV 1000
16
17/********************************************************************/
18TauCalibrateLC::TauCalibrateLC(const std::string& name) :
19 TauRecToolBase(name) {
20}
21
22/********************************************************************/
25
26/********************************************************************/
28
29 ATH_CHECK( m_vertexInputContainer.initialize() );
30
31 std::string fullPath = find_file(m_calibrationFile);
32 ATH_MSG_INFO("Using calibration file: " << fullPath);
33
34 std::unique_ptr<TFile> file(TFile::Open(fullPath.c_str(), "READ"));
35 if (!file) {
36 ATH_MSG_FATAL("Failed to open " << fullPath);
37 return StatusCode::FAILURE;
38 }
39
40 // get the histogram defining eta binning
41 std::string key = "etaBinning";
42 TH1* histo = dynamic_cast<TH1*>(file->Get(key.c_str()));
43 if (histo) {
44 histo->SetDirectory(nullptr);
45 m_etaBinHist = std::unique_ptr<TH1>(histo);
46 }
47 else {
48 ATH_MSG_FATAL("Failed to get an object with key " << key);
49 return StatusCode::FAILURE;
50 }
51
52 //retrieve number of eta bins from file
53 m_nEtaBins = m_etaBinHist->GetNbinsX();
54
55 TString tmpSlopKey[s_nProngBins] = {"slopeNPV1P", "slopeNPV3P"};
56 TString tmpFuncBase[s_nProngBins] = {"OneP_Eta_", "MultiP_Eta_"};
57
60
63 for (int i = 0; i < s_nProngBins; ++i) {
64 m_calibFunc[i].resize(m_nEtaBins);
65 }
66
67 for (int i = 0; i < s_nProngBins; i++) {
68 histo = dynamic_cast<TH1*>(file->Get(tmpSlopKey[i])); // get pile-up slope histograms
69 if (histo) {
70 histo->SetDirectory(nullptr);
71 m_slopeNPVHist[i] = std::unique_ptr<TH1>(histo);
72 }
73 else {
74 ATH_MSG_FATAL("Failed to get an object with key " << tmpSlopKey[i]);
75 return StatusCode::FAILURE;
76 }
77
78 for (int j = 0; j < m_nEtaBins; j++) {
79 TString key = tmpFuncBase[i];
80 key += j;
81 TF1* fcn = dynamic_cast<TF1*>(file->Get(key));
82 if (fcn) {
83 m_calibFunc[i][j] = std::unique_ptr<TF1>(fcn);
84 }
85 else {
86 ATH_MSG_FATAL("Failed to get an object with key " << key);
87 return StatusCode::FAILURE;
88 }
89 }
90 }
91 m_averageNPV = m_slopeNPVHist[0]->GetBinContent(0); // underflow is the average number of reconstructed primary vertices
92 ATH_MSG_DEBUG("averageNPV = " << m_averageNPV);
93
94 file->Close();
95
96 return StatusCode::SUCCESS;
97}
98
99/********************************************************************/
101 const EventContext& ctx) const
102{
103 // get IntermediateAxis or DetectorAxis momentum
105
106 // skip calibration if negative pt
107 if ( tau_p4.Pt() <= 0.) {
108 ATH_MSG_DEBUG("tau energy at LC scale is " << tau_p4.Pt()/GeV << "--> set energy=0.001");
109 tau.setP4(0.001, tau_p4.Eta(), tau_p4.Phi(), tau.m());
110 tau.setP4(xAOD::TauJetParameters::TauEnergyScale, tau.pt(), tau.eta(), tau.phi(), tau.m());
111 return StatusCode::SUCCESS;
112 }
113
114 // energy calibration depends on number of tracks - 1p or Mp
115 int prongBin = 1; //Mp
116 if (tau.nTracks() <= 1) prongBin = 0; //1p
117
118 double absEta = std::abs( tau_p4.Eta() );
119 int etaBin = std::as_const(*m_etaBinHist).GetXaxis()->FindBin(absEta) - 1;
120
121 if (etaBin>=m_nEtaBins) etaBin = m_nEtaBins-1; // correction from last bin should be applied on all taus outside stored eta range
122
123 int nVertex = 0;
124
125 // Obtain pileup
127 if (!vertexInHandle.isValid()) {
128 ATH_MSG_ERROR ("Could not retrieve HiveDataObj with key " << vertexInHandle.key());
129 return StatusCode::FAILURE;
130 }
131 const xAOD::VertexContainer * vxContainer = vertexInHandle.cptr();
132 for (const auto *const vertex : *vxContainer) {
133 if (vertex->vertexType() == xAOD::VxType::PileUp) {
134 ++nVertex;
135 }
136 }
137 ATH_MSG_DEBUG("calculated nVertex " << nVertex );
138
139 double calibConst = 1.;
140
141 double slopeNPV = m_slopeNPVHist[prongBin]->GetBinContent(etaBin + 1);
142 double offset = slopeNPV * (nVertex - m_averageNPV);
143
144 // pt (energy) response parameterized as a function of pileup-corrected pt (energy)
145 double energyLC = tau_p4.Pt()/GeV;
146
147 if (energyLC - offset <= 0.) {
148 ATH_MSG_DEBUG("after pile-up correction energy would be = " << energyLC - offset << " --> setting offset=0 now!");
149 offset = 0.;
150 }
151
152 // apply offset correction
153 double energyPileupCorr = energyLC - offset;
154
155 if (energyPileupCorr > 0. and energyPileupCorr < 10000.) // from 0 to 10 TeV
156 {
157 calibConst = m_calibFunc[prongBin][etaBin]->Eval(energyPileupCorr);
158
159 if (calibConst <= 0.) {
160 ATH_MSG_DEBUG("calibration constant = " << calibConst);
161 ATH_MSG_DEBUG("prongBin = " << prongBin);
162 ATH_MSG_DEBUG("etaBin = " << etaBin);
163 ATH_MSG_DEBUG("energyPileupCorr = " << energyPileupCorr);
164 ATH_MSG_DEBUG("energyLC = " << energyLC);
165 calibConst = 1.;
166 }
167 }
168
169 double energyFinal = energyPileupCorr / calibConst;
170
171 // tau.m() is 0 by convention in tauRecTools
172 // while mDetectorAxis and mIntermediateAxis are not forced to 0, mTauEnergyScale is
174 tau.setP4( energyFinal * GeV, tau_p4.Eta(), tau_p4.Phi(), 0.0);
175 tau.setP4(xAOD::TauJetParameters::TauEnergyScale, tau.pt(), tau.eta(), tau.phi(), 0.0);
176 } else {
177 tau.setP4( energyFinal * GeV, tau_p4.Eta(), tau_p4.Phi(), tau.m());
178 tau.setP4(xAOD::TauJetParameters::TauEnergyScale, tau.pt(), tau.eta(), tau.phi(), tau.m());
179 }
180 ATH_MSG_DEBUG("Energy at LC scale = " << energyLC << " pile-up offset " << offset << " calib. const. = " << calibConst << " final energy = " << energyFinal);
181
182 return StatusCode::SUCCESS;
183}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_INFO(x,...)
#define ATH_MSG_FATAL(x,...)
Handle class for reading a decoration on an object.
Handle class for reading from StoreGate.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
virtual const std::string & key() const override final
Return the StoreGate ID for the referenced object.
SG::ReadHandleKey< xAOD::VertexContainer > m_vertexInputContainer
Gaudi::Property< std::string > m_calibrationFile
virtual StatusCode executeTool(xAOD::TauJet &tau, const EventContext &ctx) const override
Execute - called for each tau candidate.
TauCalibrateLC(const std::string &name="TauCalibrateLC")
std::unique_ptr< TH1 > m_etaBinHist
static const int s_nProngBins
virtual StatusCode initialize() override
Tool initializer.
std::vector< std::vector< std::unique_ptr< TF1 > > > m_calibFunc
Gaudi::Property< bool > m_doForceZeroMass
std::vector< std::unique_ptr< TH1 > > m_slopeNPVHist
Gaudi::Property< bool > m_doVertexCorrection
TauRecToolBase(const std::string &name)
std::string find_file(const std::string &fname) const
@ PileUp
Pile-up vertex.
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
TauJet_v3 TauJet
Definition of the current "tau version".
Definition TauJet.h:17
TFile * file