ATLAS Offline Software
Loading...
Searching...
No Matches
CommonDiTauEfficiencyTool.cxx
Go to the documentation of this file.
1
4
5// Framework include(s):
7
8// local include(s)
11
12// ROOT include(s)
13#include "TH2F.h"
14#include <utility>
15
16using namespace TauAnalysisTools;
17
18//______________________________________________________________________________
28
32
33
34/*
35 - Find the root files with scale factor inputs on cvmfs using PathResolver
36 (more info here:
37 https://twiki.cern.ch/twiki/bin/viewauth/AtlasComputing/PathResolver)
38 - Call further functions to process and define NP strings and so on
39 - Configure to provide nominal scale factors by default
40*/
42{
43 ATH_MSG_INFO( "Initializing CommonDiTauEfficiencyTool" );
44 // only read in histograms once
45 if (m_mSF==nullptr)
46 {
47 std::string sInputFilePath = PathResolverFindCalibFile(m_sInputFilePath);
48
49 m_mSF = std::make_unique< tSFMAP >();
50 std::unique_ptr< TFile > fSF( TFile::Open( sInputFilePath.c_str(), "READ" ) );
51 if(!fSF)
52 {
53 ATH_MSG_FATAL("Could not open file " << sInputFilePath.c_str());
54 return StatusCode::FAILURE;
55 }
56 ReadInputs(fSF);
57 fSF->Close();
58 }
59
60 // needed later on in generateSystematicSets(), maybe move it there
61 std::vector<std::string> vInputFilePath;
62 split(m_sInputFilePath,'/',vInputFilePath);
63 m_sInputFileName = vInputFilePath.back();
64
66
67 if (m_sWP.size()>0)
68 m_sSFHistName = "sf_"+m_sWP;
69
70 // load empty systematic variation by default
71 if (applySystematicVariation(CP::SystematicSet()) != StatusCode::SUCCESS )
72 return StatusCode::FAILURE;
73
74 return StatusCode::SUCCESS;
75}
76
77
78
79/*
80 Retrieve the scale factors and if requested the values for the NP's and add
81 this stuff in quadrature. Finally return sf_nom +/- n*uncertainty
82*/
83//______________________________________________________________________________
85 double& dEfficiencyScaleFactor)
86{
87 // check which true state is requestet
89 {
90 dEfficiencyScaleFactor = 1.;
92 }
93
94 CP::CorrectionCode tmpCorrectionCode = getValue(m_sSFHistName,
95 xDiTau,
96 dEfficiencyScaleFactor);
97 // return correction code if histogram is not available
98 if (tmpCorrectionCode != CP::CorrectionCode::Ok)
99 return tmpCorrectionCode;
100
101 // skip further process if systematic set is empty
102 if (m_sSystematicSet->size() == 0)
104
105 // get uncertainties summed in quadrature
106 double dTotalSystematic2 = 0.;
107 double dDirection = 0.;
108 for (auto syst : *m_sSystematicSet)
109 {
110
111 // check if systematic is available
112 auto it = m_mSystematicsHistNames.find(syst.basename());
113
114 // get uncertainty value
115 double dUncertaintySyst = 0.;
116
117 // needed for up/down decision
118 dDirection = syst.parameter();
119
120 // build up histogram name
121 std::string sHistName = it->second;
122 if (dDirection>0) sHistName+="_up";
123 else sHistName+="_down";
124 if (!m_sWP.empty()) sHistName+="_"+m_sWP;
125
126 // get the uncertainty from the histogram
127 tmpCorrectionCode = getValue(sHistName,
128 xDiTau,
129 dUncertaintySyst);
130
131 // return correction code if histogram is not available
132 if (tmpCorrectionCode != CP::CorrectionCode::Ok)
133 return tmpCorrectionCode;
134
135 // scale uncertainty with direction, i.e. +/- n*sigma
136 dUncertaintySyst *= dDirection;
137
138 // square uncertainty and add to total uncertainty
139 dTotalSystematic2 += dUncertaintySyst * dUncertaintySyst;
140 }
141
142 // now use dDirection to use up/down uncertainty
143 dDirection = (dDirection > 0.) ? 1. : -1.;
144
145 // finally apply uncertainty (eff * ( 1 +/- \sum )
146 dEfficiencyScaleFactor *= 1. + dDirection * std::sqrt(dTotalSystematic2);
147
149}
150
151/*
152 Get scale factor from getEfficiencyScaleFactor and decorate it to the
153 tau. Note that this can only be done if the variable name is not already used,
154 e.g. if the variable was already decorated on a previous step (enured by the
155 m_bSFIsAvailableCheckedDiTau check).
156
157 Technical note: cannot use `static SG::Decorator` as we will have
158 multiple instances of this tool with different decoration names.
159*/
160//______________________________________________________________________________
162{
163 double dSf = 0.;
164
167 {
168 m_bSFIsAvailableDiTau = decor.isAvailable(xDiTau);
171 {
172 ATH_MSG_DEBUG(m_sVarName << " decoration is available on first ditau processed, switched of applyEfficiencyScaleFactor for further ditaus.");
173 ATH_MSG_DEBUG("If an application of efficiency scale factors needs to be redone, please pass a shallow copy of the original ditau.");
174 }
175 }
178
179 // retrieve scale factor
180 CP::CorrectionCode tmpCorrectionCode = getEfficiencyScaleFactor(xDiTau, dSf);
181 // adding scale factor to tau as decoration
182 decor(xDiTau) = dSf;
183
184 return tmpCorrectionCode;
185}
186
187
188// //______________________________________________________________________________
189void CommonDiTauEfficiencyTool::ReadInputs(std::unique_ptr<TFile> &fFile)
190{
191 m_mSF->clear();
192
193 // initialize function pointer
197
198 TKey *kKey;
199 TIter itNext(fFile->GetListOfKeys());
200 while ((kKey = (TKey*)itNext()))
201 {
202 // parse file content for objects of type TNamed, check their title for
203 // known strings and reset funtion pointer
204 std::string sKeyName = kKey->GetName();
205
206 std::vector<std::string> vSplitName = {};
207 split(sKeyName,'_',vSplitName);
208 if (vSplitName[0] == "sf")
209 {
210 addHistogramToSFMap(kKey, sKeyName);
211 }
212 else
213 {
214 if (sKeyName.find("_up_") != std::string::npos or sKeyName.find("_down_") != std::string::npos)
215 addHistogramToSFMap(kKey, sKeyName);
216 else
217 {
218 size_t iPos = sKeyName.find('_');
219 addHistogramToSFMap(kKey, sKeyName.substr(0,iPos)+"_up"+sKeyName.substr(iPos));
220 addHistogramToSFMap(kKey, sKeyName.substr(0,iPos)+"_down"+sKeyName.substr(iPos));
221 }
222 }
223 }
224 ATH_MSG_INFO("data loaded from " << fFile->GetName());
225}
226
227
228/*
229 This function parses the names of the objects from the input file and
230 generates the systematic sets and defines which ones are recommended or only
231 available. It also checks, based on the root file name, on which tau it needs
232 to be applied, e.g. only on reco taus coming from true taus or on those faked
233 by true electrons...
234 Examples:
235 filename: JetID_TrueHadDiTau_2017-fall.root -> apply only to true ditaus
236 histname: sf_* -> nominal scale factor
237 histname: TOTAL_* -> "total" NP, recommended
238 histname: afii_* -> "total" NP, not recommended, but available
239*/
240//______________________________________________________________________________
242{
243 // creation of basic string for all NPs, e.g. "TAUS_TRUEHADTAU_EFF_RECO_"
244 std::vector<std::string> vSplitInputFilePath = {};
245 split(m_sInputFileName,'_',vSplitInputFilePath);
246 std::string sEfficiencyType = vSplitInputFilePath.at(0);
247 std::string sTruthType = vSplitInputFilePath.at(1);
248 std::transform(sEfficiencyType.begin(), sEfficiencyType.end(), sEfficiencyType.begin(), toupper);
249 std::transform(sTruthType.begin(), sTruthType.end(), sTruthType.begin(), toupper);
250 std::string sSystematicBaseString = "TAUS_"+sTruthType+"_EFF_"+sEfficiencyType+"_";
251 // set truth type to check for in truth matching
252 if (sTruthType=="TRUEHADTAU") m_eCheckTruth = TauAnalysisTools::TruthHadronicTau;
253 if (sTruthType=="TRUEHADDITAU") m_eCheckTruth = TauAnalysisTools::TruthHadronicDiTau;
254
255 for (auto mSF : *m_mSF)
256 {
257 // parse for nuisance parameter in histogram name
258 std::vector<std::string> vSplitNP = {};
259 split(mSF.first,'_',vSplitNP);
260 std::string sNP = vSplitNP.at(0);
261 std::string sNPUppercase = vSplitNP.at(0);
262 // skip nominal scale factors
263 if (sNP == "sf") continue;
264 // test if NP starts with a capital letter indicating that this should be recommended
265 bool bIsRecommended = false;
266 if (isupper(sNP.at(0)))
267 bIsRecommended = true;
268 // make sNP uppercase and build final NP entry name
269 std::transform(sNPUppercase.begin(), sNPUppercase.end(), sNPUppercase.begin(), toupper);
270 std::string sSystematicString = sSystematicBaseString+sNPUppercase;
271 // add all found systematics to the AffectingSystematics
272 m_sAffectingSystematics.insert(CP::SystematicVariation (sSystematicString, 1));
273 m_sAffectingSystematics.insert(CP::SystematicVariation (sSystematicString, -1));
274 // only add found uppercase systematics to the RecommendedSystematics
275 if (bIsRecommended)
276 {
277 m_sRecommendedSystematics.insert(CP::SystematicVariation (sSystematicString, 1));
278 m_sRecommendedSystematics.insert(CP::SystematicVariation (sSystematicString, -1));
279 }
280 ATH_MSG_DEBUG("connected base name " << sNP << " with systematic " <<sSystematicString);
281 m_mSystematicsHistNames.insert({sSystematicString,sNP});
282 }
283}
284
285/*
286 return value from the tuple map object based on the pt/eta values (or the
287 corresponding value in case of configuration)
288*/
289//______________________________________________________________________________
291 const xAOD::DiTauJet& xDiTau,
292 double& dEfficiencyScaleFactor) const
293{
294 const tSFMAP& mSF = *m_mSF;
295 auto it = mSF.find (sHistName);
296 if (it == mSF.end())
297 {
298 ATH_MSG_ERROR("Object with name "<<sHistName<<" was not found in input file.");
299 ATH_MSG_DEBUG("Content of input file");
300 for (auto eEntry : mSF)
301 ATH_MSG_DEBUG(" Entry: "<<eEntry.first);
303 }
304
305 // get a tuple (TObject*,functionPointer) from the scale factor map
306 tTupleObjectFunc tTuple = it->second;
307
308 // get pt and eta (for x and y axis respectively)
309 double dX = m_fXDiTau(xDiTau);
310 double dY = m_fYDiTau(xDiTau);
311 double dZ = m_fZDiTau(xDiTau);
312
313 double dVars[3] = {dX, dY, dZ};
314 // finally obtain efficiency scale factor from TH1F/TH1D/TF1, by calling the
315 // function pointer stored in the tuple from the scale factor map
316 return (std::get<1>(tTuple))(std::get<0>(tTuple), dEfficiencyScaleFactor, dVars);
317}
318
319//______________________________________________________________________________
321{
322 // return leading truth tau pt in GeV
323 static const SG::ConstAccessor< float > acc( "TruthVisLeadPt" );
324 return acc( xDiTau ) * 0.001;
325}
326
327//______________________________________________________________________________
329{
330 // return subleading truth tau pt in GeV
331 static const SG::ConstAccessor< float > acc( "TruthVisSubleadPt" );
332 return acc( xDiTau ) * 0.001;
333}
334
335//______________________________________________________________________________
337{
338 // return truth taus distance delta R
339 static const SG::ConstAccessor< float > acc( "TruthVisDeltaR" );
340 return acc( xDiTau );
341}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Return value from object correction CP tools.
@ Error
Some error happened during the object correction.
@ Ok
The correction was done successfully.
Class to wrap a set of SystematicVariations.
Helper class to provide type-safe access to aux data.
Definition Decorator.h:59
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
double(* m_fXDiTau)(const xAOD::DiTauJet &xDiTau)
scale factor bin x (e.g.
CommonDiTauEfficiencyTool(const std::string &sName)
Create a proper constructor for Athena.
void generateSystematicSets()
generate a set of relevant systematic variations to be applied
CP::CorrectionCode getValue(const std::string &sHistName, const xAOD::DiTauJet &xDiTau, double &dEfficiencyScaleFactor) const
Get the scale factor from a particular recommendations histogram.
bool m_bSFIsAvailableDiTau
true if scale factor name is already decorated
virtual StatusCode initialize() override
Dummy implementation of the initialisation function.
double(* m_fZDiTau)(const xAOD::DiTauJet &xDiTau)
scale factor bin z (e.g.
void ReadInputs(std::unique_ptr< TFile > &fFile)
virtual CP::CorrectionCode applyEfficiencyScaleFactor(const xAOD::DiTauJet &xDiTau) override
Get the Efficiency Scale Factor of ditau jet.
bool m_bSFIsAvailableCheckedDiTau
true if cale factor name is already decorated has already been checked
double(* m_fYDiTau)(const xAOD::DiTauJet &xDiTau)
scale factor bin y (e.g.
virtual CP::CorrectionCode getEfficiencyScaleFactor(const xAOD::DiTauJet &xDiTau, double &dEfficiencyScaleFactor) override
Get the Efficiency Scale Factor of ditau jet.
virtual StatusCode applySystematicVariation(const CP::SystematicSet &sSystematicSet)
configure this tool for the given list of systematic variations.
CommonEfficiencyTool(const std::string &sName)
Create a proper constructor for Athena.
std::map< std::string, tTupleObjectFunc > tSFMAP
Gaudi::Property< std::string > m_sInputFilePath
std::tuple< TObject *, CP::CorrectionCode(*)(const TObject *oObject, double &dEfficiencyScaleFactor, double dVars[]) > tTupleObjectFunc
void addHistogramToSFMap(TKey *kKey, const std::string &sKeyName)
std::map< std::string, std::string > m_mSystematicsHistNames
Gaudi::Property< std::string > m_sVarName
double TruthSubleadPt(const xAOD::DiTauJet &xDiTau)
return the truth vis pT of the subleading pT matched particle.
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 TruthDeltaR(const xAOD::DiTauJet &xDiTau)
return the dR of between the leading and subleading pT matched particle.
double TruthLeadPt(const xAOD::DiTauJet &xDiTau)
return the truth vis pT of the leading pT matched particle.
DiTauJet_v1 DiTauJet
Definition of the current version.
Definition DiTauJet.h:17