ATLAS Offline Software
Loading...
Searching...
No Matches
Reconstruction/Jet/JetUncertainties/Root/ResolutionHelper.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
5
8
9#include "TEnv.h"
10#include "TFile.h"
11
12#include <stdexcept>
13
14namespace jet
15{
16
17ResolutionHelper::ResolutionHelper(const std::string& name, const std::string& jetDef)
18 : asg::AsgMessaging(name)
19 , m_name(name)
20 , m_jetDef(jetDef)
21 , m_isInit(false)
22 , m_smearOnlyMC(false)
23 , m_ptNomHistData(nullptr)
26 , m_ptNomHistMC(nullptr)
29 , m_fvNomHistData(nullptr)
32 , m_fvNomHistMC(nullptr)
35 , m_mQCDNomHistData(nullptr)
38 , m_mQCDNomHistMC(nullptr)
41 , m_mWZNomHistData(nullptr)
44 , m_mWZNomHistMC(nullptr)
47 , m_mHbbNomHistData(nullptr)
50 , m_mHbbNomHistMC(nullptr)
53 , m_mTopNomHistData(nullptr)
56 , m_mTopNomHistMC(nullptr)
59{ }
60
62 : asg::AsgMessaging(toCopy.m_name)
63 , m_name(toCopy.m_name)
64 , m_jetDef(toCopy.m_jetDef)
65 , m_isInit(toCopy.m_isInit)
70 , m_ptNomHistMC(!toCopy.m_ptNomHistMC ? nullptr : new UncertaintyHistogram(*toCopy.m_ptNomHistMC))
76 , m_fvNomHistMC(!toCopy.m_fvNomHistMC ? nullptr : new UncertaintyHistogram(*toCopy.m_fvNomHistMC))
88 , m_mWZNomHistMC(!toCopy.m_mWZNomHistMC ? nullptr : new UncertaintyHistogram(*toCopy.m_mWZNomHistMC))
100 , m_mTopNomHistMC(!toCopy.m_mTopNomHistMC ? nullptr : new UncertaintyHistogram(*toCopy.m_mTopNomHistMC))
103{ }
104
120
121StatusCode ResolutionHelper::parseInput(TEnv& settings, TFile* histFile, const TString& key, const TString& defaultValue, UncertaintyHistogram*& hist, CompParametrization::TypeEnum& param, CompMassDef::TypeEnum& massDef, const TString& MCtype)
122{
123 // Get the string
124 TString value = settings.GetValue(key,defaultValue);
125
126 // Check the trivial case
127 if (value == "")
128 return StatusCode::SUCCESS;
129
130 // Ensure it matches the expected format
131 if (!value.Contains(","))
132 {
133 ATH_MSG_ERROR("Key of " << key.Data() << " has an unexpected value format (missing comma): " << value.Data());
134 return StatusCode::FAILURE;
135 }
136
137 // Split the string
138 std::vector<TString> splitValue = utils::vectorize<TString>(value,", ");
139 if (splitValue.size() < 3)
140 {
141 ATH_MSG_ERROR("Key of " << key.Data() << " has unexpected value format (less than 3 strings): " << value.Data());
142 return StatusCode::FAILURE;
143 }
144 else if (splitValue.size() > 4)
145 {
146 ATH_MSG_ERROR("Key of " << key.Data() << " has unexpected value format (more than 4 strings): " << value.Data());
147 return StatusCode::FAILURE;
148 }
149
150 // Ensure that the parametrization is valid
151 param = CompParametrization::stringToEnum(splitValue.at(1));
152 if (param == CompParametrization::UNKNOWN)
153 {
154 ATH_MSG_ERROR("Key of " << key.Data() << " has unexpected parametrization value: " << splitValue.at(1));
155 return StatusCode::FAILURE;
156 }
157
158 // Ensure that the interpolation type is valid
159 Interpolate::TypeEnum interp = Interpolate::stringToEnum(splitValue.at(2));
160 if (interp == Interpolate::UNKNOWN)
161 {
162 ATH_MSG_ERROR("Key of " << key.Data() << " has unexpected interpolation type: " << splitValue.at(2));
163 return StatusCode::FAILURE;
164 }
165
166 // If this is a mass parametrization, ensure that a mass definition was specified
168 {
169 if (splitValue.size() != 4)
170 {
171 ATH_MSG_ERROR("Key of " << key.Data() << " has unexpected value format (missing mass definition): " << value.Data());
172 return StatusCode::FAILURE;
173 }
174 massDef = CompMassDef::stringToEnum(splitValue.at(3));
175 if (massDef == CompMassDef::UNKNOWN)
176 {
177 ATH_MSG_ERROR("Key of " << key.Data() << " has unexpected mass definition: " << splitValue.at(3));
178 return StatusCode::FAILURE;
179 }
180 }
181
182 // Replace generic MCTYPE string with the user-specified type if applicable
183 TString histName = splitValue.at(0);
184 histName.ReplaceAll("MCTYPE",MCtype);
185
186 // Create the histogram
187 hist = new UncertaintyHistogram(histName+"_"+m_jetDef.c_str(),interp);
188
189 // Initialize the histogram
190 if (hist->initialize(histFile).isFailure())
191 return StatusCode::FAILURE;
192
193 // Print out that we successfully read the input
194 ATH_MSG_INFO(Form(" %s: \"%s\"",key.Data(),value.Data()));
195
196 return StatusCode::SUCCESS;
197}
198
199StatusCode ResolutionHelper::initialize(TEnv& settings, TFile* histFile, const TString& MCtype)
200{
201 if (m_isInit)
202 {
203 ATH_MSG_ERROR("Blocking double-initialization: " << m_name);
204 return StatusCode::FAILURE;
205 }
206
207 // Read nominal resolution information from the configuration file
208 // In many cases (especially configs before summer 2018), there are no inputs to find
209 // As such, it is perfectly normal behaviour to read zero inputs from the file
210 // However, there are some expectations
211 // There should be no cases of data resolution without MC resolution
212 // There can be cases of MC resolution without data resolution
213 // Histograms and their parametrizations must be paired (potentially also with mass)
214
215 // Expected format:
216 // KeyString: HistName,Parametrization
217 // KeyString: HistName,Parametrization,MassDef
218 // Example:
219 // NominalPtResData: PtResData,PtAbsEta
220 // Histogram name is PtResData_JETDEF
221 // Parametrization is pT vs |eta|
222 // NominalMassResMC: MassResMC,PtMass,Calo
223 // Histogram name is MassResMC_JETDEF
224 // Parametrization is pT vs m/pt
225 // Mass definition is calorimeter (not track-assisted or combined)
226
227
228 // Start with nominal pT resolution
229 if (parseInput(settings,histFile,"NominalPtResData","",m_ptNomHistData,m_ptNomParamData,m_ptNomMassDefData,MCtype).isFailure())
230 return StatusCode::FAILURE;
231 if (parseInput(settings,histFile,"NominalPtResMC","",m_ptNomHistMC,m_ptNomParamMC,m_ptNomMassDefMC,MCtype).isFailure())
232 return StatusCode::FAILURE;
234 {
235 ATH_MSG_ERROR("There should never be a nominal data resolution without a nominal MC resolution (pT)");
236 return StatusCode::FAILURE;
237 }
238
239 // Now the nominal four-vector resolution
240 if (parseInput(settings,histFile,"NominalFourVecResData","",m_fvNomHistData,m_fvNomParamData,m_fvNomMassDefData,MCtype).isFailure())
241 return StatusCode::FAILURE;
242 if (parseInput(settings,histFile,"NominalFourVecResMC","",m_fvNomHistMC,m_fvNomParamMC,m_fvNomMassDefMC,MCtype).isFailure())
243 return StatusCode::FAILURE;
245 {
246 ATH_MSG_ERROR("There should never be a nominal data resolution without a nominal MC resolution (four-vector)");
247 return StatusCode::FAILURE;
248 }
249
250 // Now the nominal mass resolution (topology-dependent)
251 // For simplicity, this is done with separate histograms for each one
252 // Lots of code duplication, but time is of the essence, and it works
253
254 // QCD topology
255 if (parseInput(settings,histFile,"NominalMassResDataQCD","",m_mQCDNomHistData,m_mQCDNomParamData,m_mQCDNomMassDefData,MCtype).isFailure())
256 return StatusCode::FAILURE;
257 if (parseInput(settings,histFile,"NominalMassResMCQCD","",m_mQCDNomHistMC,m_mQCDNomParamMC,m_mQCDNomMassDefMC,MCtype).isFailure())
258 return StatusCode::FAILURE;
260 {
261 ATH_MSG_ERROR("There should never be a nominal data resolution without a nominal MC resolution (four-vector)");
262 return StatusCode::FAILURE;
263 }
264
265 // WZ topology
266 if (parseInput(settings,histFile,"NominalMassResDataWZ","",m_mWZNomHistData,m_mWZNomParamData,m_mWZNomMassDefData,MCtype).isFailure())
267 return StatusCode::FAILURE;
268 if (parseInput(settings,histFile,"NominalMassResMCWZ","",m_mWZNomHistMC,m_mWZNomParamMC,m_mWZNomMassDefMC,MCtype).isFailure())
269 return StatusCode::FAILURE;
271 {
272 ATH_MSG_ERROR("There should never be a nominal data resolution without a nominal MC resolution (four-vector)");
273 return StatusCode::FAILURE;
274 }
275
276 // Hbb topology
277 if (parseInput(settings,histFile,"NominalMassResDataHbb","",m_mHbbNomHistData,m_mHbbNomParamData,m_mHbbNomMassDefData,MCtype).isFailure())
278 return StatusCode::FAILURE;
279 if (parseInput(settings,histFile,"NominalMassResMCHbb","",m_mHbbNomHistMC,m_mHbbNomParamMC,m_mHbbNomMassDefMC,MCtype).isFailure())
280 return StatusCode::FAILURE;
282 {
283 ATH_MSG_ERROR("There should never be a nominal data resolution without a nominal MC resolution (four-vector)");
284 return StatusCode::FAILURE;
285 }
286
287 // Top topology
288 if (parseInput(settings,histFile,"NominalMassResDataTop","",m_mTopNomHistData,m_mTopNomParamData,m_mTopNomMassDefData,MCtype).isFailure())
289 return StatusCode::FAILURE;
290 if (parseInput(settings,histFile,"NominalMassResMCTop","",m_mTopNomHistMC,m_mTopNomParamMC,m_mTopNomMassDefMC,MCtype).isFailure())
291 return StatusCode::FAILURE;
293 {
294 ATH_MSG_ERROR("There should never be a nominal data resolution without a nominal MC resolution (four-vector)");
295 return StatusCode::FAILURE;
296 }
297
298 // Check if the user has specified if this is full correlations or MC-only
299 TString smearType = settings.GetValue("ResolutionSmearOnlyMC","");
300 if (smearType != "")
301 {
302 if (!smearType.CompareTo("true",TString::kIgnoreCase))
303 m_smearOnlyMC = true;
304 else if (!smearType.CompareTo("false",TString::kIgnoreCase))
305 m_smearOnlyMC = false;
306 else
307 {
308 ATH_MSG_ERROR("The value of ResolutionSmearOnlyMC doesn't look like the expected boolean: " << smearType.Data());
309 return StatusCode::FAILURE;
310 }
311 ATH_MSG_INFO(Form(" ResolutionSmearOnlyMC: \"%s\"",m_smearOnlyMC ? "true" : "false"));
312 }
313
314 // If we are also smearing data, we need the data histograms for any MC histogram
315 if (!m_smearOnlyMC)
316 {
318 {
319 ATH_MSG_ERROR("Requested full smearing correlations (both data and MC), but only provided the MC nominal histogram for pT");
320 return StatusCode::FAILURE;
321 }
323 {
324 ATH_MSG_ERROR("Requested full smearing correlations (both data and MC), but only provided the MC nominal histogram for fourvec");
325 return StatusCode::FAILURE;
326 }
328 {
329 ATH_MSG_ERROR("Requested full smearing correlations (both data and MC), but only provided the MC nominal histogram for mQCD");
330 return StatusCode::FAILURE;
331 }
333 {
334 ATH_MSG_ERROR("Requested full smearing correlations (both data and MC), but only provided the MC nominal histogram for mWZ");
335 return StatusCode::FAILURE;
336 }
338 {
339 ATH_MSG_ERROR("Requested full smearing correlations (both data and MC), but only provided the MC nominal histogram for mHbb");
340 return StatusCode::FAILURE;
341 }
343 {
344 ATH_MSG_ERROR("Requested full smearing correlations (both data and MC), but only provided the MC nominal histogram for mTop");
345 return StatusCode::FAILURE;
346 }
347 }
348
349
350 m_isInit = true;
351 return StatusCode::SUCCESS;
352}
353
354std::tuple<const UncertaintyHistogram*,CompParametrization::TypeEnum,CompMassDef::TypeEnum> ResolutionHelper::getNominalResolution(const CompScaleVar::TypeEnum smearType, const JetTopology::TypeEnum topology, const bool readMC) const
355{
356 // First get the resolution histogram and parametrization
357 const jet::UncertaintyHistogram* resolution = nullptr;
360
361 if (!m_isInit)
362 {
363 ATH_MSG_ERROR("Asking for the nominal resolution before initialization");
364 return std::tuple<const UncertaintyHistogram*,CompParametrization::TypeEnum,CompMassDef::TypeEnum>(NULL,CompParametrization::UNKNOWN,CompMassDef::UNKNOWN);
365 }
366
367
368 switch (smearType)
369 {
372 switch (topology)
373 {
374 case JetTopology::QCD:
375 if (readMC)
376 {
377 resolution = m_mQCDNomHistMC;
378 param = m_mQCDNomParamMC;
379 massDef = m_mQCDNomMassDefMC;
380 }
381 else
382 {
383 resolution = m_mQCDNomHistData;
384 param = m_mQCDNomParamData;
385 massDef = m_mQCDNomMassDefData;
386 }
387 break;
388
389 case JetTopology::WZ:
390 if (readMC)
391 {
392 resolution = m_mWZNomHistMC;
393 param = m_mWZNomParamMC;
394 massDef = m_mWZNomMassDefMC;
395 }
396 else
397 {
398 resolution = m_mWZNomHistData;
399 param = m_mWZNomParamData;
400 massDef = m_mWZNomMassDefData;
401 }
402 break;
403
404 case JetTopology::Hbb:
405 if (readMC)
406 {
407 resolution = m_mHbbNomHistMC;
408 param = m_mHbbNomParamMC;
409 massDef = m_mHbbNomMassDefMC;
410 }
411 else
412 {
413 resolution = m_mHbbNomHistData;
414 param = m_mHbbNomParamData;
415 massDef = m_mHbbNomMassDefData;
416 }
417 break;
418
419 case JetTopology::Top:
420 if (readMC)
421 {
422 resolution = m_mTopNomHistMC;
423 param = m_mTopNomParamMC;
424 massDef = m_mTopNomMassDefMC;
425 }
426 else
427 {
428 resolution = m_mTopNomHistData;
429 param = m_mTopNomParamData;
430 massDef = m_mTopNomMassDefData;
431 }
432 break;
433
435 // We shouldn't read this, as it was checked at a higher level
436 // Just to be safe, check it and return error code
437 ATH_MSG_ERROR("Mass resolution depends on a single jet topology, not a mixed topology");
438 return std::tuple<const UncertaintyHistogram*,CompParametrization::TypeEnum,CompMassDef::TypeEnum>(NULL,CompParametrization::UNKNOWN,CompMassDef::UNKNOWN);
439
440 default:
441 // We shouldn't read this, as it was checked at a higher level
442 // Just to be safe, check it and return error code
443 ATH_MSG_ERROR("Mass resolution depends on the jet topology, which was not specified");
444 return std::tuple<const UncertaintyHistogram*,CompParametrization::TypeEnum,CompMassDef::TypeEnum>(NULL,CompParametrization::UNKNOWN,CompMassDef::UNKNOWN);
445 }
446 break;
447
450 if (readMC)
451 {
452 resolution = m_ptNomHistMC;
453 param = m_ptNomParamMC;
454 massDef = m_ptNomMassDefMC;
455 }
456 else
457 {
458 resolution = m_ptNomHistData;
459 param = m_ptNomParamData;
460 massDef = m_ptNomMassDefData;
461 }
462 break;
463
466 if (readMC)
467 {
468 resolution = m_fvNomHistMC;
469 param = m_fvNomParamMC;
470 massDef = m_fvNomMassDefMC;
471 }
472 else
473 {
474 resolution = m_fvNomHistData;
475 param = m_fvNomParamData;
476 massDef = m_fvNomMassDefData;
477 }
478 break;
479
480 default:
481 // This is not a resolution uncertainty component
482 // We should not get here
483 // Print an erorr and return error code
484 ATH_MSG_ERROR("Asked for the smearing factor for a non-resolution component");
485 return std::tuple<const UncertaintyHistogram*,CompParametrization::TypeEnum,CompMassDef::TypeEnum>(NULL,CompParametrization::UNKNOWN,CompMassDef::UNKNOWN);
486 }
487 return std::tuple<const UncertaintyHistogram*,CompParametrization::TypeEnum,CompMassDef::TypeEnum>(resolution,param,massDef);
488}
489
491{
492 if (!m_isInit)
493 {
494 throw std::runtime_error("Asking for nominal resolution information before initialization");
495 return false;
496 }
497
498 // Check that the nominal MC histograms for the specified type exist
499 // We have already checked that the parametrizations exist for each histogram
500 // We have already checked that the data histograms exist for each MC if relevant
501 switch (type)
502 {
505 return m_ptNomHistMC != nullptr;
506
509 return m_fvNomHistMC != nullptr;
510
513 switch (topology)
514 {
515 case JetTopology::QCD:
516 return m_mQCDNomHistMC != nullptr;
517
518 case JetTopology::WZ:
519 return m_mWZNomHistMC != nullptr;
520
521 case JetTopology::Hbb:
522 return m_mHbbNomHistMC != nullptr;
523
524 case JetTopology::Top:
525 return m_mTopNomHistMC != nullptr;
526
527 default:
528 throw std::runtime_error(Form("Unexpected topology type, cannot determine if relevant info exists: %s",JetTopology::enumToString(topology).Data()));
529 return false;
530 }
531
532 default:
533 throw std::runtime_error(Form("Unexpected variable type, cannot determine if relevant info exists: %s",CompScaleVar::enumToString(type).Data()));
534 return false;
535 }
536}
537
538} // end jet namespace
539
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
@ Data
Definition BaseObject.h:11
AsgMessaging(const std::string &name)
Constructor with a name.
virtual StatusCode initialize(TEnv &settings, TFile *histFile, const TString &MCtype)
std::tuple< const UncertaintyHistogram *, CompParametrization::TypeEnum, CompMassDef::TypeEnum > getNominalResolution(const CompScaleVar::TypeEnum smearType, const JetTopology::TypeEnum topology, const bool readMC) const
bool hasRelevantInfo(const CompScaleVar::TypeEnum type, const JetTopology::TypeEnum topology) const
StatusCode parseInput(TEnv &settings, TFile *histFile, const TString &key, const TString &defaultValue, UncertaintyHistogram *&hist, CompParametrization::TypeEnum &param, CompMassDef::TypeEnum &massDef, const TString &MCtype)
ResolutionHelper(const std::string &name, const std::string &jetDef)
TypeEnum stringToEnum(const TString &type)
TypeEnum stringToEnum(const TString &type)
bool includesMass(const TypeEnum type)
TString enumToString(const TypeEnum type)
TypeEnum stringToEnum(const TString &type)
TString enumToString(const TypeEnum type)
bool vectorize(const TString &str, const TString &sep, std::vector< T > &result)