ATLAS Offline Software
Loading...
Searching...
No Matches
TauCalibrateLC.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 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{
102 // get IntermediateAxis or DetectorAxis momentum
104
105 // skip calibration if negative pt
106 if ( tau_p4.Pt() <= 0.) {
107 ATH_MSG_DEBUG("tau energy at LC scale is " << tau_p4.Pt()/GeV << "--> set energy=0.001");
108 tau.setP4(0.001, tau_p4.Eta(), tau_p4.Phi(), tau.m());
109 tau.setP4(xAOD::TauJetParameters::TauEnergyScale, tau.pt(), tau.eta(), tau.phi(), tau.m());
110 return StatusCode::SUCCESS;
111 }
112
113 // energy calibration depends on number of tracks - 1p or Mp
114 int prongBin = 1; //Mp
115 if (tau.nTracks() <= 1) prongBin = 0; //1p
116
117 double absEta = std::abs( tau_p4.Eta() );
118 int etaBin = std::as_const(*m_etaBinHist).GetXaxis()->FindBin(absEta) - 1;
119
120 if (etaBin>=m_nEtaBins) etaBin = m_nEtaBins-1; // correction from last bin should be applied on all taus outside stored eta range
121
122 int nVertex = 0;
123
124 // Obtain pileup
126 if (!vertexInHandle.isValid()) {
127 ATH_MSG_ERROR ("Could not retrieve HiveDataObj with key " << vertexInHandle.key());
128 return StatusCode::FAILURE;
129 }
130 const xAOD::VertexContainer * vxContainer = vertexInHandle.cptr();
131 for (const auto *const vertex : *vxContainer) {
132 if (vertex->vertexType() == xAOD::VxType::PileUp) {
133 ++nVertex;
134 }
135 }
136 ATH_MSG_DEBUG("calculated nVertex " << nVertex );
137
138 double calibConst = 1.;
139
140 double slopeNPV = m_slopeNPVHist[prongBin]->GetBinContent(etaBin + 1);
141 double offset = slopeNPV * (nVertex - m_averageNPV);
142
143 // pt (energy) response parameterized as a function of pileup-corrected pt (energy)
144 double energyLC = tau_p4.Pt()/GeV;
145
146 if (energyLC - offset <= 0.) {
147 ATH_MSG_DEBUG("after pile-up correction energy would be = " << energyLC - offset << " --> setting offset=0 now!");
148 offset = 0.;
149 }
150
151 // apply offset correction
152 double energyPileupCorr = energyLC - offset;
153
154 if (energyPileupCorr > 0. and energyPileupCorr < 10000.) // from 0 to 10 TeV
155 {
156 calibConst = m_calibFunc[prongBin][etaBin]->Eval(energyPileupCorr);
157
158 if (calibConst <= 0.) {
159 ATH_MSG_DEBUG("calibration constant = " << calibConst);
160 ATH_MSG_DEBUG("prongBin = " << prongBin);
161 ATH_MSG_DEBUG("etaBin = " << etaBin);
162 ATH_MSG_DEBUG("energyPileupCorr = " << energyPileupCorr);
163 ATH_MSG_DEBUG("energyLC = " << energyLC);
164 calibConst = 1.;
165 }
166 }
167
168 double energyFinal = energyPileupCorr / calibConst;
169
170 // tau.m() is 0 by convention in tauRecTools
171 // while mDetectorAxis and mIntermediateAxis are not forced to 0, mTauEnergyScale is
173 tau.setP4( energyFinal * GeV, tau_p4.Eta(), tau_p4.Phi(), 0.0);
174 tau.setP4(xAOD::TauJetParameters::TauEnergyScale, tau.pt(), tau.eta(), tau.phi(), 0.0);
175 } else {
176 tau.setP4( energyFinal * GeV, tau_p4.Eta(), tau_p4.Phi(), tau.m());
177 tau.setP4(xAOD::TauJetParameters::TauEnergyScale, tau.pt(), tau.eta(), tau.phi(), tau.m());
178 }
179 ATH_MSG_DEBUG("Energy at LC scale = " << energyLC << " pile-up offset " << offset << " calib. const. = " << calibConst << " final energy = " << energyFinal);
180
181 return StatusCode::SUCCESS;
182}
#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 execute(xAOD::TauJet &tau) 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