ATLAS Offline Software
Loading...
Searching...
No Matches
CommonDiTauSmearingTool.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// Framework include(s):
7
8// local include(s)
10
11// ROOT include(s)
12#include "TROOT.h"
13#include "TClass.h"
14#include "TKey.h"
15#include "TH3.h"
16
17
18using namespace TauAnalysisTools;
19
20//______________________________________________________________________________
30
31/*
32 - Find the root files with smearing inputs on eos/cvmfs using PathResolver
33 - Call further functions to process and define NP strings and so on
34 - Configure to provide nominal smearings by default
35*/
37{
38 ATH_MSG_INFO( "Initializing CommonDiTauSmearingTool" );
39
40 // only read in histograms once
41 if (m_mDTSF.empty())
42 {
43 std::string sInputFilePath = PathResolverFindCalibFile(m_sInputFilePath);
44 std::unique_ptr< TFile > fSF( TFile::Open(sInputFilePath.c_str(), "READ") );
45 if(fSF == nullptr)
46 {
47 ATH_MSG_FATAL("Could not open file " << sInputFilePath.c_str());
48 return StatusCode::FAILURE;
49 }
50 ReadInputs(fSF.get(), m_mDTSF);
51 fSF->Close();
52 }
53
55
56 // load empty systematic variation by default
57 if (applySystematicVariation(CP::SystematicSet()) != StatusCode::SUCCESS )
58 return StatusCode::FAILURE;
59
60 return StatusCode::SUCCESS;
61}
62
63/*
64 Retrieve the smearing value and if requested the values for the NP's and add
65 this stuff in quadrature. Finally apply the correction to the tau pt of the
66 non-const tau.
67*/
68//______________________________________________________________________________
70{
71 // step out here if we run on data
72 if (m_bIsData)
74
75 // check which true state is requested
77 {
79 }
80
81 double dCorrection = 1.;
82 // get standard scale factor
83 CP::CorrectionCode tmpCorrectionCode = getValue("sf",
84 xDiTau,
85 dCorrection);
86 // return correction code if histogram is not available
87 if (tmpCorrectionCode != CP::CorrectionCode::Ok)
88 return tmpCorrectionCode;
89
90 // skip further process if systematic set is empty
91 if (m_sSystematicSet->size() > 0)
92 {
93 // get uncertainties summed in quadrature
94 double dTotalSystematic2 = 0;
95 double dDirection = 0;
96 for (auto syst : *m_sSystematicSet)
97 {
98 // check if systematic is available
99 auto it = m_mSystematicsHistNames.find(syst.basename());
100
101 // get uncertainty value
102 double dUncertaintySyst = 0;
103 tmpCorrectionCode = getValue(it->second,
104 xDiTau,
105 dUncertaintySyst);
106
107 // return correction code if histogram is not available
108 if (tmpCorrectionCode != CP::CorrectionCode::Ok)
109 return tmpCorrectionCode;
110
111 // needed for up/down decision
112 dDirection = syst.parameter();
113
114 // scale uncertainty with direction, i.e. +/- n*sigma
115 dUncertaintySyst *= dDirection;
116
117 // square uncertainty and add to total uncertainty
118 dTotalSystematic2 += dUncertaintySyst * dUncertaintySyst;
119 }
120
121 // now use dDirection to use up/down uncertainty
122 dDirection = (dDirection > 0) ? +1 : -1;
123
124 // finally apply uncertainty (eff * ( 1 +/- \sum )
125 dCorrection *= 1 + dDirection * std::sqrt(dTotalSystematic2);
126 }
127
128 // finally apply correction
129 xDiTau.setP4( xDiTau.pt() * dCorrection,
130 xDiTau.eta(), xDiTau.phi(), xDiTau.m());
132}
133
134/*
135 Create a non-const copy of the passed const xDiTau object and apply the
136 correction to the non-const copy.
137 */
138//______________________________________________________________________________
140 xAOD::DiTauJet*& xDiTauCopy ) const
141{
142
143 // A sanity check:
144 if( xDiTauCopy )
145 {
146 ATH_MSG_WARNING( "Non-null pointer received. "
147 "There's a possible memory leak!" );
148 }
149
150 // Create a new object:
151 xDiTauCopy = new xAOD::DiTauJet();
152 xDiTauCopy->makePrivateStore( xDiTau );
153
154 // Use the other function to modify this object:
155 return applyCorrection( *xDiTauCopy );
156}
157
158/*
159 standard check if a systematic is available
160*/
161//______________________________________________________________________________
163{
165 return sys.find(systematic) != sys.end();
166}
167
168/*
169 standard way to return systematics that are available (including recommended
170 systematics)
171*/
172//______________________________________________________________________________
177
178/*
179 standard way to return systematics that are recommended
180*/
181//______________________________________________________________________________
186
187/*
188 Configure the tool to use a systematic variation for further usage, until the
189 tool is reconfigured with this function. The passed systematic set is checked
190 for sanity:
191 - unsupported systematics are skipped
192 - only combinations of up or down supported systematics is allowed
193 - don't mix recommended systematics with other available systematics, cause
194 sometimes recommended are a quadratic sum of the other variations,
195 e.g. TOTAL=(SYST^2 + STAT^2)^0.5
196*/
197//______________________________________________________________________________
199{
200 // first check if we already know this systematic configuration
201 auto itSystematicSet = m_mSystematicSets.find(sSystematicSet);
202 if (itSystematicSet != m_mSystematicSets.end())
203 {
204 m_sSystematicSet = &itSystematicSet->first;
205 return StatusCode::SUCCESS;
206 }
207
208 // sanity checks if systematic set is supported
209 double dDirection = 0.;
210 CP::SystematicSet sSystematicSetAvailable;
211 for (auto& sSyst : sSystematicSet)
212 {
213 // check if systematic is available
214 auto it = m_mSystematicsHistNames.find(sSyst.basename());
215 if (it == m_mSystematicsHistNames.end())
216 {
217 ATH_MSG_VERBOSE("unsupported systematic variation: "<< sSyst.basename()<<"; skipping this one");
218 continue;
219 }
220
221 if (sSyst.parameter() * dDirection < 0)
222 {
223 ATH_MSG_ERROR("unsupported set of systematic variations, you should either use only \"UP\" or only \"DOWN\" systematics in one set!");
224 ATH_MSG_ERROR("systematic set will not be applied");
225 return StatusCode::FAILURE;
226 }
227 dDirection = sSyst.parameter();
228
229 if ((m_sRecommendedSystematics.find(sSyst.basename()) != m_sRecommendedSystematics.end()) and sSystematicSet.size() > 1)
230 {
231 ATH_MSG_ERROR("unsupported set of systematic variations, you should not combine \"TAUS_{TRUE|FAKE}_SME_TOTAL\" with other systematic variations!");
232 ATH_MSG_ERROR("systematic set will not be applied");
233 return StatusCode::FAILURE;
234 }
235
236 // finally add the systematic to the set of systematics to process
237 sSystematicSetAvailable.insert(sSyst);
238 }
239
240 // store this calibration for future use, and make it current
241 m_sSystematicSet = &m_mSystematicSets.insert(std::pair<CP::SystematicSet,std::string>(sSystematicSetAvailable, sSystematicSet.name())).first->first;
242
243 return StatusCode::SUCCESS;
244}
245
246//=================================PRIVATE-PART=================================
247
248template<class T>
249void CommonDiTauSmearingTool::ReadInputs(TFile* fFile, std::map<std::string, T>& mMap)
250{
251 // initialize function pointer
252 m_fX = &TruthLeadPt;
254 m_fZ = &TruthDeltaR;
255
256 TKey *kKey;
257 TIter itNext(fFile->GetListOfKeys());
258 while ((kKey = (TKey*)itNext()))
259 {
260 TClass *cClass = gROOT->GetClass(kKey->GetClassName());
261 std::string sKeyName = kKey->GetName();
262
263 if (!cClass->InheritsFrom("TH3"))
264 continue;
265
266 T tObj = (T)kKey->ReadObj();
267 tObj->SetDirectory(0);
268 mMap[sKeyName] = tObj;
269 }
270 ATH_MSG_INFO("data loaded from " << fFile->GetName());
271}
272
273//______________________________________________________________________________
275{
276 std::vector<std::string> vInputFilePath;
277 split(m_sInputFilePath,'/',vInputFilePath);
278 std::string sInputFileName = vInputFilePath.back();
279
280 // creation of basic string for all NPs, e.g. "TAUS_TRUEHADTAU_SME_TES_"
281 std::vector<std::string> vSplitInputFilePath = {};
282 split(sInputFileName,'_',vSplitInputFilePath);
283 std::string sEfficiencyType = vSplitInputFilePath.at(0);
284 std::string sTruthType = vSplitInputFilePath.at(1);
285 std::transform(sEfficiencyType.begin(), sEfficiencyType.end(), sEfficiencyType.begin(), toupper);
286 std::transform(sTruthType.begin(), sTruthType.end(), sTruthType.begin(), toupper);
287 std::string sSystematicBaseString = "TAUS_"+sTruthType+"_SME_"+sEfficiencyType+"_";
288
289 // set truth type to check for in truth matching
290 if (sTruthType=="TRUEHADTAU") m_eCheckTruth = TauAnalysisTools::TruthHadronicTau;
291 if (sTruthType=="TRUEHADDITAU") m_eCheckTruth = TauAnalysisTools::TruthHadronicDiTau;
292
293 for (auto mSF : m_mDTSF)
294 {
295 // parse for nuisance parameter in histogram name
296 std::vector<std::string> vSplitNP = {};
297 split(mSF.first,'_',vSplitNP);
298 std::string sNP = vSplitNP.at(0);
299 std::string sNPUppercase = vSplitNP.at(0);
300
301 // skip nominal scale factors
302 if (sNP == "sf") continue;
303
304 // test if NP starts with a capital letter indicating that this should be recommended
305 bool bIsRecommended = false;
306 if (isupper(sNP.at(0)))
307 bIsRecommended = true;
308
309 // make sNP uppercase and build final NP entry name
310 std::transform(sNPUppercase.begin(), sNPUppercase.end(), sNPUppercase.begin(), toupper);
311 std::string sSystematicString = sSystematicBaseString+sNPUppercase;
312
313 // add all found systematics to the AffectingSystematics
314 m_sAffectingSystematics.insert(CP::SystematicVariation (sSystematicString, 1));
315 m_sAffectingSystematics.insert(CP::SystematicVariation (sSystematicString, -1));
316 // only add found uppercase systematics to the RecommendedSystematics
317 if (bIsRecommended)
318 {
319 m_sRecommendedSystematics.insert(CP::SystematicVariation (sSystematicString, 1));
320 m_sRecommendedSystematics.insert(CP::SystematicVariation (sSystematicString, -1));
321 }
322
323 ATH_MSG_DEBUG("connected histogram base name " << sNP << " with systematic " <<sSystematicString);
324 m_mSystematicsHistNames.insert({sSystematicString,sNP});
325 }
326}
327
328//______________________________________________________________________________
330 const xAOD::DiTauJet& xDiTau,
331 double& dEfficiencyScaleFactor) const
332{
333 TH3* hHist = m_mDTSF.at(sHistName);
334 if (!hHist)
335 {
336 ATH_MSG_ERROR("Histogram with name "<<sHistName<<" was not found in input file.");
338 }
339
340 double dX = m_fX(xDiTau);
341 double dY = m_fY(xDiTau);
342 double dZ = m_fZ(xDiTau);
343
344 // protect values from underflow bins
345 dX = std::max(dX,hHist->GetXaxis()->GetXmin());
346 dY = std::max(dY,hHist->GetYaxis()->GetXmin());
347 dZ = std::max(dZ,hHist->GetZaxis()->GetXmin());
348 // protect values from overflow bins (times .999 to keep it inside last bin)
349 dX = std::min(dX,hHist->GetXaxis()->GetXmax() * .999);
350 dY = std::min(dY,hHist->GetYaxis()->GetXmax() * .999);
351 dZ = std::min(dZ,hHist->GetZaxis()->GetXmax() * .999);
352
353 int iBin = hHist->FindFixBin(dX,dY,dZ);
354 dEfficiencyScaleFactor = hHist->GetBinContent(iBin);
355
357}
358
#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)
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.
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
double(* m_fY)(const xAOD::DiTauJet &xDiTau)
CommonDiTauSmearingTool(const std::string &sName)
Create a proper constructor for Athena.
virtual CP::SystematicSet recommendedSystematics() const
returns: the list of all systematics this tool recommends to use
virtual CP::CorrectionCode applyCorrection(xAOD::DiTauJet &xDiTau) const
Apply the correction on a modifiable object.
std::unordered_map< CP::SystematicSet, std::string > m_mSystematicSets
std::map< std::string, std::string > m_mSystematicsHistNames
double(* m_fX)(const xAOD::DiTauJet &xDiTau)
virtual CP::CorrectionCode correctedCopy(const xAOD::DiTauJet &xDiTau, xAOD::DiTauJet *&xDiTauCopy) const
Create a corrected copy from a constant ditau.
virtual bool isAffectedBySystematic(const CP::SystematicVariation &systematic) const
returns: whether this tool is affected by the given systematics
double(* m_fZ)(const xAOD::DiTauJet &xDiTau)
virtual StatusCode applySystematicVariation(const CP::SystematicSet &sSystematicSet)
configure this tool for the given list of systematic variations.
virtual CP::SystematicSet affectingSystematics() const
returns: the list of all systematics this tool can be affected by
virtual CP::CorrectionCode getValue(const std::string &sHistName, const xAOD::DiTauJet &xDiTau, double &dCorrectionFactor) const
void ReadInputs(TFile *fFile, std::map< std::string, T > &mMap)
Gaudi::Property< std::string > m_sInputFilePath
virtual StatusCode initialize()
Dummy implementation of the initialisation function.
AsgMetadataTool(const std::string &name)
Normal ASG tool constructor with a name.
void setP4(double pt, double eta, double phi, double m)
Set methods for IParticle values.
virtual double eta() const
The pseudorapidity ( ) of the particle.
virtual double m() const
The invariant mass of the particle.
virtual double pt() const
The transverse momentum ( ) of the particle.
virtual double phi() const
The azimuthal angle ( ) of the particle.
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