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 , m_accessors{std::make_unique<Accessors>(*this)}
80{
81}
82
83/*
84 need to clear the map of histograms cause we have the ownership, not ROOT
85*/
87{
88 if (m_mSF)
89 for (auto mEntry : *m_mSF)
90 delete std::get<0>(mEntry.second);
91}
92
93/*
94 - Find the root files with scale factor inputs on cvmfs using PathResolver
95 (more info here:
96 https://twiki.cern.ch/twiki/bin/viewauth/AtlasComputing/PathResolver)
97 - Call further functions to process and define NP strings and so on
98 - Configure to provide nominal scale factors by default
99*/
101{
102 ATH_MSG_INFO( "Initializing CommonEfficiencyTool" );
103 // only read in histograms once
104 if (m_mSF==nullptr)
105 {
106 std::string sInputFilePath = PathResolverFindCalibFile(m_sInputFilePath);
107
108 m_mSF = std::make_unique< tSFMAP >();
109 std::unique_ptr< TFile > fSF( TFile::Open( sInputFilePath.c_str(), "READ" ) );
110 if(!fSF)
111 {
112 ATH_MSG_FATAL("Could not open file " << sInputFilePath.c_str());
113 return StatusCode::FAILURE;
114 }
115 ReadInputs(*fSF);
116 fSF->Close();
117 }
118
119 // needed later on in generateSystematicSets(), maybe move it there
120 std::vector<std::string> vInputFilePath;
121 split(m_sInputFilePath,'/',vInputFilePath);
122 m_sInputFileName = vInputFilePath.back();
123
125
126 if (!m_sWP.empty())
127 m_sSFHistName = "sf_"+m_sWP;
128
129 // load empty systematic variation by default
130 if (applySystematicVariation(CP::SystematicSet()) != StatusCode::SUCCESS )
131 return StatusCode::FAILURE;
132
133 ATH_CHECK (initializeColumns());
134
135 return StatusCode::SUCCESS;
136}
137
138/*
139 Retrieve the scale factors and if requested the values for the NP's and add
140 this stuff in quadrature. Finally return sf_nom +/- n*uncertainty
141*/
142
143//______________________________________________________________________________
145 double& dEfficiencyScaleFactor, unsigned int iRunNumber)
146{
147 return getEfficiencyScaleFactor(columnar::TauJetId(xTau), dEfficiencyScaleFactor, iRunNumber);
148}
149
151 unsigned int /*iRunNumber*/) const
152{
153 const Accessors& acc = *m_accessors;
154
155 // check which true state is requested
156 // need columnar migration
157 if (!m_bSkipTruthMatchCheck and getTruthParticleType(tau.getXAODObject()) != m_eCheckTruth)
158 {
159 dEfficiencyScaleFactor = 1.;
161 }
162
163 // need columnar migration
164 int ntracks = tau.getXAODObject().nTracks();
165
166 // check if 1 prong
167 if (m_bNoMultiprong && ntracks != 1)
168 {
169 dEfficiencyScaleFactor = 1.;
171 }
172
173 // get decay mode or prong extension for histogram name
174 std::string sMode;
176 {
177 int iDecayMode = acc.m_decayMode(tau);
178 sMode = ConvertDecayModeToString(iDecayMode);
179 if (sMode.empty())
180 {
181 ATH_MSG_WARNING("Found tau with unknown decay mode. Skip efficiency correction.");
183 }
184 }
185 else
186 {
187 // skip taus which are not 1 or 3 prong
188 if( ntracks != 1 && ntracks != 3) {
189 dEfficiencyScaleFactor = 1.;
191 }
192
193 sMode = ConvertProngToString(ntracks);
194 }
195
196 std::string sHistName;
197 if(m_doTauTrig){
198 sHistName = "sf_all_"+m_sWP+sMode;
199 } else {
200 sHistName = m_sSFHistName + sMode;
201 }
202
203 // get standard scale factor
204 CP::CorrectionCode tmpCorrectionCode = getValue(sHistName,
205 tau,
206 dEfficiencyScaleFactor);
207 // return correction code if histogram is not available
208 if (tmpCorrectionCode != CP::CorrectionCode::Ok)
209 return tmpCorrectionCode;
210
211 // skip further process if systematic set is empty
212 if (m_sSystematicSet->empty())
214
215 // get uncertainties summed in quadrature
216 double dTotalSystematic2 = 0.;
217 double dDirection = 0.;
218 for (auto syst : *m_sSystematicSet)
219 {
220 // check if systematic is available
221 auto it = m_mSystematicsHistNames.find(syst.basename());
222
223 // get uncertainty value
224 double dUncertaintySyst = 0.;
225
226 // needed for up/down decision
227 dDirection = syst.parameter();
228
229 // build up histogram name
230 sHistName = it->second;
231 if (dDirection>0.) sHistName+="_up";
232 else sHistName+="_down";
233
234 if(m_doTauTrig){ sHistName+="_all"; }
235
236 if (!m_sWP.empty()) sHistName+="_"+m_sWP;
237 sHistName += sMode;
238
239
240 // filter unwanted combinations
241 if( (sHistName.find("3P") != std::string::npos && sHistName.find("1p") != std::string::npos) ||
242 (sHistName.find("1P") != std::string::npos && sHistName.find("3p") != std::string::npos))
243 continue;
244
245 if( (sHistName.find("1520") != std::string::npos && sHistName.find("loose") != std::string::npos) ){
246 continue;
247 }
248
249 // get the uncertainty from the histogram
250 tmpCorrectionCode = getValue(sHistName,
251 tau,
252 dUncertaintySyst);
253
254 // return correction code if histogram is not available
255 if (tmpCorrectionCode != CP::CorrectionCode::Ok)
256 return tmpCorrectionCode;
257
258 // scale uncertainty with direction, i.e. +/- n*sigma
259 dUncertaintySyst *= dDirection;
260
261 // square uncertainty and add to total uncertainty
262 dTotalSystematic2 += dUncertaintySyst * dUncertaintySyst;
263 }
264
265 // now use dDirection to use up/down uncertainty
266 dDirection = (dDirection > 0.) ? 1. : -1.;
267
268 // finally apply uncertainty (eff * ( 1 +/- \sum )
269 dEfficiencyScaleFactor *= 1. + dDirection * std::sqrt(dTotalSystematic2);
270
272}
273
274/*
275 Get scale factor from getEfficiencyScaleFactor and decorate it to the
276 tau. Note that this can only be done if the variable name is not already used,
277 e.g. if the variable was already decorated on a previous step (enured by the
278 m_bSFIsAvailableChecked check).
279
280 Technical note: cannot use `static SG::Decorator` as we will have
281 multiple instances of this tool with different decoration names.
282*/
283//______________________________________________________________________________
285 unsigned int iRunNumber)
286{
287 double dSf = 0.;
288
291 {
292 m_bSFIsAvailable = decor.isAvailable(xTau);
295 {
296 ATH_MSG_DEBUG(m_sVarName << " decoration is available on first tau processed, switched off applyEfficiencyScaleFactor for further taus.");
297 ATH_MSG_DEBUG("If an application of efficiency scale factors needs to be redone, please pass a shallow copy of the original tau.");
298 }
299 }
302
303 // retrieve scale factor
304 CP::CorrectionCode tmpCorrectionCode = getEfficiencyScaleFactor(xTau, dSf, iRunNumber);
305 // adding scale factor to tau as decoration
306 decor(xTau) = dSf;
307
308 return tmpCorrectionCode;
309}
310
311
312
313/*
314 standard check if a systematic is available
315*/
316//______________________________________________________________________________
318{
320 return sys.find(systematic) != sys.end();
321}
322
323/*
324 standard way to return systematics that are available (including recommended
325 systematics)
326*/
327//______________________________________________________________________________
332
333/*
334 standard way to return systematics that are recommended
335*/
336//______________________________________________________________________________
341
342/*
343 Configure the tool to use a systematic variation for further usage, until the
344 tool is reconfigured with this function. The passed systematic set is checked
345 for sanity:
346 - unsupported systematics are skipped
347 - only combinations of up or down supported systematics is allowed
348 - don't mix recommended systematics with other available systematics, cause
349 sometimes recommended are a quadratic sum of the other variations,
350 e.g. TOTAL=(SYST^2 + STAT^2)^0.5
351*/
352//______________________________________________________________________________
354{
355
356 // first check if we already know this systematic configuration
357 auto itSystematicSet = m_mSystematicSets.find(sSystematicSet);
358 if (itSystematicSet != m_mSystematicSets.end())
359 {
360 m_sSystematicSet = &itSystematicSet->first;
361 return StatusCode::SUCCESS;
362 }
363
364 // sanity checks if systematic set is supported
365 double dDirection = 0.;
366 CP::SystematicSet sSystematicSetAvailable;
367 for (auto sSyst : sSystematicSet)
368 {
369 // check if systematic is available
370 auto it = m_mSystematicsHistNames.find(sSyst.basename());
371 if (it == m_mSystematicsHistNames.end())
372 {
373 ATH_MSG_VERBOSE("unsupported systematic variation: "<< sSyst.basename()<<"; skipping this one");
374 continue;
375 }
376
377
378 if (sSyst.parameter() * dDirection < 0)
379 {
380 ATH_MSG_ERROR("unsupported set of systematic variations, you should either use only \"UP\" or only \"DOWN\" systematics in one set!");
381 ATH_MSG_ERROR("systematic set will not be applied");
382 return StatusCode::FAILURE;
383 }
384 dDirection = sSyst.parameter();
385
386 if ((m_sRecommendedSystematics.find(sSyst.basename()) != m_sRecommendedSystematics.end()) and sSystematicSet.size() > 1)
387 {
388 ATH_MSG_ERROR("unsupported set of systematic variations, you should not combine \"TAUS_{TRUE|FAKE}_EFF_*_TOTAL\" with other systematic variations!");
389 ATH_MSG_ERROR("systematic set will not be applied");
390 return StatusCode::FAILURE;
391 }
392
393 // finally add the systematic to the set of systematics to process
394 sSystematicSetAvailable.insert(sSyst);
395 }
396
397 // store this calibration for future use, and make it current
398 m_sSystematicSet = &m_mSystematicSets.insert(std::pair<CP::SystematicSet,std::string>(sSystematicSetAvailable, sSystematicSet.name())).first->first;
399
400 return StatusCode::SUCCESS;
401}
402
403//=================================PRIVATE-PART=================================
404std::string CommonEfficiencyTool::ConvertProngToString(const int fProngness) const
405{
406 return fProngness == 1 ? "_1p" : "_3p";
407}
408
409/*
410 decay mode converter
411*/
412//______________________________________________________________________________
413std::string CommonEfficiencyTool::ConvertDecayModeToString(const int iDecayMode) const
414{
415 switch(iDecayMode)
416 {
418 return "_r1p0n";
420 return "_r1p1n";
422 return "_r1pXn";
424 return "_r3p0n";
426 return "_r3pXn";
427 default:
428 return "";
429 }
430}
431
432/*
433 Read in a root file and store all objects to a map of this type:
434 std::map<std::string, tTupleObjectFunc > (see header) It's basically a map of
435 the histogram name and a function pointer based on the TObject type (TH1F,
436 TH1D, TF1). This is resolved in the function:
437 - CommonEfficiencyTool::addHistogramToSFMap
438 Further this function figures out the axis definition (see description on the
439 top)
440*/
441//______________________________________________________________________________
442void CommonEfficiencyTool::ReadInputs(const TFile& fFile)
443{
444 m_mSF->clear();
445
446 // initialize function pointer
447 m_fX = &finalTauPt;
448 m_fY = &finalTauEta;
449
450 TKey *kKey;
451 TIter itNext(fFile.GetListOfKeys());
452 while ((kKey = (TKey*)itNext()))
453 {
454 // parse file content for objects of type TNamed, check their title for
455 // known strings and reset funtion pointer
456 std::string sKeyName = kKey->GetName();
457 if (sKeyName == "Xaxis")
458 {
459 TNamed* tObj = (TNamed*)kKey->ReadObj();
460 std::string sTitle = tObj->GetTitle();
461 delete tObj;
462 if (sTitle == "TruthDecayMode")
463 {
465 ATH_MSG_DEBUG("using truth decay mode for x-axis");
466 }
467 if (sTitle == "truth visible pt")
468 {
470 ATH_MSG_DEBUG("using truth visible pT for x-axis");
471 }
472 if (sTitle == "|eta|")
473 {
475 ATH_MSG_DEBUG("using absolute tau eta for x-axis");
476 }
477
478 continue;
479 }
480 else if (sKeyName == "Yaxis")
481 {
482 TNamed* tObj = (TNamed*)kKey->ReadObj();
483 std::string sTitle = tObj->GetTitle();
484 delete tObj;
485 if (sTitle == "|eta|")
486 {
488 ATH_MSG_DEBUG("using absolute tau eta for y-axis");
489 }
490 else if (sTitle == "truth |eta|")
491 {
493 ATH_MSG_DEBUG("using absolute truth tau eta for y-axis");
494 }
495 continue;
496 }
497
498 std::vector<std::string> vSplitName = {};
499 split(sKeyName,'_',vSplitName);
500 if (vSplitName[0] == "sf")
501 {
502 addHistogramToSFMap(kKey, sKeyName);
503 }
504 else
505 {
506 // std::string sDirection = vSplitName[1];
507 if (sKeyName.find("_up_") != std::string::npos or sKeyName.find("_down_") != std::string::npos)
508 addHistogramToSFMap(kKey, sKeyName);
509 else
510 {
511 size_t iPos = sKeyName.find('_');
512 addHistogramToSFMap(kKey, sKeyName.substr(0,iPos)+"_up"+sKeyName.substr(iPos));
513 addHistogramToSFMap(kKey, sKeyName.substr(0,iPos)+"_down"+sKeyName.substr(iPos));
514 }
515 }
516 }
517 ATH_MSG_INFO("data loaded from " << fFile.GetName());
518}
519
520/*
521 Create the tuple objects for the map
522*/
523//______________________________________________________________________________
524void CommonEfficiencyTool::addHistogramToSFMap(TKey* kKey, const std::string& sKeyName)
525{
526 // handling for the 3 different input types TH1F/TH1D/TF1, function pointer
527 // handle the access methods for the final scale factor retrieval
528 TClass *cClass = gROOT->GetClass(kKey->GetClassName());
529 if (cClass->InheritsFrom("TH2"))
530 {
531 TH1* oObject = (TH1*)kKey->ReadObj();
532 oObject->SetDirectory(0);
533 (*m_mSF)[sKeyName] = tTupleObjectFunc(oObject,&getValueTH2);
534 ATH_MSG_DEBUG("added histogram with name "<<sKeyName);
535 }
536 else if (cClass->InheritsFrom("TH1"))
537 {
538 TH1* oObject = (TH1*)kKey->ReadObj();
539 oObject->SetDirectory(0);
540 (*m_mSF)[sKeyName] = tTupleObjectFunc(oObject,&getValueTH1);
541 ATH_MSG_DEBUG("added histogram with name "<<sKeyName);
542 }
543 else if (cClass->InheritsFrom("TF1"))
544 {
545 TObject* oObject = kKey->ReadObj();
546 (*m_mSF)[sKeyName] = tTupleObjectFunc(oObject,&getValueTF1);
547 ATH_MSG_DEBUG("added function with name "<<sKeyName);
548 }
549 else
550 {
551 ATH_MSG_DEBUG("ignored object with name "<<sKeyName);
552 }
553}
554
555/*
556 This function parses the names of the obejects from the input file and
557 generates the systematic sets and defines which ones are recommended or only
558 available. It also checks, based on the root file name, on which tau it needs
559 to be applied, e.g. only on reco taus coming from true taus or on those faked
560 by true electrons...
561
562 Examples:
563 filename: Reco_TrueHadTau_2016-ichep.root -> apply only to true taus
564 histname: sf_1p -> nominal 1p scale factor
565 histname: TOTAL_3p -> "total" 3p NP, recommended
566 histname: afii_1p -> "total" 3p NP, not recommended, but available
567*/
568//______________________________________________________________________________
570{
571 // creation of basic string for all NPs, e.g. "TAUS_TRUEHADTAU_EFF_RECO_"
572 std::vector<std::string> vSplitInputFilePath = {};
573 split(m_sInputFileName,'_',vSplitInputFilePath);
574 std::string sEfficiencyType = vSplitInputFilePath.at(0);
575 std::string sTruthType = vSplitInputFilePath.at(1);
576 std::transform(sEfficiencyType.begin(), sEfficiencyType.end(), sEfficiencyType.begin(), toupper);
577 std::transform(sTruthType.begin(), sTruthType.end(), sTruthType.begin(), toupper);
578 std::string sSystematicBaseString = "TAUS_"+sTruthType+"_EFF_"+sEfficiencyType+"_";
579
580 // set truth type to check for in truth matching
581 if (sTruthType=="TRUEHADTAU") m_eCheckTruth = TauAnalysisTools::TruthHadronicTau;
582 else if (sTruthType=="TRUEELECTRON") m_eCheckTruth = TauAnalysisTools::TruthElectron;
583 // 3p eVeto, still need this to be measurable in T&P
584 if (sEfficiencyType=="ELERNN" || sEfficiencyType=="ELEOLR") m_bNoMultiprong = true;
585
586 for (auto mSF : *m_mSF)
587 {
588 // parse for nuisance parameter in histogram name
589 std::vector<std::string> vSplitNP = {};
590 split(mSF.first,'_',vSplitNP);
591 std::string sNP = vSplitNP.at(0);
592 std::string sNPUppercase = vSplitNP.at(0);
593
594 // skip nominal scale factors
595 if (sNP == "sf") continue;
596
597 // skip if 3p histogram to avoid duplications (TODO: come up with a better solution)
598 //if (mSF.first.find("_3p") != std::string::npos) continue;
599
600 // test if NP starts with a capital letter indicating that this should be recommended
601 bool bIsRecommended = false;
602 if (isupper(sNP.at(0)) || isupper(sNP.at(1)))
603 bIsRecommended = true;
604
605 // make sNP uppercase and build final NP entry name
606 std::transform(sNPUppercase.begin(), sNPUppercase.end(), sNPUppercase.begin(), toupper);
607 std::string sSystematicString = sSystematicBaseString+sNPUppercase;
608
609 // add all found systematics to the AffectingSystematics
610 m_sAffectingSystematics.insert(CP::SystematicVariation (sSystematicString, 1));
611 m_sAffectingSystematics.insert(CP::SystematicVariation (sSystematicString, -1));
612 // only add found uppercase systematics to the RecommendedSystematics
613 if (bIsRecommended)
614 {
615 m_sRecommendedSystematics.insert(CP::SystematicVariation (sSystematicString, 1));
616 m_sRecommendedSystematics.insert(CP::SystematicVariation (sSystematicString, -1));
617 }
618
619 ATH_MSG_DEBUG("connected base name " << sNP << " with systematic " <<sSystematicString);
620 m_mSystematicsHistNames.insert({sSystematicString,sNP});
621 }
622}
623
624/*
625 return value from the tuple map object based on the pt/eta values (or the
626 corresponding value in case of configuration)
627*/
628//______________________________________________________________________________
631 double& dEfficiencyScaleFactor) const
632{
633
634
635 const tSFMAP& mSF = *m_mSF;
636 auto it = mSF.find (sHistName);
637 if (it == mSF.end())
638 {
639 ATH_MSG_ERROR("Object with name "<<sHistName<<" was not found in input file.");
640 ATH_MSG_DEBUG("Content of input file");
641 for (auto eEntry : mSF)
642 ATH_MSG_DEBUG(" Entry: "<<eEntry.first);
644 }
645
646 // get a tuple (TObject*,functionPointer) from the scale factor map
647 tTupleObjectFunc tTuple = it->second;
648
649 // get pt and eta (for x and y axis respectively)
650 // need columnar migration
651 double dPt = m_fX(tau.getXAODObject());
652 double dEta = m_fY(tau.getXAODObject());
653
654 double dVars[2] = {dPt, dEta};
655
656 // finally obtain efficiency scale factor from TH1F/TH1D/TF1, by calling the
657 // function pointer stored in the tuple from the scale factor map
658 return (std::get<1>(tTuple))(std::get<0>(tTuple), dEfficiencyScaleFactor, dVars);
659}
660
661/*
662 find the particular value in TH1 depending on pt (or the
663 corresponding value in case of configuration)
664 Note: In case values are outside of bin ranges, the closest bin value is used
665*/
666//______________________________________________________________________________
668 double& dEfficiencyScaleFactor, double dVars[])
669{
670 double dPt = dVars[0];
671
672 const TH1* hHist = dynamic_cast<const TH1*>(oObject);
673
674 if (!hHist)
675 {
676 // ATH_MSG_ERROR("Problem with casting TObject of type "<<oObject->ClassName()<<" to TH2F");
678 }
679
680 // protect values from underflow bins
681 dPt = std::max(dPt,hHist->GetXaxis()->GetXmin());
682 // protect values from overflow bins (times .999 to keep it inside last bin)
683 dPt = std::min(dPt,hHist->GetXaxis()->GetXmax() * .999);
684
685 // get bin from TH2 depending on x and y values; finally set the scale factor
686 int iBin = hHist->FindFixBin(dPt);
687 dEfficiencyScaleFactor = hHist->GetBinContent(iBin);
689}
690
691/*
692 find the particular value in TH2 depending on pt and eta (or the
693 corresponding value in case of configuration)
694 Note: In case values are outside of bin ranges, the closest bin value is used
695*/
696//______________________________________________________________________________
698 double& dEfficiencyScaleFactor, double dVars[])
699{
700 double dPt = dVars[0];
701 double dEta = dVars[1];
702
703 const TH2* hHist = dynamic_cast<const TH2*>(oObject);
704
705 if (!hHist)
706 {
707 // ATH_MSG_ERROR("Problem with casting TObject of type "<<oObject->ClassName()<<" to TH2F");
709 }
710
711 // protect values from underflow bins
712 dPt = std::max(dPt,hHist->GetXaxis()->GetXmin());
713 dEta = std::max(dEta,hHist->GetYaxis()->GetXmin());
714 // protect values from overflow bins (times .999 to keep it inside last bin)
715 dPt = std::min(dPt,hHist->GetXaxis()->GetXmax() * .999);
716 dEta = std::min(dEta,hHist->GetYaxis()->GetXmax() * .999);
717
718 // get bin from TH2 depending on x and y values; finally set the scale factor
719 int iBin = hHist->FindFixBin(dPt,dEta);
720 dEfficiencyScaleFactor = hHist->GetBinContent(iBin);
722}
723
724/*
725 Find the particular value in TF1 depending on pt and eta (or the corresponding
726 value in case of configuration)
727*/
728//______________________________________________________________________________
730 double& dEfficiencyScaleFactor, double dVars[])
731{
732 double dPt = dVars[0];
733 double dEta = dVars[1];
734
735 const TF1* fFunc = static_cast<const TF1*>(oObject);
736
737 if (!fFunc)
738 {
739 // ATH_MSG_ERROR("Problem with casting TObject of type "<<oObject->ClassName()<<" to TF1");
741 }
742
743 // evaluate TFunction and set scale factor
744 dEfficiencyScaleFactor = fFunc->Eval(dPt, dEta);
746}
747
749{
750
751 const Accessors& acc = *m_accessors;
752 unsigned int runNumber = 0;
753 if (!acc.randomrunnumber.isAvailable(event)) {
755 "Pileup tool not run before using ElectronEfficiencyTool! SFs do not "
756 "reflect PU distribution in data");
757 return;
758 }
759 runNumber = acc.randomrunnumber(event);
760
761 for (columnar::TauJetId tau : taus)
762 {
763 double sf = 0;
764 switch (getEfficiencyScaleFactor(tau, sf, runNumber).code())
765 {
767 acc.m_sfDec(tau) = sf;
768 acc.m_validDec(tau) = true;
769 break;
771 acc.m_sfDec(tau) = sf;
772 acc.m_validDec(tau) = false;
773 break;
774 default:
775 throw std::runtime_error("Error in getEfficiencyScaleFactor");
776 }
777 }
778}
779
781{
782 const Accessors& acc = *m_accessors;
783 for (columnar::EventContextId event : events)
784 {
785 auto eventInfo = acc.m_eventInfo(event);
786 callSingleEvent (acc.m_taus(event), eventInfo);
787 }
788}
789
790
791
792
#define ATH_CHECK
Evaluate an expression and check for errors.
#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)
static Double_t taus
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
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
virtual CP::SystematicSet affectingSystematics() const override
returns: the list of all systematics this tool can be affected by
std::string ConvertDecayModeToString(const int iDecayMode) const
std::function< double(const xAOD::TauJet &xTau)> m_fY
CommonEfficiencyTool(const std::string &sName)
Create a proper constructor for Athena.
virtual StatusCode initialize() override
Dummy implementation of the initialisation function.
virtual bool isAffectedBySystematic(const CP::SystematicVariation &systematic) const override
returns: whether this tool is affected by the given systematics
void callEvents(columnar::EventContextRange events) const override
std::map< std::string, tTupleObjectFunc > tSFMAP
virtual CP::CorrectionCode getEfficiencyScaleFactor(const xAOD::TauJet &tau, double &dEfficiencyScaleFactor, unsigned int iRunNumber=0) override
Declare the interface that the class provides.
Gaudi::Property< std::string > m_sInputFilePath
virtual CP::CorrectionCode applyEfficiencyScaleFactor(const xAOD::TauJet &xTau, unsigned int iRunNumber=0) override
Decorate the tau with its efficiency.
virtual StatusCode applySystematicVariation(const CP::SystematicSet &sSystematicSet) override
configure this tool for the given list of systematic variations.
void callSingleEvent(columnar::TauJetRange taus, columnar::EventInfoId event) const
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)
static CP::CorrectionCode getValueTH2(const TObject *oObject, double &dEfficiencyScaleFactor, double dVars[])
virtual CP::SystematicSet recommendedSystematics() const override
returns: the list of all systematics this tool recommends to use
std::map< std::string, std::string > m_mSystematicsHistNames
std::function< double(const xAOD::TauJet &xTau)> m_fX
Gaudi::Property< std::string > m_sVarName
static CP::CorrectionCode getValueTF1(const TObject *oObject, double &dEfficiencyScaleFactor, double dVars[])
virtual CP::CorrectionCode getValue(const std::string &sHistName, columnar::TauJetId tau, double &dEfficiencyScaleFactor) const
std::string ConvertProngToString(const int iProngness) const
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
SG::Decorator< T, ALLOC > Decorator
Helper class to provide type-safe access to aux data, specialized for JaggedVecElt.
Definition AuxElement.h:576
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 truthTauAbsEta(const xAOD::TauJet &xTau)
return truth match tau eta (if hadronic truth tau match)
double truthDecayMode(const xAOD::TauJet &xTau)
return truth decay mode (if hadronic truth tau match)
ObjectRange< TauJetDef > TauJetRange
Definition TauJetDef.h:21
ObjectRange< EventContextDef > EventContextRange
ObjectId< EventContextDef > EventContextId
ObjectId< TauJetDef > TauJetId
Definition TauJetDef.h:22
ObjectId< EventInfoDef > EventInfoId
STL namespace.
TauJet_v3 TauJet
Definition of the current "tau version".