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//______________________________________________________________________________
194StatusCode TauWPDecorator::execute(xAOD::TauJet& tau) const {
195 // obtain the dependent variables of the efficiency
196 // x variable is tau pt
197 double xVariable = tau.pt();
198
199 // y variable is |eta| of leading track in electron mode, and pileup in other cases
200 double yVariable = 0.0;
201 if (m_useAbsEta) {
202 static const SG::ConstAccessor<float> acc_absEta("ABS_ETA_LEAD_TRACK");
203 yVariable = std::abs(acc_absEta(tau));
204 }
205 else {
207 if (!eventInfoDecorHandle.isPresent()) {
208 ATH_MSG_ERROR( "EventInfo decoration " << m_aveIntPerXKey << " not available!" );
209 return StatusCode::FAILURE;
210 }
211 yVariable = eventInfoDecorHandle(0);
212 }
213
214 int nTracks = tau.nTracks();
215 int nProng = nTracks;
216
217 // 0p is treated as 3p when no calibration file is not provided for 0p
218 // 2p is treated as 3p when no calibration file is not provided for 2p
219 if (nTracks == 0 && !m_hists0p) {
220 // 0p->3p mapping was done for R21 backward compatibility reasons, may want to change this
221 nProng = 3;
222 }
223 else if (nTracks == 2 && !m_hists2p) {
224 nProng = 3;
225 }
226 else if (nTracks > 2) {
227 nProng = 3;
228 }
229
230 // make sure the dependent variables are within the range of calibration histograms
231 ATH_MSG_DEBUG("original pT:\t" << xVariable);
232 if (m_useAbsEta) {
233 ATH_MSG_DEBUG("original |eta|:\t" << yVariable);
234 }
235 else {
236 ATH_MSG_DEBUG("original mu:\t" << yVariable);
237 }
238
239 xVariable = std::min(m_xMax.at(nProng), std::max(m_xMin.at(nProng), xVariable));
240 yVariable = std::min(m_yMax.at(nProng), std::max(m_yMin.at(nProng), yVariable));
241
242 ATH_MSG_DEBUG("final pT:\t" << xVariable);
243 if (m_useAbsEta) {
244 ATH_MSG_DEBUG("final |eta|:\t" << yVariable);
245 }
246 else {
247 ATH_MSG_DEBUG("final mu:\t" << yVariable);
248 }
249
250 std::shared_ptr<std::vector<m_pair_t>> histArray = nullptr;
251 if (nProng == 0) histArray = m_hists0p;
252 else if (nProng == 1) histArray = m_hists1p;
253 else if (nProng == 2) histArray = m_hists2p;
254 else histArray = m_hists3p;
255
256 std::array<double, 2> cuts = {-1.01, 1.01}; // lower and upper bounday of the score
257 std::array<double, 2> effs = {1.0, 0.0}; // efficiency corresponding to the score cut
258 bool gotLow = false; // whether lower bounday is found
259 bool gotHigh = false; // whether upper bounday is found
260
261 const SG::ConstAccessor<float> acc_score(m_scoreName);
262 double score = acc_score(tau); // original score (BDT/RNN)
263
264 // Loop over all histograms to find the lower and upper bounary of the score and corresponding efficiency
265 for (unsigned int i = 0; i < histArray->size(); ++i) {
266 std::shared_ptr<TH2> myHist = histArray->at(i).second;
267 double myCut = myHist->Interpolate(xVariable, yVariable);
268
269 if (myCut <= score && ((!gotLow) || std::abs(myCut-score) < std::abs(cuts[0]-score))) {
270 gotLow = true;
271 effs[0] = histArray->at(i).first;
272 cuts[0] = myCut;
273 }
274 else if (myCut > score && ((!gotHigh) || std::abs(myCut-score) < std::abs(cuts[1]-score))) {
275 gotHigh = true;
276 effs[1] = histArray->at(i).first;
277 cuts[1] = myCut;
278 }
279
280 if (gotLow && gotHigh){
281 ATH_MSG_VERBOSE("break @ " << myHist->GetName());
282 break;
283 }
284 }
285
286 double scoreTrans = -1111.; // flattened score
287 if (score > cuts[1]) { // should not happen
288 scoreTrans = 1 - effs[1];
289 }
290 else if (score < cuts[0]) { // score is -9999 when BDT/RNN fails
291 scoreTrans = 1 - effs[0];
292 }
293 else {
294 scoreTrans = transformScore(score, cuts[0], effs[0], cuts[1], effs[1]);
295 }
296
297 const SG::Accessor<float> acc_scoreTrans(m_scoreNameTrans);
298 acc_scoreTrans(tau) = scoreTrans;
299
300 if(m_defineWPs) {
301 // WPs in EDM
302 for (size_t wpIndex=0; wpIndex < m_EDMWPs.size(); ++wpIndex) {
303 if(nProng == 0) {
304 tau.setIsTau((xAOD::TauJetParameters::IsTauFlag) m_EDMWPs[wpIndex], scoreTrans > (1-m_EDMWPEffs0p[wpIndex]));
305 }
306 else if(nProng == 1) {
307 tau.setIsTau((xAOD::TauJetParameters::IsTauFlag) m_EDMWPs[wpIndex], scoreTrans > (1-m_EDMWPEffs1p[wpIndex]));
308 }
309 else if(nProng == 2) {
310 tau.setIsTau((xAOD::TauJetParameters::IsTauFlag) m_EDMWPs[wpIndex], scoreTrans > (1-m_EDMWPEffs2p[wpIndex]));
311 }
312 else {
313 tau.setIsTau((xAOD::TauJetParameters::IsTauFlag) m_EDMWPs[wpIndex], scoreTrans > (1-m_EDMWPEffs3p[wpIndex]));
314 }
315 }
316 // Decorate other WPs
317 for (size_t wpIndex=0; wpIndex < m_decorWPs.size(); ++wpIndex) {
318 const SG::Accessor<char>& decorator = m_charDecors[wpIndex];
319
320 if(nProng == 0) {
321 decorator(tau) = scoreTrans > (1-m_decorWPEffs0p[wpIndex]);
322 }
323 else if(nProng == 1) {
324 decorator(tau) = scoreTrans > (1-m_decorWPEffs1p[wpIndex]);
325 }
326 else if(nProng == 2) {
327 decorator(tau) = scoreTrans > (1-m_decorWPEffs2p[wpIndex]);
328 }
329 else {
330 decorator(tau) = scoreTrans > (1-m_decorWPEffs3p[wpIndex]);
331 }
332 }
333 }
334
335 return StatusCode::SUCCESS;
336}
#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
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
virtual StatusCode execute(xAOD::TauJet &tau) const override
Executation of this tool.
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
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
virtual double pt() const
The transverse momentum ( ) of the particle.
void setIsTau(TauJetParameters::IsTauFlag flag, bool value)
Set Flag for tau acceptance based on predefined arbitrary criteria.
size_t nTracks(TauJetParameters::TauTrackFlag flag=TauJetParameters::TauTrackFlag::classifiedCharged) const
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