71CommonEfficiencyTool::CommonEfficiencyTool(
const std::string& sName)
72 :
asg::AsgTool( sName )
74 , m_sSystematicSet(nullptr)
78 , m_bNoMultiprong(false)
80 , m_bSFIsAvailable(false)
81 , m_bSFIsAvailableChecked(false)
82 , m_accessors{
std::make_unique<Accessors>(*this)}
89CommonEfficiencyTool::~CommonEfficiencyTool()
92 for (
auto mEntry : *m_mSF)
93 delete std::get<0>(mEntry.second);
103StatusCode CommonEfficiencyTool::initialize()
111 m_mSF = std::make_unique< tSFMAP >();
112 std::unique_ptr< TFile > fSF( TFile::Open( sInputFilePath.c_str(),
"READ" ) );
115 ATH_MSG_FATAL(
"Could not open file " << sInputFilePath.c_str());
116 return StatusCode::FAILURE;
123 std::vector<std::string> vInputFilePath;
124 split(m_sInputFilePath,
'/',vInputFilePath);
125 m_sInputFileName = vInputFilePath.back();
127 generateSystematicSets();
130 m_sSFHistName =
"sf_"+m_sWP;
134 return StatusCode::FAILURE;
138 return StatusCode::SUCCESS;
148 double& dEfficiencyScaleFactor,
unsigned int iRunNumber)
150 return getEfficiencyScaleFactor(
columnar::TauJetId(xTau), dEfficiencyScaleFactor, iRunNumber);
156 const Accessors&
acc = *m_accessors;
161 ATH_MSG_DEBUG(
"retrieving the SFs while running on data ...");
162 }
else if (!m_bSkipTruthMatchCheck and
acc.m_truthParticleType(tau) != m_eCheckTruth)
164 dEfficiencyScaleFactor = 1.;
169 int ntracks =
tau.getXAODObject().nTracks();
172 if (m_bNoMultiprong && ntracks != 1)
174 dEfficiencyScaleFactor = 1.;
180 if (m_bUseTauSubstructure)
182 int iDecayMode =
acc.m_decayMode(tau);
183 sMode = ConvertDecayModeToString(iDecayMode);
186 ATH_MSG_WARNING(
"Found tau with unknown decay mode. Skip efficiency correction.");
193 if( ntracks != 1 && ntracks != 3) {
194 dEfficiencyScaleFactor = 1.;
198 sMode = ConvertProngToString(ntracks);
201 std::string sHistName;
203 sHistName =
"sf_all_"+m_sWP+sMode;
205 sHistName = m_sSFHistName + sMode;
211 dEfficiencyScaleFactor);
214 return tmpCorrectionCode;
217 if (m_sSystematicSet->empty())
221 double dTotalSystematic2 = 0.;
222 double dDirection = 0.;
223 for (
const auto & syst : *m_sSystematicSet)
226 auto it = m_mSystematicsHistNames.find(syst.basename());
227 if (it == m_mSystematicsHistNames.end())[[
unlikely]]{
231 double dUncertaintySyst = 0.;
234 dDirection = syst.parameter();
237 sHistName =
it->second;
238 if (dDirection>0.) sHistName+=
"_up";
239 else sHistName+=
"_down";
241 if(m_doTauTrig){ sHistName+=
"_all"; }
243 if (!m_sWP.empty()) sHistName+=
"_"+m_sWP;
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))
252 if( (sHistName.find(
"1520") != std::string::npos && sHistName.find(
"loose") != std::string::npos) ){
257 tmpCorrectionCode = getValue(sHistName,
263 return tmpCorrectionCode;
266 dUncertaintySyst *= dDirection;
269 dTotalSystematic2 += dUncertaintySyst * dUncertaintySyst;
273 dDirection = (dDirection > 0.) ? 1. : -1.;
276 dEfficiencyScaleFactor *= 1. + dDirection * std::sqrt(dTotalSystematic2);
292 unsigned int iRunNumber)
297 if (!m_bSFIsAvailableChecked)
299 m_bSFIsAvailable = decor.isAvailable(xTau);
300 m_bSFIsAvailableChecked =
true;
301 if (m_bSFIsAvailable)
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.");
307 if (m_bSFIsAvailable)
311 CP::CorrectionCode tmpCorrectionCode = getEfficiencyScaleFactor(xTau, dSf, iRunNumber);
315 return tmpCorrectionCode;
327 return sys.find(systematic) !=
sys.end();
337 return m_sAffectingSystematics;
346 return m_sRecommendedSystematics;
360StatusCode CommonEfficiencyTool::applySystematicVariation (
const CP::SystematicSet& sSystematicSet)
364 auto itSystematicSet = m_mSystematicSets.
find(sSystematicSet);
365 if (itSystematicSet != m_mSystematicSets.end())
367 m_sSystematicSet = &itSystematicSet->first;
368 return StatusCode::SUCCESS;
372 double dDirection = 0.;
374 for (
const auto & sSyst : sSystematicSet)
377 auto it = m_mSystematicsHistNames.find(sSyst.basename());
378 if (it == m_mSystematicsHistNames.end())
380 ATH_MSG_VERBOSE(
"unsupported systematic variation: "<< sSyst.basename()<<
"; skipping this one");
385 if (sSyst.parameter() * dDirection < 0)
387 ATH_MSG_ERROR(
"unsupported set of systematic variations, you should either use only \"UP\" or only \"DOWN\" systematics in one set!");
389 return StatusCode::FAILURE;
391 dDirection = sSyst.parameter();
393 if ((m_sRecommendedSystematics.find(sSyst.basename()) != m_sRecommendedSystematics.end()) and sSystematicSet.size() > 1)
395 ATH_MSG_ERROR(
"unsupported set of systematic variations, you should not combine \"TAUS_{TRUE|FAKE}_EFF_*_TOTAL\" with other systematic variations!");
397 return StatusCode::FAILURE;
401 sSystematicSetAvailable.
insert(sSyst);
405 m_sSystematicSet = &m_mSystematicSets.
insert(std::pair<CP::SystematicSet,std::string>(sSystematicSetAvailable, sSystematicSet.name())).first->first;
407 return StatusCode::SUCCESS;
411std::string CommonEfficiencyTool::ConvertProngToString(
const int fProngness)
const
413 return fProngness == 1 ?
"_1p" :
"_3p";
420std::string CommonEfficiencyTool::ConvertDecayModeToString(
const int iDecayMode)
const
449void CommonEfficiencyTool::ReadInputs(
const TFile& fFile)
458 TIter itNext(fFile.GetListOfKeys());
459 while ((kKey = (TKey*)itNext()))
463 std::string sKeyName = kKey->GetName();
464 if (sKeyName ==
"Xaxis")
466 TNamed* tObj = (TNamed*)kKey->ReadObj();
467 std::string sTitle = tObj->GetTitle();
469 if (sTitle ==
"TruthDecayMode")
471 m_fX = &truthDecayMode;
474 if (sTitle ==
"truth visible pt")
476 m_fX = &truthVisTauPt;
479 if (sTitle ==
"|eta|")
481 m_fX = &finalTauAbsEta;
487 else if (sKeyName ==
"Yaxis")
489 TNamed* tObj = (TNamed*)kKey->ReadObj();
490 std::string sTitle = tObj->GetTitle();
492 if (sTitle ==
"|eta|")
494 m_fY = &finalTauAbsEta;
497 else if (sTitle ==
"truth |eta|")
499 m_fY = &truthTauAbsEta;
505 std::vector<std::string> vSplitName = {};
506 split(sKeyName,
'_',vSplitName);
507 if (vSplitName[0] ==
"sf")
509 addHistogramToSFMap(kKey, sKeyName);
514 if (sKeyName.find(
"_up_") != std::string::npos or sKeyName.find(
"_down_") != std::string::npos)
515 addHistogramToSFMap(kKey, sKeyName);
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));
531void CommonEfficiencyTool::addHistogramToSFMap(TKey* kKey,
const std::string& sKeyName)
535 TClass *cClass = gROOT->GetClass(kKey->GetClassName());
536 if (cClass->InheritsFrom(
"TH2"))
538 TH1* oObject = (TH1*)kKey->ReadObj();
539 oObject->SetDirectory(0);
540 (*m_mSF)[sKeyName] = tTupleObjectFunc(oObject,&getValueTH2);
543 else if (cClass->InheritsFrom(
"TH1"))
545 TH1* oObject = (TH1*)kKey->ReadObj();
546 oObject->SetDirectory(0);
547 (*m_mSF)[sKeyName] = tTupleObjectFunc(oObject,&getValueTH1);
550 else if (cClass->InheritsFrom(
"TF1"))
552 TObject* oObject = kKey->ReadObj();
553 (*m_mSF)[sKeyName] = tTupleObjectFunc(oObject,&getValueTF1);
576void CommonEfficiencyTool::generateSystematicSets()
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+
"_";
591 if (sEfficiencyType==
"ELERNN" || sEfficiencyType==
"ELEOLR") m_bNoMultiprong =
true;
593 for (
const auto & mSF : *m_mSF)
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);
602 if (sNP ==
"sf")
continue;
608 bool bIsRecommended =
false;
609 if (isupper(sNP.at(0)) || isupper(sNP.at(1)))
610 bIsRecommended =
true;
613 std::transform(sNPUppercase.begin(), sNPUppercase.end(), sNPUppercase.begin(), toupper);
614 std::string sSystematicString = sSystematicBaseString+sNPUppercase;
626 ATH_MSG_DEBUG(
"connected base name " << sNP <<
" with systematic " <<sSystematicString);
627 m_mSystematicsHistNames.insert({sSystematicString,sNP});
638 double& dEfficiencyScaleFactor)
const
642 const tSFMAP& mSF = *m_mSF;
643 auto it = mSF.find (sHistName);
646 ATH_MSG_ERROR(
"Object with name "<<sHistName<<
" was not found in input file.");
648 for (
const auto & eEntry : mSF)
654 tTupleObjectFunc tTuple =
it->second;
658 double dPt = m_fX(
tau.getXAODObject());
659 double dEta = m_fY(
tau.getXAODObject());
661 double dVars[2] = {dPt,
dEta};
665 return (std::get<1>(tTuple))(std::get<0>(tTuple), dEfficiencyScaleFactor, dVars);
675 double& dEfficiencyScaleFactor,
double dVars[])
677 double dPt = dVars[0];
679 const TH1* hHist =
dynamic_cast<const TH1*
>(oObject);
688 dPt = std::max(dPt,hHist->GetXaxis()->GetXmin());
690 dPt = std::min(dPt,hHist->GetXaxis()->GetXmax() * .999);
693 int iBin = hHist->FindFixBin(dPt);
694 dEfficiencyScaleFactor = hHist->GetBinContent(iBin);
705 double& dEfficiencyScaleFactor,
double dVars[])
707 double dPt = dVars[0];
708 double dEta = dVars[1];
710 const TH2* hHist =
dynamic_cast<const TH2*
>(oObject);
719 dPt = std::max(dPt,hHist->GetXaxis()->GetXmin());
720 dEta = std::max(dEta,hHist->GetYaxis()->GetXmin());
722 dPt = std::min(dPt,hHist->GetXaxis()->GetXmax() * .999);
723 dEta = std::min(dEta,hHist->GetYaxis()->GetXmax() * .999);
726 int iBin = hHist->FindFixBin(dPt,dEta);
727 dEfficiencyScaleFactor = hHist->GetBinContent(iBin);
737 double& dEfficiencyScaleFactor,
double dVars[])
739 double dPt = dVars[0];
740 double dEta = dVars[1];
742 const TF1* fFunc =
static_cast<const TF1*
>(oObject);
751 dEfficiencyScaleFactor = fFunc->Eval(dPt, dEta);
758 const Accessors&
acc = *m_accessors;
760 if (!
acc.randomrunnumber.isAvailable(event)) {
762 "Pileup tool not run before using ElectronEfficiencyTool! SFs do not "
763 "reflect PU distribution in data");
771 switch (getEfficiencyScaleFactor(tau, sf, runNumber).code())
774 acc.m_sfDec(tau) =
sf;
775 acc.m_validDec(tau) =
true;
778 acc.m_sfDec(tau) =
sf;
779 acc.m_validDec(tau) =
false;
782 throw std::runtime_error(
"Error in getEfficiencyScaleFactor");
789 const Accessors&
acc = *m_accessors;
792 auto eventInfo =
acc.m_eventInfo(event);
793 callSingleEvent (
acc.m_taus(event), eventInfo);
#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,...)
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
struct TBPatternUnitContext Unknown
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.
void insert(const SystematicVariation &systematic)
description: insert a systematic into the set
iterator find(const SystematicVariation &sys) const
description: find an element in the set
std::vector< std::string > split(const std::string &s, const std::string &t=":")
SG::Decorator< T, ALLOC > Decorator
Helper class to provide type-safe access to aux data, specialized for JaggedVecElt.
bool dEta(const xAOD::TauJet &tau, const xAOD::CaloVertexedTopoCluster &cluster, float &out)
ObjectRange< TauJetDef > TauJetRange
ObjectRange< EventContextDef > EventContextRange
ObjectId< EventContextDef > EventContextId
ObjectId< TauJetDef > TauJetId
ObjectId< EventInfoDef > EventInfoId
TauJet_v3 TauJet
Definition of the current "tau version".