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