ATLAS Offline Software
Loading...
Searching...
No Matches
TauWPDecorator.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 <algorithm>
11#include <array>
12#include "TFile.h"
13#include "TH2.h"
14
15//______________________________________________________________________________
16TauWPDecorator::TauWPDecorator(const std::string& name) :
17 TauRecToolBase(name) {
18}
19
20//______________________________________________________________________________
23
24//______________________________________________________________________________
25StatusCode TauWPDecorator::retrieveHistos(int nProng) {
26 // Find and open file
27 std::string fileName;
28 std::shared_ptr<std::vector<m_pair_t>> histArray = nullptr;
29 if (nProng == 0) {
30 fileName = m_file0p;
31 histArray = m_hists0p;
32 }
33 else if (nProng == 1) {
34 fileName = m_file1p;
35 histArray = m_hists1p;
36 }
37 else if (nProng == 2) {
38 fileName = m_file2p;
39 histArray = m_hists2p;
40 }
41 else if (nProng == 3) {
42 fileName = m_file3p;
43 histArray = m_hists3p;
44 }
45 else {
46 ATH_MSG_ERROR("nProng " << nProng << " not supported.");
47 return StatusCode::FAILURE;
48 }
49 if (!histArray)[[unlikely]]{
50 ATH_MSG_ERROR("histArray pointer is null.");
51 return StatusCode::FAILURE;
52 }
53
54 std::string fullPath = find_file(fileName);
55 std::unique_ptr<TFile> file(TFile::Open(fullPath.c_str(), "READ"));
56
57 if (!file || file->IsZombie()) {
58 ATH_MSG_FATAL("Could not open file " << fullPath.c_str());
59 return StatusCode::FAILURE;
60 }
61
62 ATH_MSG_INFO("Loading working points [" << nProng << "-prong]: " << fullPath.c_str());
63
64 // Iterate over working points
65 for (int i = 0; i < 100; ++i) {
66 // Retrieve histogram
67 TH2* graph = dynamic_cast<TH2*>(file->Get(Form("h2_%02d", i)));
68 if (!graph){
69 ATH_MSG_ERROR("Failed to retrieve Graph " << i << " named " << Form("h2_%02d", i));
70 return StatusCode::FAILURE;
71 }
72 graph->SetDirectory(nullptr);
73 std::shared_ptr<TH2> sharedGraph(graph);
74 histArray->push_back(m_pair_t(float(i)/100., std::move(sharedGraph)));
75 }
76
77 file->Close();
78
79 return StatusCode::SUCCESS;
80}
81
82//______________________________________________________________________________
83StatusCode TauWPDecorator::storeLimits(int nProng) {
84 std::shared_ptr<std::vector<m_pair_t>> histArray = nullptr;
85 if (nProng == 0) {
86 histArray = m_hists0p;
87 }
88 else if (nProng == 1) {
89 histArray = m_hists1p;
90 }
91 else if (nProng == 2) {
92 histArray = m_hists2p;
93 }
94 else if (nProng == 3) {
95 histArray = m_hists3p;
96 }
97 else {
98 ATH_MSG_ERROR("nProng " << nProng << " not supported.");
99 return StatusCode::FAILURE;
100 }
101 if (!histArray)[[unlikely]]{
102 ATH_MSG_ERROR("histArray pointer is null.");
103 return StatusCode::FAILURE;
104 }
105 std::shared_ptr<TH2> firstHist = histArray->at(0).second;
106 m_xMin[nProng] = firstHist->GetXaxis()->GetXmin();
107 m_xMax[nProng] = firstHist->GetXaxis()->GetBinCenter(firstHist->GetNbinsX());
108 m_yMin[nProng] = firstHist->GetYaxis()->GetXmin();
109 m_yMax[nProng] = firstHist->GetYaxis()->GetBinCenter(firstHist->GetNbinsY());
110
111 // Check all the histograms have the same limits
112 for (size_t i = 1; i < histArray->size(); ++i) {
113 std::shared_ptr<TH2> hist = histArray->at(i).second;
114
115 double xMin = hist->GetXaxis()->GetXmin();
116 double xMax = hist->GetXaxis()->GetBinCenter(firstHist->GetNbinsX());
117 double yMin = hist->GetYaxis()->GetXmin();
118 double yMax = hist->GetYaxis()->GetBinCenter(firstHist->GetNbinsY());
119
120 if (std::abs(m_xMin[nProng] - xMin) > 1e-5 ||
121 std::abs(m_xMax[nProng] - xMax) > 1e-5 ||
122 std::abs(m_yMin[nProng] - yMin) > 1e-5 ||
123 std::abs(m_yMax[nProng] - yMax) > 1e-5) {
124 ATH_MSG_WARNING("The " << i << " th histogram has different limit");
125 }
126 }
127
128 return StatusCode::SUCCESS;
129}
130
131//______________________________________________________________________________
132double TauWPDecorator::transformScore(double score, double cutLow, double effLow, double cutHigh, double effHigh) const {
133 double efficiency = effLow + (score - cutLow)/(cutHigh - cutLow) * (effHigh - effLow);
134 double scoreTrans = 1.0 - efficiency;
135 return scoreTrans;
136}
137
138//______________________________________________________________________________
140
141 if (!m_tauContainerName.empty() && m_decorWPs.empty()) {
142 ATH_MSG_ERROR("TauContainerName is provided but DecorWPNames is empty");
143 return StatusCode::FAILURE;
144 }
145 for (size_t wpIndex=0; wpIndex < m_decorWPs.size(); ++wpIndex) {
146 m_charDecors.emplace_back(SG::Accessor<char>( m_decorWPs[wpIndex] ));
147 // temporarily need both accessor and decoration
148 if (!m_tauContainerName.empty()) {
149 m_decorHandleKeys.emplace_back(m_tauContainerName + "." + m_decorWPs[wpIndex]);
150 // add also decor handle for the trans score
152 }
153 }
154 ATH_CHECK( m_decorHandleKeys.initialize() );
155
156 ATH_CHECK( m_aveIntPerXKey.initialize() );
157
158 // 1p and 3p files must be provided
159 if (m_file1p.empty() || m_file3p.empty()) {
160 ATH_MSG_ERROR("1p/3p flattening file is not provided !");
161 return StatusCode::FAILURE;
162 }
163
164 // 0p is for trigger only
165 if (!m_file0p.empty()) {
166 m_hists0p = std::make_shared<std::vector<m_pair_t>>();
169 }
170
171 m_hists1p = std::make_shared<std::vector<m_pair_t>>();
174
175 // 2p is optional
176 if (!m_file2p.empty()) {
177 m_hists2p = std::make_shared<std::vector<m_pair_t>>();
178 //coverity[NULL_FIELD:FALSE]
180 //coverity[NULL_FIELD:FALSE]
182 }
183
184 m_hists3p = std::make_shared<std::vector<m_pair_t>>();
185 //coverity[NULL_FIELD:FALSE]
187 //coverity[NULL_FIELD:FALSE]
189
190 return StatusCode::SUCCESS;
191}
192
193//______________________________________________________________________________
195 const EventContext& ctx) const {
196 // obtain the dependent variables of the efficiency
197 // x variable is tau pt
198 double xVariable = tau.pt();
199
200 // y variable is |eta| of leading track in electron mode, and pileup in other cases
201 double yVariable = 0.0;
202 if (m_useAbsEta) {
203 static const SG::ConstAccessor<float> acc_absEta("ABS_ETA_LEAD_TRACK");
204 yVariable = std::abs(acc_absEta(tau));
205 }
206 else {
208 if (!eventInfoDecorHandle.isPresent()) {
209 ATH_MSG_ERROR( "EventInfo decoration " << m_aveIntPerXKey << " not available!" );
210 return StatusCode::FAILURE;
211 }
212 yVariable = eventInfoDecorHandle(0);
213 }
214
215 int nTracks = tau.nTracks();
216 int nProng = nTracks;
217
218 // 0p is treated as 3p when no calibration file is not provided for 0p
219 // 2p is treated as 3p when no calibration file is not provided for 2p
220 if (nTracks == 0 && !m_hists0p) {
221 // 0p->3p mapping was done for R21 backward compatibility reasons, may want to change this
222 nProng = 3;
223 }
224 else if (nTracks == 2 && !m_hists2p) {
225 nProng = 3;
226 }
227 else if (nTracks > 2) {
228 nProng = 3;
229 }
230
231 // make sure the dependent variables are within the range of calibration histograms
232 ATH_MSG_DEBUG("original pT:\t" << xVariable);
233 if (m_useAbsEta) {
234 ATH_MSG_DEBUG("original |eta|:\t" << yVariable);
235 }
236 else {
237 ATH_MSG_DEBUG("original mu:\t" << yVariable);
238 }
239
240 xVariable = std::min(m_xMax.at(nProng), std::max(m_xMin.at(nProng), xVariable));
241 yVariable = std::min(m_yMax.at(nProng), std::max(m_yMin.at(nProng), yVariable));
242
243 ATH_MSG_DEBUG("final pT:\t" << xVariable);
244 if (m_useAbsEta) {
245 ATH_MSG_DEBUG("final |eta|:\t" << yVariable);
246 }
247 else {
248 ATH_MSG_DEBUG("final mu:\t" << yVariable);
249 }
250
251 std::shared_ptr<std::vector<m_pair_t>> histArray = nullptr;
252 if (nProng == 0) histArray = m_hists0p;
253 else if (nProng == 1) histArray = m_hists1p;
254 else if (nProng == 2) histArray = m_hists2p;
255 else histArray = m_hists3p;
256
257 std::array<double, 2> cuts = {m_ScoreBounds[0], m_ScoreBounds[1]}; // lower and upper boundaRy of the score
258 std::array<double, 2> effs = {1.0, 0.0}; // efficiency corresponding to the score cut
259 bool gotLow = false; // whether lower bounday is found
260 bool gotHigh = false; // whether upper bounday is found
261
262 const SG::ConstAccessor<float> acc_score(m_scoreName);
263 double score = acc_score(tau); // original score (BDT/RNN)
264
265 // Loop over all histograms to find the lower and upper bounary of the score and corresponding efficiency
266 for (unsigned int i = 0; i < histArray->size(); ++i) {
267 std::shared_ptr<TH2> myHist = histArray->at(i).second;
268 double myCut = myHist->Interpolate(xVariable, yVariable);
269
270 if (myCut <= score && ((!gotLow) || std::abs(myCut-score) < std::abs(cuts[0]-score))) {
271 gotLow = true;
272 effs[0] = histArray->at(i).first;
273 cuts[0] = myCut;
274 }
275 else if (myCut > score && ((!gotHigh) || std::abs(myCut-score) < std::abs(cuts[1]-score))) {
276 gotHigh = true;
277 effs[1] = histArray->at(i).first;
278 cuts[1] = myCut;
279 }
280
281 if (gotLow && gotHigh){
282 ATH_MSG_VERBOSE("break @ " << myHist->GetName());
283 break;
284 }
285 }
286
287 double scoreTrans = -1111.; // flattened score
288 if (score > cuts[1]) { // should not happen
289 scoreTrans = 1 - effs[1];
290 }
291 else if (score < cuts[0]) { // score is -9999 when BDT/RNN fails
292 scoreTrans = 1 - effs[0];
293 }
294 else {
295 scoreTrans = transformScore(score, cuts[0], effs[0], cuts[1], effs[1]);
296 }
297
298 const SG::Accessor<float> acc_scoreTrans(m_scoreNameTrans);
299 acc_scoreTrans(tau) = scoreTrans;
300
301 if(m_defineWPs) {
302 // WPs in EDM
303 for (size_t wpIndex=0; wpIndex < m_EDMWPs.size(); ++wpIndex) {
304 if(nProng == 0) {
305 tau.setIsTau((xAOD::TauJetParameters::IsTauFlag) m_EDMWPs[wpIndex], scoreTrans > (1-m_EDMWPEffs0p[wpIndex]));
306 }
307 else if(nProng == 1) {
308 tau.setIsTau((xAOD::TauJetParameters::IsTauFlag) m_EDMWPs[wpIndex], scoreTrans > (1-m_EDMWPEffs1p[wpIndex]));
309 }
310 else if(nProng == 2) {
311 tau.setIsTau((xAOD::TauJetParameters::IsTauFlag) m_EDMWPs[wpIndex], scoreTrans > (1-m_EDMWPEffs2p[wpIndex]));
312 }
313 else {
314 tau.setIsTau((xAOD::TauJetParameters::IsTauFlag) m_EDMWPs[wpIndex], scoreTrans > (1-m_EDMWPEffs3p[wpIndex]));
315 }
316 }
317 // Decorate other WPs
318 for (size_t wpIndex=0; wpIndex < m_decorWPs.size(); ++wpIndex) {
319 const SG::Accessor<char>& decorator = m_charDecors[wpIndex];
320
321 if(nProng == 0) {
322 decorator(tau) = scoreTrans > (1-m_decorWPEffs0p[wpIndex]);
323 }
324 else if(nProng == 1) {
325 decorator(tau) = scoreTrans > (1-m_decorWPEffs1p[wpIndex]);
326 }
327 else if(nProng == 2) {
328 decorator(tau) = scoreTrans > (1-m_decorWPEffs2p[wpIndex]);
329 }
330 else {
331 decorator(tau) = scoreTrans > (1-m_decorWPEffs3p[wpIndex]);
332 }
333 }
334 }
335
336 return StatusCode::SUCCESS;
337}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
#define ATH_MSG_FATAL(x,...)
Handle class for reading a decoration on an object.
Handle class for adding a decoration to an object.
Helper class to provide type-safe access to aux data.
Helper class to provide constant type-safe access to aux data.
Handle class for reading a decoration on an object.
bool isPresent() const
Is the referenced container present in SG?
TauRecToolBase(const std::string &name)
std::string find_file(const std::string &fname) const
StatusCode storeLimits(int nProng)
Obtain the limit of the dependent variables.
Gaudi::Property< std::string > m_scoreNameTrans
Gaudi::Property< std::vector< float > > m_EDMWPEffs0p
Gaudi::Property< std::vector< float > > m_EDMWPEffs3p
std::map< int, double > m_yMin
Map of n-prong and the minimum value of y variables.
Gaudi::Property< std::vector< float > > m_EDMWPEffs1p
Gaudi::Property< std::string > m_file3p
virtual StatusCode executeTool(xAOD::TauJet &tau, const EventContext &ctx) const override
Execute - called for each tau candidate.
Gaudi::Property< std::string > m_tauContainerName
Gaudi::Property< std::vector< std::string > > m_decorWPs
double transformScore(double score, double cutLow, double effLow, double cutHigh, double effHigh) const
Obtain the flattened score.
std::shared_ptr< std::vector< m_pair_t > > m_hists1p
Efficiency and corresponding score distributions of 1-prong taus.
Gaudi::Property< std::vector< float > > m_decorWPEffs0p
std::shared_ptr< std::vector< m_pair_t > > m_hists0p
Efficiency and corresponding score distributions of 0-prong taus.
Gaudi::Property< std::vector< int > > m_EDMWPs
Gaudi::Property< std::vector< float > > m_decorWPEffs1p
Gaudi::Property< bool > m_defineWPs
Gaudi::Property< std::vector< float > > m_EDMWPEffs2p
Gaudi::Property< std::string > m_scoreName
virtual StatusCode initialize() override
Initialization of this tool.
Gaudi::Property< std::string > m_file0p
Gaudi::Property< std::string > m_file1p
std::map< int, double > m_yMax
Map of n-prong and the maximum value of y variables.
SG::WriteDecorHandleKeyArray< xAOD::TauJetContainer > m_decorHandleKeys
std::map< int, double > m_xMax
Map of n-prong and the maximum value of x variables.
std::map< int, double > m_xMin
Map of n-prong and the minimum value of x variables.
std::shared_ptr< std::vector< m_pair_t > > m_hists3p
Efficiency and corresponding score distributions of 3-prong taus.
SG::ReadDecorHandleKey< xAOD::EventInfo > m_aveIntPerXKey
StatusCode retrieveHistos(int nProng)
Retrieve the histograms containing BDT/RNN score distributions as a function of dependent variables.
std::pair< double, std::shared_ptr< TH2 > > m_pair_t
std::vector< SG::Accessor< char > > m_charDecors
Gaudi::Property< std::vector< float > > m_decorWPEffs2p
Gaudi::Property< bool > m_useAbsEta
Gaudi::Property< std::vector< double > > m_ScoreBounds
std::shared_ptr< std::vector< m_pair_t > > m_hists2p
Efficiency and corresponding score distributions of 2-prong taus.
~TauWPDecorator()
Destructor.
Gaudi::Property< std::string > m_file2p
TauWPDecorator(const std::string &name="TauWPDecorator")
Constructor.
Gaudi::Property< std::vector< float > > m_decorWPEffs3p
void efficiency(std::vector< double > &bins, std::vector< double > &values, const std::vector< std::string > &files, const std::string &histname, const std::string &tplotname, const std::string &label="")
IsTauFlag
Enum for IsTau flags.
Definition TauDefs.h:116
TauJet_v3 TauJet
Definition of the current "tau version".
Definition TauJet.h:17
#define unlikely(x)
TFile * file