ATLAS Offline Software
Loading...
Searching...
No Matches
CommonEfficiencyTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Framework include(s):
7
8// local include(s)
11
12// ROOT include(s)
13#include "TF1.h"
14#include "TH1.h"
15#include "TH2.h"
16#include "TROOT.h"
17#include "TClass.h"
18
19using namespace TauAnalysisTools;
20
21/*
22 This tool acts as a common tool to apply efficiency scale factors and
23 uncertainties. By default, only nominal scale factors without systematic
24 variations are applied. Unavailable systematic variations are ignored, meaning
25 that the tool only returns the nominal value. In case the one available
26 systematic is requested, the smeared scale factor is computed as:
27 - sf = sf_nominal +/- n * uncertainty
28
29 where n is in general 1 (representing a 1 sigma smearing), but can be any
30 arbitrary value. In case multiple systematic variations are passed they are
31 added in quadrature. Note that it's currently only supported if all are up or
32 down systematics.
33
34 The tool reads in root files including TH2 histograms which need to fullfil a
35 predefined structure:
36
37 scale factors:
38 - sf_<workingpoint>_<prongness>p
39 uncertainties:
40 - <NP>_<up/down>_<workingpoint>_<prongness>p (for asymmetric uncertainties)
41 - <NP>_<workingpoint>_<prongness>p (for symmetric uncertainties)
42
43 where the <workingpoint> (e.g. loose/medium/tight) fields may be
44 optional. <prongness> represents either 1 or 3, whereas 3 is currently used
45 for multiprong in general. The <NP> fields are names for the type of nuisance
46 parameter (e.g. STAT or SYST), note the tool decides whethe the NP is a
47 recommended or only an available systematic based on the first character:
48 - uppercase -> recommended
49 - lowercase -> available
50 This magic happens here:
51 - CommonEfficiencyTool::generateSystematicSets()
52
53 In addition the root input file can also contain objects of type TF1 that can
54 be used to provide kind of unbinned scale factors or systematics. The major
55 usecase for now is the high-pt uncertainty for the tau ID and tau
56 reconstruction.
57
58 The files may also include TNamed objects which is used to define how x and
59 y-axes should be treated. By default the x-axis is given in units of tau-pT in
60 GeV and the y-axis is given as tau-eta. If there is for example a TNamed
61 object with name "Yaxis" and title "|eta|" the y-axis is treated in units of
62 absolute tau eta. All this is done in:
63 - void CommonEfficiencyTool::ReadInputs(TFile* fFile)
64
65*/
66
67//______________________________________________________________________________
69 : asg::AsgTool( sName )
70 , m_mSF(nullptr)
71 , m_sSystematicSet(nullptr)
74 , m_sSFHistName("sf")
75 , m_bNoMultiprong(false)
77 , m_bSFIsAvailable(false)
79{
80}
81
82/*
83 need to clear the map of histograms cause we have the ownership, not ROOT
84*/
86{
87 if (m_mSF)
88 for (auto mEntry : *m_mSF)
89 delete std::get<0>(mEntry.second);
90}
91
92/*
93 - Find the root files with scale factor inputs on cvmfs using PathResolver
94 (more info here:
95 https://twiki.cern.ch/twiki/bin/viewauth/AtlasComputing/PathResolver)
96 - Call further functions to process and define NP strings and so on
97 - Configure to provide nominal scale factors by default
98*/
100{
101 ATH_MSG_INFO( "Initializing CommonEfficiencyTool" );
102 // only read in histograms once
103 if (m_mSF==nullptr)
104 {
105 std::string sInputFilePath = PathResolverFindCalibFile(m_sInputFilePath);
106
107 m_mSF = std::make_unique< tSFMAP >();
108 std::unique_ptr< TFile > fSF( TFile::Open( sInputFilePath.c_str(), "READ" ) );
109 if(!fSF)
110 {
111 ATH_MSG_FATAL("Could not open file " << sInputFilePath.c_str());
112 return StatusCode::FAILURE;
113 }
114 ReadInputs(*fSF);
115 fSF->Close();
116 }
117
118 // needed later on in generateSystematicSets(), maybe move it there
119 std::vector<std::string> vInputFilePath;
120 split(m_sInputFilePath,'/',vInputFilePath);
121 m_sInputFileName = vInputFilePath.back();
122
124
125 if (!m_sWP.empty())
126 m_sSFHistName = "sf_"+m_sWP;
127
128 // load empty systematic variation by default
129 if (applySystematicVariation(CP::SystematicSet()) != StatusCode::SUCCESS )
130 return StatusCode::FAILURE;
131
132 return StatusCode::SUCCESS;
133}
134
135/*
136 Retrieve the scale factors and if requested the values for the NP's and add
137 this stuff in quadrature. Finally return sf_nom +/- n*uncertainty
138*/
139
140//______________________________________________________________________________
142 double& dEfficiencyScaleFactor, unsigned int /*iRunNumber*/)
143{
144 // check which true state is requested
146 {
147 dEfficiencyScaleFactor = 1.;
149 }
150
151 // check if 1 prong
152 if (m_bNoMultiprong && xTau.nTracks() != 1)
153 {
154 dEfficiencyScaleFactor = 1.;
156 }
157
158 // get decay mode or prong extension for histogram name
159 std::string sMode;
161 {
162 int iDecayMode = -1;
164 sMode = ConvertDecayModeToString(iDecayMode);
165 if (sMode.empty())
166 {
167 ATH_MSG_WARNING("Found tau with unknown decay mode. Skip efficiency correction.");
169 }
170 }
171 else
172 {
173 // skip taus which are not 1 or 3 prong
174 if( xTau.nTracks() != 1 && xTau.nTracks() != 3) {
175 dEfficiencyScaleFactor = 1.;
177 }
178
179 sMode = ConvertProngToString(xTau.nTracks());
180 }
181
182 std::string sHistName;
183 if(m_doTauTrig){
184 sHistName = "sf_all_"+m_sWP+sMode;
185 } else {
186 sHistName = m_sSFHistName + sMode;
187 }
188
189 // get standard scale factor
190 CP::CorrectionCode tmpCorrectionCode = getValue(sHistName,
191 xTau,
192 dEfficiencyScaleFactor);
193 // return correction code if histogram is not available
194 if (tmpCorrectionCode != CP::CorrectionCode::Ok)
195 return tmpCorrectionCode;
196
197 // skip further process if systematic set is empty
198 if (m_sSystematicSet->empty())
200
201 // get uncertainties summed in quadrature
202 double dTotalSystematic2 = 0.;
203 double dDirection = 0.;
204 for (auto syst : *m_sSystematicSet)
205 {
206 // check if systematic is available
207 auto it = m_mSystematicsHistNames.find(syst.basename());
208
209 // get uncertainty value
210 double dUncertaintySyst = 0.;
211
212 // needed for up/down decision
213 dDirection = syst.parameter();
214
215 // build up histogram name
216 sHistName = it->second;
217 if (dDirection>0.) sHistName+="_up";
218 else sHistName+="_down";
219
220 if(m_doTauTrig){ sHistName+="_all"; }
221
222 if (!m_sWP.empty()) sHistName+="_"+m_sWP;
223 sHistName += sMode;
224
225
226 // filter unwanted combinations
227 if( (sHistName.find("3P") != std::string::npos && sHistName.find("1p") != std::string::npos) ||
228 (sHistName.find("1P") != std::string::npos && sHistName.find("3p") != std::string::npos))
229 continue;
230
231 if( (sHistName.find("1520") != std::string::npos && sHistName.find("loose") != std::string::npos) ){
232 continue;
233 }
234
235 // get the uncertainty from the histogram
236 tmpCorrectionCode = getValue(sHistName,
237 xTau,
238 dUncertaintySyst);
239
240 // return correction code if histogram is not available
241 if (tmpCorrectionCode != CP::CorrectionCode::Ok)
242 return tmpCorrectionCode;
243
244 // scale uncertainty with direction, i.e. +/- n*sigma
245 dUncertaintySyst *= dDirection;
246
247 // square uncertainty and add to total uncertainty
248 dTotalSystematic2 += dUncertaintySyst * dUncertaintySyst;
249 }
250
251 // now use dDirection to use up/down uncertainty
252 dDirection = (dDirection > 0.) ? 1. : -1.;
253
254 // finally apply uncertainty (eff * ( 1 +/- \sum )
255 dEfficiencyScaleFactor *= 1. + dDirection * std::sqrt(dTotalSystematic2);
256
258}
259
260/*
261 Get scale factor from getEfficiencyScaleFactor and decorate it to the
262 tau. Note that this can only be done if the variable name is not already used,
263 e.g. if the variable was already decorated on a previous step (enured by the
264 m_bSFIsAvailableChecked check).
265
266 Technical note: cannot use `static SG::Decorator` as we will have
267 multiple instances of this tool with different decoration names.
268*/
269//______________________________________________________________________________
271 unsigned int iRunNumber)
272{
273 double dSf = 0.;
274
277 {
278 m_bSFIsAvailable = decor.isAvailable(xTau);
281 {
282 ATH_MSG_DEBUG(m_sVarName << " decoration is available on first tau processed, switched off applyEfficiencyScaleFactor for further taus.");
283 ATH_MSG_DEBUG("If an application of efficiency scale factors needs to be redone, please pass a shallow copy of the original tau.");
284 }
285 }
288
289 // retrieve scale factor
290 CP::CorrectionCode tmpCorrectionCode = getEfficiencyScaleFactor(xTau, dSf, iRunNumber);
291 // adding scale factor to tau as decoration
292 decor(xTau) = dSf;
293
294 return tmpCorrectionCode;
295}
296
297/*
298 standard check if a systematic is available
299*/
300//______________________________________________________________________________
302{
304 return sys.find(systematic) != sys.end();
305}
306
307/*
308 standard way to return systematics that are available (including recommended
309 systematics)
310*/
311//______________________________________________________________________________
316
317/*
318 standard way to return systematics that are recommended
319*/
320//______________________________________________________________________________
325
326/*
327 Configure the tool to use a systematic variation for further usage, until the
328 tool is reconfigured with this function. The passed systematic set is checked
329 for sanity:
330 - unsupported systematics are skipped
331 - only combinations of up or down supported systematics is allowed
332 - don't mix recommended systematics with other available systematics, cause
333 sometimes recommended are a quadratic sum of the other variations,
334 e.g. TOTAL=(SYST^2 + STAT^2)^0.5
335*/
336//______________________________________________________________________________
338{
339
340 // first check if we already know this systematic configuration
341 auto itSystematicSet = m_mSystematicSets.find(sSystematicSet);
342 if (itSystematicSet != m_mSystematicSets.end())
343 {
344 m_sSystematicSet = &itSystematicSet->first;
345 return StatusCode::SUCCESS;
346 }
347
348 // sanity checks if systematic set is supported
349 double dDirection = 0.;
350 CP::SystematicSet sSystematicSetAvailable;
351 for (auto sSyst : sSystematicSet)
352 {
353 // check if systematic is available
354 auto it = m_mSystematicsHistNames.find(sSyst.basename());
355 if (it == m_mSystematicsHistNames.end())
356 {
357 ATH_MSG_VERBOSE("unsupported systematic variation: "<< sSyst.basename()<<"; skipping this one");
358 continue;
359 }
360
361
362 if (sSyst.parameter() * dDirection < 0)
363 {
364 ATH_MSG_ERROR("unsupported set of systematic variations, you should either use only \"UP\" or only \"DOWN\" systematics in one set!");
365 ATH_MSG_ERROR("systematic set will not be applied");
366 return StatusCode::FAILURE;
367 }
368 dDirection = sSyst.parameter();
369
370 if ((m_sRecommendedSystematics.find(sSyst.basename()) != m_sRecommendedSystematics.end()) and sSystematicSet.size() > 1)
371 {
372 ATH_MSG_ERROR("unsupported set of systematic variations, you should not combine \"TAUS_{TRUE|FAKE}_EFF_*_TOTAL\" with other systematic variations!");
373 ATH_MSG_ERROR("systematic set will not be applied");
374 return StatusCode::FAILURE;
375 }
376
377 // finally add the systematic to the set of systematics to process
378 sSystematicSetAvailable.insert(sSyst);
379 }
380
381 // store this calibration for future use, and make it current
382 m_sSystematicSet = &m_mSystematicSets.insert(std::pair<CP::SystematicSet,std::string>(sSystematicSetAvailable, sSystematicSet.name())).first->first;
383
384 return StatusCode::SUCCESS;
385}
386
387//=================================PRIVATE-PART=================================
388std::string CommonEfficiencyTool::ConvertProngToString(const int fProngness) const
389{
390 return fProngness == 1 ? "_1p" : "_3p";
391}
392
393/*
394 decay mode converter
395*/
396//______________________________________________________________________________
397std::string CommonEfficiencyTool::ConvertDecayModeToString(const int iDecayMode) const
398{
399 switch(iDecayMode)
400 {
402 return "_r1p0n";
404 return "_r1p1n";
406 return "_r1pXn";
408 return "_r3p0n";
410 return "_r3pXn";
411 default:
412 return "";
413 }
414}
415
416/*
417 Read in a root file and store all objects to a map of this type:
418 std::map<std::string, tTupleObjectFunc > (see header) It's basically a map of
419 the histogram name and a function pointer based on the TObject type (TH1F,
420 TH1D, TF1). This is resolved in the function:
421 - CommonEfficiencyTool::addHistogramToSFMap
422 Further this function figures out the axis definition (see description on the
423 top)
424*/
425//______________________________________________________________________________
426void CommonEfficiencyTool::ReadInputs(const TFile& fFile)
427{
428 m_mSF->clear();
429
430 // initialize function pointer
431 m_fX = &finalTauPt;
432 m_fY = &finalTauEta;
433
434 TKey *kKey;
435 TIter itNext(fFile.GetListOfKeys());
436 while ((kKey = (TKey*)itNext()))
437 {
438 // parse file content for objects of type TNamed, check their title for
439 // known strings and reset funtion pointer
440 std::string sKeyName = kKey->GetName();
441 if (sKeyName == "Xaxis")
442 {
443 TNamed* tObj = (TNamed*)kKey->ReadObj();
444 std::string sTitle = tObj->GetTitle();
445 delete tObj;
446 if (sTitle == "P" || sTitle == "PFinalCalib")
447 {
448 m_fX = &finalTauP;
449 ATH_MSG_DEBUG("using full momentum for x-axis");
450 }
451 if (sTitle == "TruthDecayMode")
452 {
454 ATH_MSG_DEBUG("using truth decay mode for x-axis");
455 }
456 if (sTitle == "truth pt")
457 {
458 m_fX = &truthTauPt;
459 ATH_MSG_DEBUG("using truth pT for x-axis");
460 }
461 if (sTitle == "truth visible pt")
462 {
464 ATH_MSG_DEBUG("using truth visible pT for x-axis");
465 }
466 if (sTitle == "|eta|")
467 {
469 ATH_MSG_DEBUG("using absolute tau eta for x-axis");
470 }
471
472 continue;
473 }
474 else if (sKeyName == "Yaxis")
475 {
476 TNamed* tObj = (TNamed*)kKey->ReadObj();
477 std::string sTitle = tObj->GetTitle();
478 delete tObj;
479 if (sTitle == "track-eta")
480 {
482 ATH_MSG_DEBUG("using leading track eta for y-axis");
483 }
484 else if (sTitle == "|eta|")
485 {
487 ATH_MSG_DEBUG("using absolute tau eta for y-axis");
488 }
489 else if (sTitle == "mu")
490 {
491 m_fY = [this](const xAOD::TauJet&) -> double {
492 const xAOD::EventInfo* xEventInfo = nullptr;
493 if (evtStore()->retrieve(xEventInfo,"EventInfo").isFailure()) {
494 return 0;
495 }
496 if (xEventInfo->runNumber()==284500)
497 {
498 return xEventInfo->averageInteractionsPerCrossing();
499 }
500 else if (xEventInfo->runNumber()==300000 || xEventInfo->runNumber()==310000)
501 {
502 return xEventInfo->actualInteractionsPerCrossing();
503 }
504 return 0;
505 };
506 ATH_MSG_DEBUG("using average mu for y-axis");
507 }
508 else if (sTitle == "truth |eta|")
509 {
511 ATH_MSG_DEBUG("using absolute truth tau eta for y-axis");
512 }
513 continue;
514 }
515
516 std::vector<std::string> vSplitName = {};
517 split(sKeyName,'_',vSplitName);
518 if (vSplitName[0] == "sf")
519 {
520 addHistogramToSFMap(kKey, sKeyName);
521 }
522 else
523 {
524 // std::string sDirection = vSplitName[1];
525 if (sKeyName.find("_up_") != std::string::npos or sKeyName.find("_down_") != std::string::npos)
526 addHistogramToSFMap(kKey, sKeyName);
527 else
528 {
529 size_t iPos = sKeyName.find('_');
530 addHistogramToSFMap(kKey, sKeyName.substr(0,iPos)+"_up"+sKeyName.substr(iPos));
531 addHistogramToSFMap(kKey, sKeyName.substr(0,iPos)+"_down"+sKeyName.substr(iPos));
532 }
533 }
534 }
535 ATH_MSG_INFO("data loaded from " << fFile.GetName());
536}
537
538/*
539 Create the tuple objects for the map
540*/
541//______________________________________________________________________________
542void CommonEfficiencyTool::addHistogramToSFMap(TKey* kKey, const std::string& sKeyName)
543{
544 // handling for the 3 different input types TH1F/TH1D/TF1, function pointer
545 // handle the access methods for the final scale factor retrieval
546 TClass *cClass = gROOT->GetClass(kKey->GetClassName());
547 if (cClass->InheritsFrom("TH2"))
548 {
549 TH1* oObject = (TH1*)kKey->ReadObj();
550 oObject->SetDirectory(0);
551 (*m_mSF)[sKeyName] = tTupleObjectFunc(oObject,&getValueTH2);
552 ATH_MSG_DEBUG("added histogram with name "<<sKeyName);
553 }
554 else if (cClass->InheritsFrom("TH1"))
555 {
556 TH1* oObject = (TH1*)kKey->ReadObj();
557 oObject->SetDirectory(0);
558 (*m_mSF)[sKeyName] = tTupleObjectFunc(oObject,&getValueTH1);
559 ATH_MSG_DEBUG("added histogram with name "<<sKeyName);
560 }
561 else if (cClass->InheritsFrom("TF1"))
562 {
563 TObject* oObject = kKey->ReadObj();
564 (*m_mSF)[sKeyName] = tTupleObjectFunc(oObject,&getValueTF1);
565 ATH_MSG_DEBUG("added function with name "<<sKeyName);
566 }
567 else
568 {
569 ATH_MSG_DEBUG("ignored object with name "<<sKeyName);
570 }
571}
572
573/*
574 This function parses the names of the obejects from the input file and
575 generates the systematic sets and defines which ones are recommended or only
576 available. It also checks, based on the root file name, on which tau it needs
577 to be applied, e.g. only on reco taus coming from true taus or on those faked
578 by true electrons...
579
580 Examples:
581 filename: Reco_TrueHadTau_2016-ichep.root -> apply only to true taus
582 histname: sf_1p -> nominal 1p scale factor
583 histname: TOTAL_3p -> "total" 3p NP, recommended
584 histname: afii_1p -> "total" 3p NP, not recommended, but available
585*/
586//______________________________________________________________________________
588{
589 // creation of basic string for all NPs, e.g. "TAUS_TRUEHADTAU_EFF_RECO_"
590 std::vector<std::string> vSplitInputFilePath = {};
591 split(m_sInputFileName,'_',vSplitInputFilePath);
592 std::string sEfficiencyType = vSplitInputFilePath.at(0);
593 std::string sTruthType = vSplitInputFilePath.at(1);
594 std::transform(sEfficiencyType.begin(), sEfficiencyType.end(), sEfficiencyType.begin(), toupper);
595 std::transform(sTruthType.begin(), sTruthType.end(), sTruthType.begin(), toupper);
596 std::string sSystematicBaseString = "TAUS_"+sTruthType+"_EFF_"+sEfficiencyType+"_";
597
598 // set truth type to check for in truth matching
599 if (sTruthType=="TRUEHADTAU") m_eCheckTruth = TauAnalysisTools::TruthHadronicTau;
600 else if (sTruthType=="TRUEELECTRON") m_eCheckTruth = TauAnalysisTools::TruthElectron;
601 // 3p eVeto, still need this to be measurable in T&P
602 if (sEfficiencyType=="ELERNN" || sEfficiencyType=="ELEOLR") m_bNoMultiprong = true;
603
604 for (auto mSF : *m_mSF)
605 {
606 // parse for nuisance parameter in histogram name
607 std::vector<std::string> vSplitNP = {};
608 split(mSF.first,'_',vSplitNP);
609 std::string sNP = vSplitNP.at(0);
610 std::string sNPUppercase = vSplitNP.at(0);
611
612 // skip nominal scale factors
613 if (sNP == "sf") continue;
614
615 // skip if 3p histogram to avoid duplications (TODO: come up with a better solution)
616 //if (mSF.first.find("_3p") != std::string::npos) continue;
617
618 // test if NP starts with a capital letter indicating that this should be recommended
619 bool bIsRecommended = false;
620 if (isupper(sNP.at(0)) || isupper(sNP.at(1)))
621 bIsRecommended = true;
622
623 // make sNP uppercase and build final NP entry name
624 std::transform(sNPUppercase.begin(), sNPUppercase.end(), sNPUppercase.begin(), toupper);
625 std::string sSystematicString = sSystematicBaseString+sNPUppercase;
626
627 // add all found systematics to the AffectingSystematics
628 m_sAffectingSystematics.insert(CP::SystematicVariation (sSystematicString, 1));
629 m_sAffectingSystematics.insert(CP::SystematicVariation (sSystematicString, -1));
630 // only add found uppercase systematics to the RecommendedSystematics
631 if (bIsRecommended)
632 {
633 m_sRecommendedSystematics.insert(CP::SystematicVariation (sSystematicString, 1));
634 m_sRecommendedSystematics.insert(CP::SystematicVariation (sSystematicString, -1));
635 }
636
637 ATH_MSG_DEBUG("connected base name " << sNP << " with systematic " <<sSystematicString);
638 m_mSystematicsHistNames.insert({sSystematicString,sNP});
639 }
640}
641
642/*
643 return value from the tuple map object based on the pt/eta values (or the
644 corresponding value in case of configuration)
645*/
646//______________________________________________________________________________
648 const xAOD::TauJet& xTau,
649 double& dEfficiencyScaleFactor) const
650{
651 const tSFMAP& mSF = *m_mSF;
652 auto it = mSF.find (sHistName);
653 if (it == mSF.end())
654 {
655 ATH_MSG_ERROR("Object with name "<<sHistName<<" was not found in input file.");
656 ATH_MSG_DEBUG("Content of input file");
657 for (auto eEntry : mSF)
658 ATH_MSG_DEBUG(" Entry: "<<eEntry.first);
660 }
661
662 // get a tuple (TObject*,functionPointer) from the scale factor map
663 tTupleObjectFunc tTuple = it->second;
664
665 // get pt and eta (for x and y axis respectively)
666 double dPt = m_fX(xTau);
667 double dEta = m_fY(xTau);
668
669 double dVars[2] = {dPt, dEta};
670
671 // finally obtain efficiency scale factor from TH1F/TH1D/TF1, by calling the
672 // function pointer stored in the tuple from the scale factor map
673 return (std::get<1>(tTuple))(std::get<0>(tTuple), dEfficiencyScaleFactor, dVars);
674}
675
676/*
677 find the particular value in TH1 depending on pt (or the
678 corresponding value in case of configuration)
679 Note: In case values are outside of bin ranges, the closest bin value is used
680*/
681//______________________________________________________________________________
683 double& dEfficiencyScaleFactor, double dVars[])
684{
685 double dPt = dVars[0];
686
687 const TH1* hHist = dynamic_cast<const TH1*>(oObject);
688
689 if (!hHist)
690 {
691 // ATH_MSG_ERROR("Problem with casting TObject of type "<<oObject->ClassName()<<" to TH2F");
693 }
694
695 // protect values from underflow bins
696 dPt = std::max(dPt,hHist->GetXaxis()->GetXmin());
697 // protect values from overflow bins (times .999 to keep it inside last bin)
698 dPt = std::min(dPt,hHist->GetXaxis()->GetXmax() * .999);
699
700 // get bin from TH2 depending on x and y values; finally set the scale factor
701 int iBin = hHist->FindFixBin(dPt);
702 dEfficiencyScaleFactor = hHist->GetBinContent(iBin);
704}
705
706/*
707 find the particular value in TH2 depending on pt and eta (or the
708 corresponding value in case of configuration)
709 Note: In case values are outside of bin ranges, the closest bin value is used
710*/
711//______________________________________________________________________________
713 double& dEfficiencyScaleFactor, double dVars[])
714{
715 double dPt = dVars[0];
716 double dEta = dVars[1];
717
718 const TH2* hHist = dynamic_cast<const TH2*>(oObject);
719
720 if (!hHist)
721 {
722 // ATH_MSG_ERROR("Problem with casting TObject of type "<<oObject->ClassName()<<" to TH2F");
724 }
725
726 // protect values from underflow bins
727 dPt = std::max(dPt,hHist->GetXaxis()->GetXmin());
728 dEta = std::max(dEta,hHist->GetYaxis()->GetXmin());
729 // protect values from overflow bins (times .999 to keep it inside last bin)
730 dPt = std::min(dPt,hHist->GetXaxis()->GetXmax() * .999);
731 dEta = std::min(dEta,hHist->GetYaxis()->GetXmax() * .999);
732
733 // get bin from TH2 depending on x and y values; finally set the scale factor
734 int iBin = hHist->FindFixBin(dPt,dEta);
735 dEfficiencyScaleFactor = hHist->GetBinContent(iBin);
737}
738
739/*
740 Find the particular value in TF1 depending on pt and eta (or the corresponding
741 value in case of configuration)
742*/
743//______________________________________________________________________________
745 double& dEfficiencyScaleFactor, double dVars[])
746{
747 double dPt = dVars[0];
748 double dEta = dVars[1];
749
750 const TF1* fFunc = static_cast<const TF1*>(oObject);
751
752 if (!fFunc)
753 {
754 // ATH_MSG_ERROR("Problem with casting TObject of type "<<oObject->ClassName()<<" to TF1");
756 }
757
758 // evaluate TFunction and set scale factor
759 dEfficiencyScaleFactor = fFunc->Eval(dPt, dEta);
761}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
ServiceHandle< StoreGateSvc > & evtStore()
Return value from object correction CP tools.
@ Error
Some error happened during the object correction.
@ OutOfValidityRange
Input object is out of validity range.
@ Ok
The correction was done successfully.
Class to wrap a set of SystematicVariations.
std::string name() const
returns: the systematics joined into a single string.
void insert(const SystematicVariation &systematic)
description: insert a systematic into the set
size_t size() const
returns: size of the set
Helper class to provide type-safe access to aux data.
Definition Decorator.h:59
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
std::string ConvertDecayModeToString(const int iDecayMode) const
std::function< double(const xAOD::TauJet &xTau)> m_fY
virtual StatusCode applySystematicVariation(const CP::SystematicSet &sSystematicSet)
configure this tool for the given list of systematic variations.
virtual CP::CorrectionCode getValue(const std::string &sHistName, const xAOD::TauJet &xTau, double &dEfficiencyScaleFactor) const
CommonEfficiencyTool(const std::string &sName)
Create a proper constructor for Athena.
std::map< std::string, tTupleObjectFunc > tSFMAP
Gaudi::Property< std::string > m_sInputFilePath
virtual CP::SystematicSet affectingSystematics() const
returns: the list of all systematics this tool can be affected by
virtual CP::SystematicSet recommendedSystematics() const
returns: the list of all systematics this tool recommends to use
static CP::CorrectionCode getValueTH1(const TObject *oObject, double &dEfficiencyScaleFactor, double dVars[])
std::tuple< TObject *, CP::CorrectionCode(*)(const TObject *oObject, double &dEfficiencyScaleFactor, double dVars[]) > tTupleObjectFunc
std::unordered_map< CP::SystematicSet, std::string > m_mSystematicSets
void addHistogramToSFMap(TKey *kKey, const std::string &sKeyName)
virtual CP::CorrectionCode getEfficiencyScaleFactor(const xAOD::TauJet &tau, double &dEfficiencyScaleFactor, unsigned int iRunNumber=0)
Declare the interface that the class provides.
static CP::CorrectionCode getValueTH2(const TObject *oObject, double &dEfficiencyScaleFactor, double dVars[])
virtual StatusCode initialize()
Dummy implementation of the initialisation function.
std::map< std::string, std::string > m_mSystematicsHistNames
virtual bool isAffectedBySystematic(const CP::SystematicVariation &systematic) const
returns: whether this tool is affected by the given systematics
std::function< double(const xAOD::TauJet &xTau)> m_fX
Gaudi::Property< std::string > m_sVarName
virtual CP::CorrectionCode applyEfficiencyScaleFactor(const xAOD::TauJet &xTau, unsigned int iRunNumber=0)
Decorate the tau with its efficiency.
static CP::CorrectionCode getValueTF1(const TObject *oObject, double &dEfficiencyScaleFactor, double dVars[])
std::string ConvertProngToString(const int iProngness) const
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
float averageInteractionsPerCrossing() const
Average interactions per crossing for all BCIDs - for out-of-time pile-up.
float actualInteractionsPerCrossing() const
Average interactions per crossing for the current BCID - for in-time pile-up.
uint32_t runNumber() const
The current event's run number.
bool panTauDetail(TauJetParameters::PanTauDetails panTauDetail, int &value) const
Get and set values of pantau details variables via enum.
size_t nTracks(TauJetParameters::TauTrackFlag flag=TauJetParameters::TauTrackFlag::classifiedCharged) const
double finalTauEta(const xAOD::TauJet &xTau)
return MVA based tau eta
TruthMatchedParticleType getTruthParticleType(const xAOD::TauJet &xTau)
return TauJet match type
void split(const std::string &sInput, const char cDelim, std::vector< std::string > &vOut)
double finalTauPt(const xAOD::TauJet &xTau)
return MVA based tau pt in GeV
double finalTauAbsEta(const xAOD::TauJet &xTau)
return MVA based absolute tau eta
double truthVisTauPt(const xAOD::TauJet &xTau)
return truth match visible tau pt in GeV (if hadronic truth tau match)
double tauLeadTrackEta(const xAOD::TauJet &xTau)
return leading charge tau track eta
double truthTauAbsEta(const xAOD::TauJet &xTau)
return truth match tau eta (if hadronic truth tau match)
double finalTauP(const xAOD::TauJet &xTau)
return MVA based tau P in GeV
double truthTauPt(const xAOD::TauJet &xTau)
return truth match tau pt in GeV (if hadronic truth tau match)
double truthDecayMode(const xAOD::TauJet &xTau)
return truth decay mode (if hadronic truth tau match)
EventInfo_v1 EventInfo
Definition of the latest event info version.
TauJet_v3 TauJet
Definition of the current "tau version".