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 or if we are running on data
156 // need columnar migration
157 if(m_applyToData){
158 ATH_MSG_DEBUG("retrieving the SFs while running on data ...");
159 } else if (!m_bSkipTruthMatchCheck and acc.m_truthParticleType(tau) != m_eCheckTruth)
160 {
161 dEfficiencyScaleFactor = 1.;
163 }
164
165 // need columnar migration
166 int ntracks = tau.getXAODObject().nTracks();
167
168 // check if 1 prong
169 if (m_bNoMultiprong && ntracks != 1)
170 {
171 dEfficiencyScaleFactor = 1.;
173 }
174
175 // get decay mode or prong extension for histogram name
176 std::string sMode;
178 {
179 int iDecayMode = acc.m_decayMode(tau);
180 sMode = ConvertDecayModeToString(iDecayMode);
181 if (sMode.empty())
182 {
183 ATH_MSG_WARNING("Found tau with unknown decay mode. Skip efficiency correction.");
185 }
186 }
187 else
188 {
189 // skip taus which are not 1 or 3 prong
190 if( ntracks != 1 && ntracks != 3) {
191 dEfficiencyScaleFactor = 1.;
193 }
194
195 sMode = ConvertProngToString(ntracks);
196 }
197
198 std::string sHistName;
199 if(m_doTauTrig){
200 sHistName = "sf_all_"+m_sWP+sMode;
201 } else {
202 sHistName = m_sSFHistName + sMode;
203 }
204
205 // get standard scale factor
206 CP::CorrectionCode tmpCorrectionCode = getValue(sHistName,
207 tau,
208 dEfficiencyScaleFactor);
209 // return correction code if histogram is not available
210 if (tmpCorrectionCode != CP::CorrectionCode::Ok)
211 return tmpCorrectionCode;
212
213 // skip further process if systematic set is empty
214 if (m_sSystematicSet->empty())
216
217 // get uncertainties summed in quadrature
218 double dTotalSystematic2 = 0.;
219 double dDirection = 0.;
220 for (auto syst : *m_sSystematicSet)
221 {
222 // check if systematic is available
223 auto it = m_mSystematicsHistNames.find(syst.basename());
224
225 // get uncertainty value
226 double dUncertaintySyst = 0.;
227
228 // needed for up/down decision
229 dDirection = syst.parameter();
230
231 // build up histogram name
232 sHistName = it->second;
233 if (dDirection>0.) sHistName+="_up";
234 else sHistName+="_down";
235
236 if(m_doTauTrig){ sHistName+="_all"; }
237
238 if (!m_sWP.empty()) sHistName+="_"+m_sWP;
239 sHistName += sMode;
240
241
242 // filter unwanted combinations
243 if( (sHistName.find("3P") != std::string::npos && sHistName.find("1p") != std::string::npos) ||
244 (sHistName.find("1P") != std::string::npos && sHistName.find("3p") != std::string::npos))
245 continue;
246
247 if( (sHistName.find("1520") != std::string::npos && sHistName.find("loose") != std::string::npos) ){
248 continue;
249 }
250
251 // get the uncertainty from the histogram
252 tmpCorrectionCode = getValue(sHistName,
253 tau,
254 dUncertaintySyst);
255
256 // return correction code if histogram is not available
257 if (tmpCorrectionCode != CP::CorrectionCode::Ok)
258 return tmpCorrectionCode;
259
260 // scale uncertainty with direction, i.e. +/- n*sigma
261 dUncertaintySyst *= dDirection;
262
263 // square uncertainty and add to total uncertainty
264 dTotalSystematic2 += dUncertaintySyst * dUncertaintySyst;
265 }
266
267 // now use dDirection to use up/down uncertainty
268 dDirection = (dDirection > 0.) ? 1. : -1.;
269
270 // finally apply uncertainty (eff * ( 1 +/- \sum )
271 dEfficiencyScaleFactor *= 1. + dDirection * std::sqrt(dTotalSystematic2);
272
274}
275
276/*
277 Get scale factor from getEfficiencyScaleFactor and decorate it to the
278 tau. Note that this can only be done if the variable name is not already used,
279 e.g. if the variable was already decorated on a previous step (enured by the
280 m_bSFIsAvailableChecked check).
281
282 Technical note: cannot use `static SG::Decorator` as we will have
283 multiple instances of this tool with different decoration names.
284*/
285//______________________________________________________________________________
287 unsigned int iRunNumber)
288{
289 double dSf = 0.;
290
293 {
294 m_bSFIsAvailable = decor.isAvailable(xTau);
297 {
298 ATH_MSG_DEBUG(m_sVarName << " decoration is available on first tau processed, switched off applyEfficiencyScaleFactor for further taus.");
299 ATH_MSG_DEBUG("If an application of efficiency scale factors needs to be redone, please pass a shallow copy of the original tau.");
300 }
301 }
304
305 // retrieve scale factor
306 CP::CorrectionCode tmpCorrectionCode = getEfficiencyScaleFactor(xTau, dSf, iRunNumber);
307 // adding scale factor to tau as decoration
308 decor(xTau) = dSf;
309
310 return tmpCorrectionCode;
311}
312
313
314
315/*
316 standard check if a systematic is available
317*/
318//______________________________________________________________________________
320{
322 return sys.find(systematic) != sys.end();
323}
324
325/*
326 standard way to return systematics that are available (including recommended
327 systematics)
328*/
329//______________________________________________________________________________
334
335/*
336 standard way to return systematics that are recommended
337*/
338//______________________________________________________________________________
343
344/*
345 Configure the tool to use a systematic variation for further usage, until the
346 tool is reconfigured with this function. The passed systematic set is checked
347 for sanity:
348 - unsupported systematics are skipped
349 - only combinations of up or down supported systematics is allowed
350 - don't mix recommended systematics with other available systematics, cause
351 sometimes recommended are a quadratic sum of the other variations,
352 e.g. TOTAL=(SYST^2 + STAT^2)^0.5
353*/
354//______________________________________________________________________________
356{
357
358 // first check if we already know this systematic configuration
359 auto itSystematicSet = m_mSystematicSets.find(sSystematicSet);
360 if (itSystematicSet != m_mSystematicSets.end())
361 {
362 m_sSystematicSet = &itSystematicSet->first;
363 return StatusCode::SUCCESS;
364 }
365
366 // sanity checks if systematic set is supported
367 double dDirection = 0.;
368 CP::SystematicSet sSystematicSetAvailable;
369 for (auto sSyst : sSystematicSet)
370 {
371 // check if systematic is available
372 auto it = m_mSystematicsHistNames.find(sSyst.basename());
373 if (it == m_mSystematicsHistNames.end())
374 {
375 ATH_MSG_VERBOSE("unsupported systematic variation: "<< sSyst.basename()<<"; skipping this one");
376 continue;
377 }
378
379
380 if (sSyst.parameter() * dDirection < 0)
381 {
382 ATH_MSG_ERROR("unsupported set of systematic variations, you should either use only \"UP\" or only \"DOWN\" systematics in one set!");
383 ATH_MSG_ERROR("systematic set will not be applied");
384 return StatusCode::FAILURE;
385 }
386 dDirection = sSyst.parameter();
387
388 if ((m_sRecommendedSystematics.find(sSyst.basename()) != m_sRecommendedSystematics.end()) and sSystematicSet.size() > 1)
389 {
390 ATH_MSG_ERROR("unsupported set of systematic variations, you should not combine \"TAUS_{TRUE|FAKE}_EFF_*_TOTAL\" with other systematic variations!");
391 ATH_MSG_ERROR("systematic set will not be applied");
392 return StatusCode::FAILURE;
393 }
394
395 // finally add the systematic to the set of systematics to process
396 sSystematicSetAvailable.insert(sSyst);
397 }
398
399 // store this calibration for future use, and make it current
400 m_sSystematicSet = &m_mSystematicSets.insert(std::pair<CP::SystematicSet,std::string>(sSystematicSetAvailable, sSystematicSet.name())).first->first;
401
402 return StatusCode::SUCCESS;
403}
404
405//=================================PRIVATE-PART=================================
406std::string CommonEfficiencyTool::ConvertProngToString(const int fProngness) const
407{
408 return fProngness == 1 ? "_1p" : "_3p";
409}
410
411/*
412 decay mode converter
413*/
414//______________________________________________________________________________
415std::string CommonEfficiencyTool::ConvertDecayModeToString(const int iDecayMode) const
416{
417 switch(iDecayMode)
418 {
420 return "_r1p0n";
422 return "_r1p1n";
424 return "_r1pXn";
426 return "_r3p0n";
428 return "_r3pXn";
429 default:
430 return "";
431 }
432}
433
434/*
435 Read in a root file and store all objects to a map of this type:
436 std::map<std::string, tTupleObjectFunc > (see header) It's basically a map of
437 the histogram name and a function pointer based on the TObject type (TH1F,
438 TH1D, TF1). This is resolved in the function:
439 - CommonEfficiencyTool::addHistogramToSFMap
440 Further this function figures out the axis definition (see description on the
441 top)
442*/
443//______________________________________________________________________________
444void CommonEfficiencyTool::ReadInputs(const TFile& fFile)
445{
446 m_mSF->clear();
447
448 // initialize function pointer
449 m_fX = &finalTauPt;
450 m_fY = &finalTauEta;
451
452 TKey *kKey;
453 TIter itNext(fFile.GetListOfKeys());
454 while ((kKey = (TKey*)itNext()))
455 {
456 // parse file content for objects of type TNamed, check their title for
457 // known strings and reset funtion pointer
458 std::string sKeyName = kKey->GetName();
459 if (sKeyName == "Xaxis")
460 {
461 TNamed* tObj = (TNamed*)kKey->ReadObj();
462 std::string sTitle = tObj->GetTitle();
463 delete tObj;
464 if (sTitle == "TruthDecayMode")
465 {
467 ATH_MSG_DEBUG("using truth decay mode for x-axis");
468 }
469 if (sTitle == "truth visible pt")
470 {
472 ATH_MSG_DEBUG("using truth visible pT for x-axis");
473 }
474 if (sTitle == "|eta|")
475 {
477 ATH_MSG_DEBUG("using absolute tau eta for x-axis");
478 }
479
480 continue;
481 }
482 else if (sKeyName == "Yaxis")
483 {
484 TNamed* tObj = (TNamed*)kKey->ReadObj();
485 std::string sTitle = tObj->GetTitle();
486 delete tObj;
487 if (sTitle == "|eta|")
488 {
490 ATH_MSG_DEBUG("using absolute tau eta for y-axis");
491 }
492 else if (sTitle == "truth |eta|")
493 {
495 ATH_MSG_DEBUG("using absolute truth tau eta for y-axis");
496 }
497 continue;
498 }
499
500 std::vector<std::string> vSplitName = {};
501 split(sKeyName,'_',vSplitName);
502 if (vSplitName[0] == "sf")
503 {
504 addHistogramToSFMap(kKey, sKeyName);
505 }
506 else
507 {
508 // std::string sDirection = vSplitName[1];
509 if (sKeyName.find("_up_") != std::string::npos or sKeyName.find("_down_") != std::string::npos)
510 addHistogramToSFMap(kKey, sKeyName);
511 else
512 {
513 size_t iPos = sKeyName.find('_');
514 addHistogramToSFMap(kKey, sKeyName.substr(0,iPos)+"_up"+sKeyName.substr(iPos));
515 addHistogramToSFMap(kKey, sKeyName.substr(0,iPos)+"_down"+sKeyName.substr(iPos));
516 }
517 }
518 }
519 ATH_MSG_INFO("data loaded from " << fFile.GetName());
520}
521
522/*
523 Create the tuple objects for the map
524*/
525//______________________________________________________________________________
526void CommonEfficiencyTool::addHistogramToSFMap(TKey* kKey, const std::string& sKeyName)
527{
528 // handling for the 3 different input types TH1F/TH1D/TF1, function pointer
529 // handle the access methods for the final scale factor retrieval
530 TClass *cClass = gROOT->GetClass(kKey->GetClassName());
531 if (cClass->InheritsFrom("TH2"))
532 {
533 TH1* oObject = (TH1*)kKey->ReadObj();
534 oObject->SetDirectory(0);
535 (*m_mSF)[sKeyName] = tTupleObjectFunc(oObject,&getValueTH2);
536 ATH_MSG_DEBUG("added histogram with name "<<sKeyName);
537 }
538 else if (cClass->InheritsFrom("TH1"))
539 {
540 TH1* oObject = (TH1*)kKey->ReadObj();
541 oObject->SetDirectory(0);
542 (*m_mSF)[sKeyName] = tTupleObjectFunc(oObject,&getValueTH1);
543 ATH_MSG_DEBUG("added histogram with name "<<sKeyName);
544 }
545 else if (cClass->InheritsFrom("TF1"))
546 {
547 TObject* oObject = kKey->ReadObj();
548 (*m_mSF)[sKeyName] = tTupleObjectFunc(oObject,&getValueTF1);
549 ATH_MSG_DEBUG("added function with name "<<sKeyName);
550 }
551 else
552 {
553 ATH_MSG_DEBUG("ignored object with name "<<sKeyName);
554 }
555}
556
557/*
558 This function parses the names of the obejects from the input file and
559 generates the systematic sets and defines which ones are recommended or only
560 available. It also checks, based on the root file name, on which tau it needs
561 to be applied, e.g. only on reco taus coming from true taus or on those faked
562 by true electrons...
563
564 Examples:
565 filename: Reco_TrueHadTau_2016-ichep.root -> apply only to true taus
566 histname: sf_1p -> nominal 1p scale factor
567 histname: TOTAL_3p -> "total" 3p NP, recommended
568 histname: afii_1p -> "total" 3p NP, not recommended, but available
569*/
570//______________________________________________________________________________
572{
573 // creation of basic string for all NPs, e.g. "TAUS_TRUEHADTAU_EFF_RECO_"
574 std::vector<std::string> vSplitInputFilePath = {};
575 split(m_sInputFileName,'_',vSplitInputFilePath);
576 std::string sEfficiencyType = vSplitInputFilePath.at(0);
577 std::string sTruthType = vSplitInputFilePath.at(1);
578 std::transform(sEfficiencyType.begin(), sEfficiencyType.end(), sEfficiencyType.begin(), toupper);
579 std::transform(sTruthType.begin(), sTruthType.end(), sTruthType.begin(), toupper);
580 std::string sSystematicBaseString = "TAUS_"+sTruthType+"_EFF_"+sEfficiencyType+"_";
581
582 // set truth type to check for in truth matching
583 if (sTruthType=="TRUEHADTAU") m_eCheckTruth = TauAnalysisTools::TruthHadronicTau;
584 else if (sTruthType=="TRUEELECTRON") m_eCheckTruth = TauAnalysisTools::TruthElectron;
585 // 3p eVeto, still need this to be measurable in T&P
586 if (sEfficiencyType=="ELERNN" || sEfficiencyType=="ELEOLR") m_bNoMultiprong = true;
587
588 for (auto mSF : *m_mSF)
589 {
590 // parse for nuisance parameter in histogram name
591 std::vector<std::string> vSplitNP = {};
592 split(mSF.first,'_',vSplitNP);
593 std::string sNP = vSplitNP.at(0);
594 std::string sNPUppercase = vSplitNP.at(0);
595
596 // skip nominal scale factors
597 if (sNP == "sf") continue;
598
599 // skip if 3p histogram to avoid duplications (TODO: come up with a better solution)
600 //if (mSF.first.find("_3p") != std::string::npos) continue;
601
602 // test if NP starts with a capital letter indicating that this should be recommended
603 bool bIsRecommended = false;
604 if (isupper(sNP.at(0)) || isupper(sNP.at(1)))
605 bIsRecommended = true;
606
607 // make sNP uppercase and build final NP entry name
608 std::transform(sNPUppercase.begin(), sNPUppercase.end(), sNPUppercase.begin(), toupper);
609 std::string sSystematicString = sSystematicBaseString+sNPUppercase;
610
611 // add all found systematics to the AffectingSystematics
612 m_sAffectingSystematics.insert(CP::SystematicVariation (sSystematicString, 1));
613 m_sAffectingSystematics.insert(CP::SystematicVariation (sSystematicString, -1));
614 // only add found uppercase systematics to the RecommendedSystematics
615 if (bIsRecommended)
616 {
617 m_sRecommendedSystematics.insert(CP::SystematicVariation (sSystematicString, 1));
618 m_sRecommendedSystematics.insert(CP::SystematicVariation (sSystematicString, -1));
619 }
620
621 ATH_MSG_DEBUG("connected base name " << sNP << " with systematic " <<sSystematicString);
622 m_mSystematicsHistNames.insert({sSystematicString,sNP});
623 }
624}
625
626/*
627 return value from the tuple map object based on the pt/eta values (or the
628 corresponding value in case of configuration)
629*/
630//______________________________________________________________________________
633 double& dEfficiencyScaleFactor) const
634{
635
636
637 const tSFMAP& mSF = *m_mSF;
638 auto it = mSF.find (sHistName);
639 if (it == mSF.end())
640 {
641 ATH_MSG_ERROR("Object with name "<<sHistName<<" was not found in input file.");
642 ATH_MSG_DEBUG("Content of input file");
643 for (auto eEntry : mSF)
644 ATH_MSG_DEBUG(" Entry: "<<eEntry.first);
646 }
647
648 // get a tuple (TObject*,functionPointer) from the scale factor map
649 tTupleObjectFunc tTuple = it->second;
650
651 // get pt and eta (for x and y axis respectively)
652 // need columnar migration
653 double dPt = m_fX(tau.getXAODObject());
654 double dEta = m_fY(tau.getXAODObject());
655
656 double dVars[2] = {dPt, dEta};
657
658 // finally obtain efficiency scale factor from TH1F/TH1D/TF1, by calling the
659 // function pointer stored in the tuple from the scale factor map
660 return (std::get<1>(tTuple))(std::get<0>(tTuple), dEfficiencyScaleFactor, dVars);
661}
662
663/*
664 find the particular value in TH1 depending on pt (or the
665 corresponding value in case of configuration)
666 Note: In case values are outside of bin ranges, the closest bin value is used
667*/
668//______________________________________________________________________________
670 double& dEfficiencyScaleFactor, double dVars[])
671{
672 double dPt = dVars[0];
673
674 const TH1* hHist = dynamic_cast<const TH1*>(oObject);
675
676 if (!hHist)
677 {
678 // ATH_MSG_ERROR("Problem with casting TObject of type "<<oObject->ClassName()<<" to TH2F");
680 }
681
682 // protect values from underflow bins
683 dPt = std::max(dPt,hHist->GetXaxis()->GetXmin());
684 // protect values from overflow bins (times .999 to keep it inside last bin)
685 dPt = std::min(dPt,hHist->GetXaxis()->GetXmax() * .999);
686
687 // get bin from TH2 depending on x and y values; finally set the scale factor
688 int iBin = hHist->FindFixBin(dPt);
689 dEfficiencyScaleFactor = hHist->GetBinContent(iBin);
691}
692
693/*
694 find the particular value in TH2 depending on pt and eta (or the
695 corresponding value in case of configuration)
696 Note: In case values are outside of bin ranges, the closest bin value is used
697*/
698//______________________________________________________________________________
700 double& dEfficiencyScaleFactor, double dVars[])
701{
702 double dPt = dVars[0];
703 double dEta = dVars[1];
704
705 const TH2* hHist = dynamic_cast<const TH2*>(oObject);
706
707 if (!hHist)
708 {
709 // ATH_MSG_ERROR("Problem with casting TObject of type "<<oObject->ClassName()<<" to TH2F");
711 }
712
713 // protect values from underflow bins
714 dPt = std::max(dPt,hHist->GetXaxis()->GetXmin());
715 dEta = std::max(dEta,hHist->GetYaxis()->GetXmin());
716 // protect values from overflow bins (times .999 to keep it inside last bin)
717 dPt = std::min(dPt,hHist->GetXaxis()->GetXmax() * .999);
718 dEta = std::min(dEta,hHist->GetYaxis()->GetXmax() * .999);
719
720 // get bin from TH2 depending on x and y values; finally set the scale factor
721 int iBin = hHist->FindFixBin(dPt,dEta);
722 dEfficiencyScaleFactor = hHist->GetBinContent(iBin);
724}
725
726/*
727 Find the particular value in TF1 depending on pt and eta (or the corresponding
728 value in case of configuration)
729*/
730//______________________________________________________________________________
732 double& dEfficiencyScaleFactor, double dVars[])
733{
734 double dPt = dVars[0];
735 double dEta = dVars[1];
736
737 const TF1* fFunc = static_cast<const TF1*>(oObject);
738
739 if (!fFunc)
740 {
741 // ATH_MSG_ERROR("Problem with casting TObject of type "<<oObject->ClassName()<<" to TF1");
743 }
744
745 // evaluate TFunction and set scale factor
746 dEfficiencyScaleFactor = fFunc->Eval(dPt, dEta);
748}
749
751{
752
753 const Accessors& acc = *m_accessors;
754 unsigned int runNumber = 0;
755 if (!acc.randomrunnumber.isAvailable(event)) {
757 "Pileup tool not run before using ElectronEfficiencyTool! SFs do not "
758 "reflect PU distribution in data");
759 return;
760 }
761 runNumber = acc.randomrunnumber(event);
762
763 for (columnar::TauJetId tau : taus)
764 {
765 double sf = 0;
766 switch (getEfficiencyScaleFactor(tau, sf, runNumber).code())
767 {
769 acc.m_sfDec(tau) = sf;
770 acc.m_validDec(tau) = true;
771 break;
773 acc.m_sfDec(tau) = sf;
774 acc.m_validDec(tau) = false;
775 break;
776 default:
777 throw std::runtime_error("Error in getEfficiencyScaleFactor");
778 }
779 }
780}
781
783{
784 const Accessors& acc = *m_accessors;
785 for (columnar::EventContextId event : events)
786 {
787 auto eventInfo = acc.m_eventInfo(event);
788 callSingleEvent (acc.m_taus(event), eventInfo);
789 }
790}
791
792
793
794
#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
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".
Definition TauJet.h:17