ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Reconstruction
Jet
JetUncertainties
Root
UncertaintyHistogram.cxx
Go to the documentation of this file.
1
/*
2
Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3
*/
4
5
#include "
JetUncertainties/UncertaintyHistogram.h
"
6
#include "
JetUncertainties/Helpers.h
"
7
8
#include "TObject.h"
9
#include "TMath.h"
10
#include "TFile.h"
11
#include "TAxis.h"
12
#include "TH2.h"
13
#include "TH3.h"
14
#include "TH3F.h"
15
#include "TH3D.h"
16
17
#include <stdexcept>
18
19
namespace
jet
20
{
21
23
// //
24
// Constructor/destructor/initialization //
25
// //
27
28
UncertaintyHistogram::UncertaintyHistogram
(
const
std::string& histName,
const
Interpolate::TypeEnum
interpolate)
29
:
asg
::
AsgMessaging
(histName)
30
,
m_isInit
(false)
31
,
m_name
(histName.c_str())
32
,
m_interpolate
(interpolate)
33
,
m_histo
(nullptr)
34
,
m_nDim
(0)
35
,
m_cachedProj
()
36
{
37
if
(histName.empty())
38
JESUNC_NO_DEFAULT_CONSTRUCTOR
;
39
ATH_MSG_DEBUG
(Form(
"Creating UncertaintyHistogram named %s"
,
getName
().
Data
()));
40
}
41
42
UncertaintyHistogram::UncertaintyHistogram
(
const
TString& histName,
const
Interpolate::TypeEnum
interpolate)
43
:
UncertaintyHistogram
(
std
::
string
(histName.
Data
()),interpolate)
44
{ }
45
46
UncertaintyHistogram::UncertaintyHistogram
(
const
char
* histName,
const
Interpolate::TypeEnum
interpolate)
47
:
UncertaintyHistogram
(
std
::
string
(histName),interpolate)
48
{ }
49
50
UncertaintyHistogram::UncertaintyHistogram
(
const
UncertaintyHistogram
& toCopy)
51
:
asg
::
AsgMessaging
(Form(
"%s"
,toCopy.
m_name
.
Data
()))
52
,
m_isInit
(toCopy.
m_isInit
)
53
,
m_name
(toCopy.
m_name
)
54
,
m_interpolate
(toCopy.
m_interpolate
)
55
,
m_histo
(nullptr)
56
,
m_nDim
(toCopy.
m_nDim
)
57
,
m_cachedProj
()
58
{
59
ATH_MSG_DEBUG
(
"Creating copy of UncertaintyHistogram named "
<<
getName
().
Data
());
60
61
if
(toCopy.
m_histo
)
62
{
63
m_histo
=
dynamic_cast<
TH1*
>
(toCopy.
m_histo
->Clone());
64
if
(!
m_histo
)
65
{
66
ATH_MSG_FATAL
(
"Failed to copy uncertainty histogram for "
<<
getName
().
Data
());
67
throw
std::runtime_error(
"Failed to copy histogram in UncertaintyHistogram copy constructor"
);
68
}
69
}
70
71
if
(!toCopy.
m_cachedProj
.empty())
72
if
(
cacheProjections
().isFailure())
73
{
74
ATH_MSG_FATAL
(
"Failed to build the required cache for "
<<
getName
().
Data
());
75
throw
std::runtime_error(
"Failed to build projection cache in UncertaintyHistogram copy constructor"
);
76
}
77
}
78
79
UncertaintyHistogram::~UncertaintyHistogram
()
80
{
81
ATH_MSG_DEBUG
(Form(
"Deleting UncertaintyHistogram named %s"
,
getName
().
Data
()));
82
JESUNC_SAFE_DELETE
(
m_histo
);
83
}
84
85
StatusCode
UncertaintyHistogram::initialize
(TFile* histFile)
86
{
87
// Ensure it wasn't already initialized
88
if
(
m_isInit
)
89
{
90
ATH_MSG_ERROR
(Form(
"UncertaintyHistogram was already initialized: %s"
,
getName
().
Data
()));
91
return
StatusCode::FAILURE;
92
}
93
94
// Ensure we can read from the file
95
if
(!histFile->IsOpen())
96
{
97
ATH_MSG_ERROR
(Form(
"Histogram file is not open for reading (%s)"
,
getName
().
Data
()));
98
return
StatusCode::FAILURE;
99
}
100
101
// Find the histogram by name
102
TObject* histo = histFile->Get(
m_name
);
103
if
(!histo)
104
{
105
ATH_MSG_ERROR
(Form(
"Histogram file does not contain a histogram named %s"
,
getName
().
Data
()));
106
return
StatusCode::FAILURE;
107
}
108
109
// Ensure the object is a histogram
110
m_histo
=
dynamic_cast<
TH1*
>
(histo);
111
if
(!
m_histo
)
112
{
113
ATH_MSG_ERROR
(Form(
"Histogram file contains the expected key, but it's not a TH1* (%s)"
,
getName
().
Data
()));
114
return
StatusCode::FAILURE;
115
}
116
m_histo
->SetDirectory(
nullptr
);
117
118
// Cache dimensionality
119
m_nDim
=
m_histo
->GetDimension();
120
121
// Cache the projections if relevant
122
if
(
m_interpolate
==
Interpolate::OnlyX
||
m_interpolate
==
Interpolate::OnlyY
)
123
if
(
cacheProjections
().isFailure())
124
return
StatusCode::FAILURE;
125
126
// Print a summary
127
ATH_MSG_DEBUG
(Form(
"%s: Found histogram"
,
getName
().
Data
()));
128
129
m_isInit
=
true
;
130
return
StatusCode::SUCCESS;
131
}
132
133
134
136
// //
137
// Histogram information access //
138
// //
140
141
double
UncertaintyHistogram::getValue
(
const
double
var1)
const
142
{
143
if
(
m_nDim
!= 1)
144
{
145
ATH_MSG_ERROR
(Form(
"Wrong dimensionality - asked for 1D for a %dD histo (%s)"
,
m_nDim
,
getName
().
Data
()));
146
return
false
;
147
}
148
return
readHisto
(var1);
149
}
150
151
double
UncertaintyHistogram::getValue
(
const
double
var1,
const
double
var2)
const
152
{
153
if
(
m_nDim
!= 2)
154
{
155
ATH_MSG_ERROR
(Form(
"Wrong dimensionality - asked for 2D for a %dD histo (%s)"
,
m_nDim
,
getName
().
Data
()));
156
return
false
;
157
}
158
return
readHisto
(var1,var2);
159
}
160
161
double
UncertaintyHistogram::getValue
(
const
double
var1,
const
double
var2,
const
double
var3)
const
162
{
163
if
(
m_nDim
!= 3)
164
{
165
ATH_MSG_ERROR
(Form(
"Wrong dimensionality - asked for 3D for a %dD histo (%s)"
,
m_nDim
,
getName
().
Data
()));
166
return
false
;
167
}
168
return
readHisto
(var1,var2,var3);
169
}
170
171
173
// //
174
// Histogram reading helpers //
175
// //
177
178
double
UncertaintyHistogram::readHisto
(
const
double
var1,
const
double
var2,
const
double
var3)
const
179
{
180
// Ensure the component was initialized
181
if
(!
m_isInit
)
182
{
183
ATH_MSG_ERROR
(Form(
"Component was not initialized (%s)"
,
getName
().
Data
()));
184
return
JESUNC_ERROR_CODE
;
185
}
186
187
188
// Ensure that the histogram exists
189
if
(!
m_histo
)
190
{
191
ATH_MSG_ERROR
(Form(
"Histogram to read is NULL (%s)"
,
getName
().
Data
()));
192
return
JESUNC_ERROR_CODE
;
193
}
194
195
// Check first dimension boundaries, always applicable
196
const
double
valX =
checkBoundariesByBin
(std::as_const(*m_histo).GetXaxis(),
m_histo
->GetNbinsX(),var1);
197
if
(
m_nDim
== 1)
198
{
199
switch
(
m_interpolate
)
200
{
201
case
Interpolate::Full
:
202
case
Interpolate::OnlyX
:
203
return
JetHelpers::Interpolate
(
m_histo
,valX);
204
205
case
Interpolate::None
:
206
return
m_histo
->GetBinContent(std::as_const(*m_histo).GetXaxis()->FindFixBin(valX));
207
208
default
:
209
ATH_MSG_ERROR
(
"Unsupported histogram interpolation type of \""
<<
Interpolate::enumToString
(
m_interpolate
).
Data
() <<
" for 1D histogram named "
<<
m_name
.Data());
210
return
JESUNC_ERROR_CODE
;
211
}
212
}
213
214
// Check second dimension boundaries, if applicable
215
const
double
valY =
checkBoundariesByBin
(std::as_const(*m_histo).GetYaxis(),
m_histo
->GetNbinsY(),var2);
216
if
(
m_nDim
== 2)
217
{
218
// We need a 2D histogram for the projection calls
219
switch
(
m_interpolate
)
220
{
221
case
Interpolate::Full
:
222
return
JetHelpers::Interpolate
(
m_histo
,valX,valY);
223
224
case
Interpolate::OnlyX
:
225
// Interpolate on the x projection for a given Y bin
226
return
JetHelpers::Interpolate
(
m_cachedProj
.at(0).at(std::as_const(*m_histo).GetYaxis()->FindFixBin(valY)).get(),valX);
227
228
case
Interpolate::OnlyY
:
229
// Interpolate on the y projection for a given X bin
230
return
JetHelpers::Interpolate
(
m_cachedProj
.at(0).at(std::as_const(*m_histo).GetXaxis()->FindFixBin(valX)).get(),valY);
231
232
case
Interpolate::None
:
233
return
m_histo
->GetBinContent(std::as_const(*m_histo).GetXaxis()->FindFixBin(valX),
234
std::as_const(*m_histo).GetYaxis()->FindFixBin(valY));
235
236
default
:
237
ATH_MSG_ERROR
(
"Unsupported histogram interpolation type of \""
<<
Interpolate::enumToString
(
m_interpolate
).
Data
() <<
" for 1D histogram named "
<<
m_name
.Data());
238
return
JESUNC_ERROR_CODE
;
239
}
240
}
241
242
// Check third dimension boundaries, if applicable
243
const
double
valZ =
checkBoundariesByBin
(std::as_const(*m_histo).GetZaxis(),
m_histo
->GetNbinsZ(),var3);
244
245
switch
(
m_interpolate
)
246
{
247
case
Interpolate::Full
:
248
return
JetHelpers::Interpolate
(
m_histo
,valX,valY,valZ);
249
250
case
Interpolate::OnlyX
:
251
// Interpolate on the x projection for a given y,z bin
252
return
JetHelpers::Interpolate
(
m_cachedProj
.at(std::as_const(*m_histo).GetYaxis()->FindFixBin(valY)).at(std::as_const(*m_histo).GetZaxis()->FindFixBin(valZ)).get(),valX);
253
254
case
Interpolate::OnlyY
:
255
// Interpolate on the y projection for a given x,z bin
256
return
JetHelpers::Interpolate
(
m_cachedProj
.at(std::as_const(*m_histo).GetXaxis()->FindFixBin(valX)).at(std::as_const(*m_histo).GetZaxis()->FindFixBin(valZ)).get(),valY);
257
258
case
Interpolate::None
:
259
return
m_histo
->GetBinContent(std::as_const(*m_histo).GetXaxis()->FindFixBin(valX),
260
std::as_const(*m_histo).GetYaxis()->FindFixBin(valY),
261
std::as_const(*m_histo).GetZaxis()->FindFixBin(valZ));
262
263
default
:
264
ATH_MSG_ERROR
(
"Unsupported histogram interpolation type of \""
<<
Interpolate::enumToString
(
m_interpolate
).
Data
() <<
" for 1D histogram named "
<<
m_name
.Data());
265
return
JESUNC_ERROR_CODE
;
266
}
267
}
268
269
270
double
UncertaintyHistogram::checkBoundariesByBin
(
const
TAxis* axis,
const
int
numBins,
const
double
valInput)
const
271
{
272
double
val = valInput;
273
274
// Root histogram binning:
275
// bin 0 = underflow bin
276
// bin 1 = first actual bin
277
// bin N = last actual bin
278
// bin N+1 = overflow bin
279
const
int
binIndex = axis->FindBin(valInput);
280
if
(binIndex < 1)
281
val = axis->GetBinLowEdge(1);
282
else
if
(binIndex > numBins)
283
{
284
// Don't use the upper edge as floating point can make it roll into the next bin (which is overflow)
285
// Instead, use the last bin width to go slightly within the boundary
286
// An offset of 1.e-3*binWidth is negligible for physics as the values don't change fast, but above floating point precision
287
val = (1.-1.e-3)*axis->GetBinWidth(numBins)+axis->GetBinLowEdge(numBins);
288
}
289
290
return
val;
291
}
292
293
double
UncertaintyHistogram::checkBoundaries
(
const
TAxis* axis,
const
int
numBins,
const
double
valInput)
const
294
{
295
const
static
int
maxNumWarn = 0;
//100
296
static
std::atomic<int> numWarn = 0;
297
298
// Bins are structured for [lowEdge,highEdge)
299
// As such, do not need to worry about equality sign for low edge
300
// However, do need to check equality sign for high edge
301
// High edge is expected and supported (no warning needed)
302
float
val = valInput;
303
const
double
lowVal = axis->GetBinLowEdge(1);
304
const
double
highVal = axis->GetBinLowEdge(numBins+1);
305
if
(val < lowVal || val >= highVal)
306
{
307
if
(val != highVal && ++numWarn < maxNumWarn)
308
ATH_MSG_WARNING
(Form(
"Variable value is %f, outside of the axis range of (%f,%f) for %s. "
309
"Using closest valid value."
,val,lowVal,highVal,
getName
().
Data
())
310
<<
" (Only first "
<< maxNumWarn <<
" instances printed, this is "
<< numWarn <<
")"
);
311
312
// Watch for the boundary sign (controls the scale factor)
313
if
(val < lowVal)
314
val = lowVal>0 ? (1.0+1.e-4)*lowVal : (1.0-1.e-4)*lowVal;
315
else
316
val = highVal>0 ? (1.0-1.e-4)*highVal : (1.0+1.e-4)*highVal;
317
}
318
319
return
val;
320
}
321
322
StatusCode
UncertaintyHistogram::cacheProjections
()
323
{
324
// Ensure the histogram exists
325
if
(!
m_histo
)
326
{
327
ATH_MSG_FATAL
(
"Cannot cache histogram as it doesn't exist: "
<<
m_name
.Data());
328
return
StatusCode::FAILURE;
329
}
330
331
// Ensure the number of dimensions is sane
332
if
(
m_histo
->GetDimension() < 1 ||
m_histo
->GetDimension() > 3)
333
{
334
ATH_MSG_FATAL
(
"Unsupported histogram dimensionality for projection caching: "
<<
m_histo
->GetDimension());
335
return
StatusCode::FAILURE;
336
}
337
338
// Ensure the cache doesn't already exist
339
if
(!
m_cachedProj
.empty())
340
{
341
ATH_MSG_FATAL
(
"Cannot cache histogram as the cache is non-empty: "
<<
m_name
.Data());
342
return
StatusCode::FAILURE;
343
}
344
345
// Protect vs Interpolate
346
switch
(
m_interpolate
)
347
{
348
case
Interpolate::OnlyX
:
349
// Simple case of 1D
350
if
(
m_histo
->GetDimension() == 1)
351
return
StatusCode::SUCCESS;
352
break
;
353
354
case
Interpolate::OnlyY
:
355
// Failure case of 1D
356
if
(
m_histo
->GetDimension() == 1)
357
{
358
ATH_MSG_FATAL
(
"Cannot project in Y for a 1D histogram: "
<<
m_name
.Data());
359
return
StatusCode::FAILURE;
360
}
361
break
;
362
363
default
:
364
ATH_MSG_FATAL
(
"The interpolation type is not supported for caching: "
<<
m_name
.Data());
365
return
StatusCode::FAILURE;
366
}
367
368
// If we got here, then the request makes sense
369
// Start the projections
370
// Intentionally include underflow and overflow bins
371
// This keeps the same indexing scheme as root
372
// Avoids confusion and problems later at cost of a small amount of RAM
373
if
(
m_histo
->GetDimension() == 2)
374
{
375
// Prepare to cache
376
TH2* localHist =
dynamic_cast<
TH2*
>
(
m_histo
);
377
m_cachedProj
.resize(1);
// 2D is a single slice of 3D
378
if
(!localHist)
379
{
380
ATH_MSG_FATAL
(
"Failed to convert histogram to a TH2, please check inputs: "
<<
m_name
.Data());
381
return
StatusCode::FAILURE;
382
}
383
384
// Create the projections
385
if
(
m_interpolate
==
Interpolate::OnlyX
)
386
{
387
for
(Long64_t binY = 0; binY < localHist->GetNbinsY()+1; ++binY)
388
{
389
// Single bin of Y, interpolate across X
390
m_cachedProj
.at(0).emplace_back(localHist->ProjectionX(Form(
"projx_%lld"
,binY),binY,binY));
391
}
392
}
393
else
if
(
m_interpolate
==
Interpolate::OnlyY
)
394
{
395
for
(Long64_t binX = 0; binX < localHist->GetNbinsX()+1; ++binX)
396
{
397
// Single bin of X, interpolate across Y
398
m_cachedProj
.at(0).emplace_back(localHist->ProjectionY(Form(
"projy_%lld"
,binX),binX,binX));
399
}
400
}
401
else
402
{
403
// We shouldn't make it here due to earlier checks
404
ATH_MSG_FATAL
(
"Unexpected interpolation type, somehow escaped earlier checks: "
<<
m_name
.Data());
405
return
StatusCode::FAILURE;
406
}
407
}
408
else
if
(
m_histo
->GetDimension() == 3)
409
{
410
// Prepare to cache
411
TH3* localHist =
dynamic_cast<
TH3*
>
(
m_histo
);
412
if
(!localHist)
413
{
414
ATH_MSG_FATAL
(
"Failed to convert histogram to a TH3, please check inputs: "
<<
m_name
.Data());
415
return
StatusCode::FAILURE;
416
}
417
418
// Create the projections
419
if
(
m_interpolate
==
Interpolate::OnlyX
)
420
{
421
m_cachedProj
.resize(localHist->GetNbinsY()+1);
// 3D is a full double-index scan
422
for
(Long64_t binY = 0; binY < localHist->GetNbinsY()+1; ++binY)
423
{
424
for
(Long64_t binZ = 0; binZ < localHist->GetNbinsZ()+1; ++binZ)
425
{
426
// Single bin of Y-Z, interpolate across X
427
m_cachedProj
.at(binY).emplace_back(localHist->ProjectionX(Form(
"projx_%lld_%lld"
,binY,binZ),binY,binY,binZ,binZ));
428
}
429
}
430
}
431
else
if
(
m_interpolate
==
Interpolate::OnlyY
)
432
{
433
m_cachedProj
.resize(localHist->GetNbinsX()+1);
// 3D is a full double-index scan
434
for
(Long64_t binX = 0; binX < localHist->GetNbinsX()+1; ++binX)
435
{
436
for
(Long64_t binZ = 0; binZ < localHist->GetNbinsZ()+1; ++binZ)
437
{
438
// Single bin of X-Z, interpolate across Y
439
m_cachedProj
.at(binX).emplace_back(localHist->ProjectionY(Form(
"projy_%lld_%lld"
,binX,binZ),binX,binX,binZ,binZ));
440
}
441
}
442
}
443
else
444
{
445
// We shouldn't make it here due to earlier checks
446
ATH_MSG_FATAL
(
"Unexpected interpolation type, somehow escaped earlier checks: "
<<
m_name
.Data());
447
return
StatusCode::FAILURE;
448
}
449
}
450
else
451
{
452
// We shouldn't make it here due to earlier checks
453
ATH_MSG_FATAL
(
"Unexpected dimensionality: "
<<
m_histo
->GetDimension());
454
return
StatusCode::FAILURE;
455
}
456
457
// Ensure that ROOT doesn't try to take posession of any of the projections
458
for
(
size_t
index
= 0;
index
<
m_cachedProj
.size(); ++
index
)
459
{
460
for
(
auto
& hist :
m_cachedProj
.at(
index
))
461
{
462
hist->SetDirectory(
nullptr
);
463
}
464
}
465
466
// All done
467
return
StatusCode::SUCCESS;
468
}
469
470
}
// end jet namespace
471
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition
AthMsgStreamMacros.h:33
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition
AthMsgStreamMacros.h:34
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition
AthMsgStreamMacros.h:32
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition
AthMsgStreamMacros.h:29
Data
@ Data
Definition
BaseObject.h:11
Helpers.h
JESUNC_ERROR_CODE
#define JESUNC_ERROR_CODE
Definition
Reconstruction/Jet/JetUncertainties/JetUncertainties/Helpers.h:22
JESUNC_NO_DEFAULT_CONSTRUCTOR
#define JESUNC_NO_DEFAULT_CONSTRUCTOR
Definition
Reconstruction/Jet/JetUncertainties/JetUncertainties/Helpers.h:23
JESUNC_SAFE_DELETE
#define JESUNC_SAFE_DELETE(T)
Definition
Reconstruction/Jet/JetUncertainties/JetUncertainties/Helpers.h:24
UncertaintyHistogram.h
asg::AsgMessaging::AsgMessaging
AsgMessaging(const std::string &name)
Constructor with a name.
Definition
AsgMessaging.cxx:17
jet::UncertaintyHistogram::m_histo
TH1 * m_histo
Definition
UncertaintyHistogram.h:51
jet::UncertaintyHistogram::initialize
virtual StatusCode initialize(TFile *histFile)
Definition
UncertaintyHistogram.cxx:85
jet::UncertaintyHistogram::m_name
const TString m_name
Definition
UncertaintyHistogram.h:49
jet::UncertaintyHistogram::checkBoundaries
double checkBoundaries(const TAxis *axis, const int numBins, const double valInput) const
Definition
UncertaintyHistogram.cxx:293
jet::UncertaintyHistogram::m_nDim
int m_nDim
Definition
UncertaintyHistogram.h:52
jet::UncertaintyHistogram::cacheProjections
StatusCode cacheProjections()
Definition
UncertaintyHistogram.cxx:322
jet::UncertaintyHistogram::getValue
double getValue(const double var1) const
Definition
UncertaintyHistogram.cxx:141
jet::UncertaintyHistogram::readHisto
double readHisto(const double var1, const double var2=0, const double var3=0) const
Definition
UncertaintyHistogram.cxx:178
jet::UncertaintyHistogram::~UncertaintyHistogram
virtual ~UncertaintyHistogram()
Definition
UncertaintyHistogram.cxx:79
jet::UncertaintyHistogram::getName
const TString & getName() const
Definition
UncertaintyHistogram.h:36
jet::UncertaintyHistogram::m_cachedProj
std::vector< std::vector< std::unique_ptr< TH1 > > > m_cachedProj
Definition
UncertaintyHistogram.h:56
jet::UncertaintyHistogram::m_isInit
bool m_isInit
Definition
UncertaintyHistogram.h:48
jet::UncertaintyHistogram::UncertaintyHistogram
UncertaintyHistogram(const std::string &histName, const Interpolate::TypeEnum interpolate)
Definition
UncertaintyHistogram.cxx:28
jet::UncertaintyHistogram::checkBoundariesByBin
double checkBoundariesByBin(const TAxis *axis, const int numBins, const double valInput) const
Definition
UncertaintyHistogram.cxx:270
jet::UncertaintyHistogram::m_interpolate
const Interpolate::TypeEnum m_interpolate
Definition
UncertaintyHistogram.h:50
string
STL class.
JetHelpers::Interpolate
double Interpolate(const TH1 *histo, const double x)
Definition
JetHelpers.cxx:16
asg
Definition
DataHandleTestTool.h:28
index
Definition
index.py:1
jet::Interpolate::enumToString
TString enumToString(const TypeEnum type)
Definition
UncertaintyEnum.cxx:645
jet::Interpolate::TypeEnum
TypeEnum
Definition
UncertaintyEnum.h:241
jet::Interpolate::None
@ None
Definition
UncertaintyEnum.h:243
jet::Interpolate::Full
@ Full
Definition
UncertaintyEnum.h:244
jet::Interpolate::OnlyY
@ OnlyY
Definition
UncertaintyEnum.h:246
jet::Interpolate::OnlyX
@ OnlyX
Definition
UncertaintyEnum.h:245
jet
Definition
JetCalibTools_PlotJESFactors.cxx:23
std
STL namespace.
Generated on
for ATLAS Offline Software by
1.17.0