ATLAS Offline Software
Loading...
Searching...
No Matches
IsolationCorrectionTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include "xAODEgamma/Egamma.h"
8#include "xAODEgamma/Photon.h"
13
14#ifndef ROOTCORE
17#endif //ROOTCORE
18
19#include "TFile.h"
20
21namespace CP {
22
23 IsolationCorrectionTool::IsolationCorrectionTool( const std::string &name )
24 : asg::AsgMetadataTool(name), m_systDDonoff("PH_Iso_DDonoff") {
25 declareProperty("CorrFile", m_corr_file = "IsolationCorrections/v5/isolation_ptcorrections_rel20_2.root") ;
26 declareProperty("CorrFile_ddshift", m_corr_ddshift_file = "IsolationCorrections/v3/isolation_ddcorrection_shift.root");
27 declareProperty("CorrFile_ddsmearing", m_corr_ddsmearing_file = "IsolationCorrections/v1/isolation_ddcorrection_smearing.root", "a run I smearing for MC calo iso");
28 declareProperty("ToolVer", m_tool_ver_str = "REL21");
29 declareProperty("DataDrivenVer", m_ddVersion = "2017");
30 declareProperty("AFII_corr", m_AFII_corr = false);
31 declareProperty("IsMC", m_is_mc = true);
32 declareProperty("Correct_etcone", m_correct_etcone = false);
33 declareProperty("Trouble_categories", m_trouble_categories = true);
34 declareProperty("LogLogFitForLeakage", m_useLogLogFit = false);
35 declareProperty("FixTimingIssueInCore", m_fixCoreTime = false);
36 declareProperty("ForcePartType", m_forcePartType = false);
37 declareProperty("Apply_ddshifts", m_apply_ddDefault = false);
38 declareProperty("Apply_SC_leakcorr", m_apply_SC_leak_corr = false);
39 declareProperty("Apply_etaEDParPU_correction", m_apply_etaEDParPU_corr = false);
40 declareProperty("Apply_etaEDPar_mc_correction", m_apply_etaEDParPU_mc_corr = false);
41 declareProperty("CorrFile_etaEDParPU_correction", m_corr_etaEDParPU_file = "IsolationCorrections/v6/zetas.root");
42 declareProperty("CorrFile_etaEDPar_mc_correction", m_corr_etaEDPar_mc_corr_file = "IsolationCorrections/v6/zetas_correction.root");
43
44 m_isol_corr = new IsolationCorrection(name);
45 }
46
48 ATH_MSG_INFO( "in initialize of " << name() << "..." );
49
50 //ReadHandles
51 ATH_CHECK(m_eventInfoKey.initialize());
54
55 //
56 m_isol_corr->msg().setLevel(this->msg().level());
57 //
58 // Resolve the paths to the input files
59 std::vector < std::string > corrFileNameList;
60 corrFileNameList.push_back(m_corr_file);
61 corrFileNameList.push_back(m_corr_ddshift_file);
62 corrFileNameList.push_back(m_corr_ddsmearing_file);
63
64 for ( unsigned int i=0; i<corrFileNameList.size(); ++i ){
65
66 //First try the PathResolver
67 std::string filename = PathResolverFindCalibFile( corrFileNameList.at(i) );
68 if (filename.empty()){
69 ATH_MSG_ERROR ( "Could NOT resolve file name " << corrFileNameList.at(i) );
70 return StatusCode::FAILURE ;
71 } else{
72 ATH_MSG_INFO(" Path found = "<<filename);
73 }
74 corrFileNameList.at(i) = filename;
75 }
76 //
77
79
80 if (m_tool_ver_str == "REL22") tool_ver = CP::IsolationCorrection::REL22;
81 else if (m_tool_ver_str == "REL21") tool_ver = CP::IsolationCorrection::REL21;
82 else if (m_tool_ver_str == "REL20_2") tool_ver = CP::IsolationCorrection::REL20_2;
83 else if (m_tool_ver_str == "REL17_2") tool_ver = CP::IsolationCorrection::REL17_2;
84 else {
85 ATH_MSG_WARNING("Tool version not recognized: "<<m_tool_ver_str<<"\nAllowed versions: REL22, REL21, REL20_2, REL17_2");
86 return StatusCode::FAILURE;
87 }
88
89 if(TString(corrFileNameList[0]).Contains("isolation_ptcorrections_rel17_2.root") && m_tool_ver_str != "REL17_2"){
90 ATH_MSG_WARNING("The specified correction file is not for "<<m_tool_ver_str<<" please use proper correction file");
91 return StatusCode::FAILURE;
92 }
93
94 if (TString(corrFileNameList[0]).Contains("isolation_ptcorrections_rel20_2.root") && !( m_tool_ver_str == "REL20_2" || m_tool_ver_str == "REL21" ) ){
95 ATH_MSG_WARNING("The specified correction file is not for "<<m_tool_ver_str<<" please use proper correction file");
96 return StatusCode::FAILURE;
97 }
98 if (TString(corrFileNameList[0]).Contains("isolation_ptcorrections_rel22_") && m_tool_ver_str != "REL22" ){
99 ATH_MSG_WARNING("The specified correction file is not for "<<m_tool_ver_str<<" please use proper correction file");
100 return StatusCode::FAILURE;
101 }
102
104 m_isol_corr->SetToolVer(tool_ver);
105 m_isol_corr->SetTroubleCategories(m_trouble_categories);
106 m_isol_corr->FitType(m_useLogLogFit);
107 m_isol_corr->ForcePartType(m_forcePartType);
108
109 // Note that systematics in Rel 21 are NOT done with the DD-Corr ON/OFF method!
110 if (m_apply_ddDefault) {
111 if (m_ddVersion == "2015" || m_ddVersion == "2015_2016" || m_ddVersion == "2017") {
112 //if not REL21, register ourselves with the systematic registry!
113 if (m_tool_ver_str!="REL21") {
115 if( registry.registerSystematics( *this ) != StatusCode::SUCCESS ) return StatusCode::FAILURE;
116 }
117 m_apply_dd = true;
118 } else {
119 ATH_MSG_WARNING("Unknown data driven correction");
120 m_apply_dd = false;
121 }
122 } else{
123 m_apply_dd = false;
124 }
125
126 // Don't use DD Corrections for AFII if not rel21 (I do not know what was done in rel20.7 !)
127 if (m_tool_ver_str != "REL21" && m_AFII_corr) m_apply_dd = false;
128
129 m_isol_corr->SetAFII(m_AFII_corr);
130 m_isol_corr->SetDataMC(m_is_mc);
131
133 std::string filename = PathResolverFindCalibFile( m_corr_etaEDParPU_file );
134 if (filename.empty()){
135 ATH_MSG_ERROR ( "Could NOT resolve file name " << m_corr_etaEDParPU_file );
136 return StatusCode::FAILURE ;
137 }
138 ATH_MSG_INFO(" Path found = "<<filename);
139 std::unique_ptr<TFile> f(TFile::Open(filename.c_str(), "READ"));
140
141 m_map_isotype_zetaPU[xAOD::Iso::topoetcone20] = std::unique_ptr<TGraph>((TGraph*)f->Get("topoetcone20"));
142 m_map_isotype_zetaPU[xAOD::Iso::topoetcone30] = std::unique_ptr<TGraph>((TGraph*)f->Get("topoetcone30"));
143 m_map_isotype_zetaPU[xAOD::Iso::topoetcone40] = std::unique_ptr<TGraph>((TGraph*)f->Get("topoetcone40"));
144 f->Close();
145
148 if (filename.empty()){
149 ATH_MSG_ERROR ( "Could NOT resolve file name " << m_corr_etaEDPar_mc_corr_file );
150 return StatusCode::FAILURE ;
151 }
152 ATH_MSG_INFO(" Path found = "<<filename);
153 std::unique_ptr<TFile> f_corr(TFile::Open(filename.c_str(), "READ"));
154
155 m_map_isotype_zeta_mc_corr[xAOD::Iso::topoetcone20] = std::unique_ptr<TGraph>((TGraph*)f_corr->Get("topoetcone20"));
156 m_map_isotype_zeta_mc_corr[xAOD::Iso::topoetcone30] = std::unique_ptr<TGraph>((TGraph*)f_corr->Get("topoetcone30"));
157 m_map_isotype_zeta_mc_corr[xAOD::Iso::topoetcone40] = std::unique_ptr<TGraph>((TGraph*)f_corr->Get("topoetcone40"));
158 f_corr->Close();
159 }
160 }
161
162 return m_isol_corr->initialize();
163 }
164
165
166 // this will correct a corrected topoetcone : replace a (old) leakage by another (new) one
167 // This is not for photon, as it does not consider DD
169
170 static const std::vector<xAOD::Iso::IsolationType> topoisolation_types = {xAOD::Iso::topoetcone20,
172
173 for (auto type : topoisolation_types) {
174 float oldleak = 0.;
175 if (eg.isolationCaloCorrection(oldleak, type, xAOD::Iso::ptCorrection)) {
176 ATH_MSG_DEBUG("leakage correction not stored for isolation type " << xAOD::Iso::toCString(type) << ". Nothing done.");
177 continue;
178 }
179 float newleak = this->GetPtCorrection(eg,type);
180 float iso = 0;
181 if (!eg.isolationValue(iso,type)) {
182 ATH_MSG_WARNING("Isolation variable " << xAOD::Iso::toCString(type) << " not stored. Nothing done.");
183 continue;
184 }
185 iso += (oldleak-newleak);
186 bool setIso = eg.setIsolationValue(iso,type);
187 setIso = (setIso && eg.setIsolationCaloCorrection(newleak,type,xAOD::Iso::ptCorrection));
188 if (!setIso) {
189 ATH_MSG_WARNING("Can't correct leakage for " << xAOD::Iso::toCString(type));
191 }
192 }
193
194 if (m_correct_etcone){
195 // this is supposed to correct an uncorrected etcone
196 static const std::vector<xAOD::Iso::IsolationType> isolation_types = {xAOD::Iso::etcone20,
199
200 ATH_MSG_VERBOSE( "Correcting etconeXX isolation..." );
201 for(auto type : topoisolation_types){
202 float Etcone_value_corr = m_isol_corr->GetPtCorrectedIsolation(eg,type);
203 eg.setIsolationValue(Etcone_value_corr,type);
204 }
205 }
206
208 }
209
211
212 static const SG::AuxElement::Accessor<float> decDDcor20("topoetcone20_DDcorr");
213 static const SG::AuxElement::Accessor<float> decDDcor40("topoetcone40_DDcorr");
214 static const SG::AuxElement::Accessor<float> decEadded_Lr2("Eadded_Lr2");
215 static const SG::AuxElement::Accessor<float> decEadded_Lr3("Eadded_Lr3");
216
217
218 float SCsub = 0;
220 float topoetconecoreConeEnergyCorrection = 0;
221 if(!eg.isolationCaloCorrection(topoetconecoreConeEnergyCorrection, xAOD::Iso::topoetcone, xAOD::Iso::coreCone, xAOD::Iso::coreEnergy)){
222 ATH_MSG_WARNING("Could not find SC based core");
223 }
224 float core57cells = 0.;
226 ATH_MSG_WARNING("Could not find core57cells to apply SC based core correction");
227 }
228 ATH_MSG_VERBOSE("Old core correction value: " << core57cells);
229 ATH_MSG_VERBOSE("SC based core correction value: " << topoetconecoreConeEnergyCorrection);
230 SCsub = - topoetconecoreConeEnergyCorrection + core57cells;
231 }
232
233 float centralDensity = 0.;
234 float forwardDensity = 0.;
238 const xAOD::EventShape* evtShapeCentral = shapeCentral.ptr();
239 const xAOD::EventShape* evtShapeForward = shapeForward.ptr();
240 centralDensity = evtShapeCentral->getDensity(xAOD::EventShape::Density);
241 forwardDensity = evtShapeForward->getDensity(xAOD::EventShape::Density);
242 }
243
244 static const std::vector<xAOD::Iso::IsolationType> topoisolation_types = {xAOD::Iso::topoetcone20,
247 for (auto type : topoisolation_types) {
248 float oldleak = 0.;
249 if (!eg.isolationCaloCorrection(oldleak, type, xAOD::Iso::ptCorrection)) {
250 ATH_MSG_DEBUG("leakage correction not stored for isolation type " << xAOD::Iso::toCString(type) << ". Nothing done");
251 continue;
252 }
253 float oldiso = 0;
254 bool gotIso = eg.isolationValue(oldiso,type);
255 if (!gotIso) continue;
256
257 // Use the Random Run Number from the Event Info to check which year's DD-Corrections to use
258 // If the RandomRunNo can't be obtained, then default to what is set by either the default choice or by the AuxData check
259 unsigned int theRunNumber = 0 ;
261 const xAOD::EventInfo* eventInfo = evtInfo.ptr();
262 if (eventInfo) {
263 static const SG::AuxElement::Accessor<unsigned int> randomrunnumber("RandomRunNumber");
264 if (randomrunnumber.isAvailable(*eventInfo)){
265 theRunNumber = randomrunnumber(*(eventInfo)) ;
266 }
267 } else{
268 ATH_MSG_WARNING("Could not retrieve EventInfo object");
269 }
270 if (theRunNumber >= 320000)
271 m_ddVersion = "2017" ; // RunNo found, and is in 2017 range
272 else if (theRunNumber > 0)
273 m_ddVersion = "2015_2016" ; // RunNo found, but less than 2017 range
274 // otherwise, stick with default (m_ddVersion is already assigned)
275
276 // Don't use DD Corrections for AFII if not rel21 ? (I do not know what was done for rel20.7 !!!)
277 if (m_tool_ver_str != "REL21" && m_AFII_corr) m_apply_dd = false;
278
279 float iso = oldiso;
280 float newleak = 0.;
282 ATH_MSG_VERBOSE("Iso before SC correction: " << iso);
283 iso += (SCsub + oldleak);
284 ATH_MSG_VERBOSE("Iso after SC correction: " << iso);
285 }
286 else {
287 newleak = this->GetPtCorrection(eg,type);
288 iso += (oldleak - newleak);
289 }
290 float ddcorr = 0;
291
292 // this correction is derived purly from data, but can also be applied to mc
294 float abseta = fabs(eg.caloCluster()->etaBE(2));
295 float densityOldCorrection = 0.;
296 if(abseta <= 1.5){
297 densityOldCorrection = centralDensity;
298 }
299 else{
300 densityOldCorrection = forwardDensity;
301 }
302 float dR = xAOD::Iso::coneSize(type);
303 static const float a_core = 5*7*0.025*TMath::Pi()/128;
304 float area = TMath::Pi()*dR*dR-a_core;
305 float oldpu_corr = densityOldCorrection*area;
306 float newpu_corr = m_map_isotype_zetaPU[type]->Eval(abseta)*centralDensity*area;
307 float pu_mc_corr = 0.;
309 pu_mc_corr += m_map_isotype_zeta_mc_corr[type]->Eval(abseta)*centralDensity*area;
310 }
311 iso = iso + oldpu_corr - newpu_corr + pu_mc_corr;
312 ATH_MSG_VERBOSE("Applying parametrized pileup correction to " << eg.type() << " with |eta|="<< abseta);
313 ATH_MSG_VERBOSE("Old parametrized pileup correction for "<<xAOD::Iso::toCString(type)<< ": "<<oldpu_corr);
314 ATH_MSG_VERBOSE("New parametrized pileup correction for "<<xAOD::Iso::toCString(type)<< ": "<<newpu_corr);
315 ATH_MSG_VERBOSE("Parametrized mc correction for "<<xAOD::Iso::toCString(type)<< ": "<<pu_mc_corr);
316 ATH_MSG_VERBOSE("Isolation after new correction for "<<xAOD::Iso::toCString(type)<< ": "<<iso);
317 ATH_MSG_VERBOSE("Isolation after old correction for "<<xAOD::Iso::toCString(type)<< ": "<<iso+newpu_corr-oldpu_corr-pu_mc_corr);
318 eg.setIsolationCaloCorrection(newpu_corr, type, xAOD::Iso::pileupCorrection);
319 }
321 float coshEta = std::cosh(eg.caloCluster()->etaBE(2)) ;
322 float outTimeCore = (decEadded_Lr2(eg) + decEadded_Lr3(eg))/coshEta ;
323 iso += outTimeCore ;
324 }
326 ddcorr = this->GetDDCorrection(eg,type);
328 decDDcor20(eg) = ddcorr;
329 else if (type == xAOD::Iso::topoetcone40)
330 decDDcor40(eg) = ddcorr;
331 iso += ddcorr;
332 }
333 bool setIso = eg.setIsolationValue(iso,type);
334 setIso = (setIso && eg.setIsolationCaloCorrection(newleak-ddcorr,type,xAOD::Iso::ptCorrection));
335 ATH_MSG_VERBOSE("oldeak = " << oldleak << " ddcor = " << ddcorr << " leak param = " << newleak
336 << " stored correction " << eg.isolationCaloCorrection(type,xAOD::Iso::ptCorrection));
337
338 if (!setIso) {
339 ATH_MSG_WARNING("Can't correct leakage for " << xAOD::Iso::toCString(type));
341 }
342 }
344 }
345
347 return m_isol_corr->GetPtCorrectedIsolation(input, isol);
348 }
349
351 return m_isol_corr->GetPtCorrection(input, isol);
352 }
353
355 return m_isol_corr->GetDDCorrection(input, isol, m_ddVersion);
356 }
357
359 // A sanity check:
360 if( output ) ATH_MSG_WARNING( "Non-null pointer received. There's a possible memory leak!" );
361
362 if ( input.type() == xAOD::Type::Electron ) {
363 output = new xAOD::Electron();
364 output->makePrivateStore( static_cast<const xAOD::Electron&>(input) );
365 return applyCorrection( *output );
366 }
367 else if ( input.type() == xAOD::Type::Photon ) {
368 output = new xAOD::Photon();
369 output->makePrivateStore( static_cast<const xAOD::Photon&>(input) );
370 return applyCorrection( *output );
371 }
372 else {
373 ATH_MSG_WARNING("Didn't get an electron or photon");
375 }
376
377 }
378
379 //Systematics
382 return sys.find( systematic ) != sys.end();
383 }
384
389
393
395 return StatusCode::SUCCESS;
396 }
397
401
402}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
double area(double R)
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.
virtual float GetPtCorrectedIsolation(const xAOD::Egamma &, xAOD::Iso::IsolationType) override
virtual StatusCode initialize() override final
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
virtual bool isAffectedBySystematic(const CP::SystematicVariation &systematic) const override final
Declare the interface that this class provides.
std::map< xAOD::Iso::IsolationType, std::unique_ptr< TGraph > > m_map_isotype_zeta_mc_corr
virtual CP::CorrectionCode CorrectLeakage(xAOD::Egamma &) override final
virtual ASG_TOOL_CLASS3(IsolationCorrectionTool, IIsolationCorrectionTool, CP::ISystematicsTool, CP::IReentrantSystematicsTool) public ~IsolationCorrectionTool()
SG::ReadHandleKey< xAOD::EventShape > m_forwardEventShapeKey
virtual CP::SystematicSet affectingSystematics() const override final
the list of all systematics this tool can be affected by
virtual CP::CorrectionCode correctedCopy(const xAOD::Egamma &, xAOD::Egamma *&) override final
virtual float GetPtCorrection(const xAOD::Egamma &, xAOD::Iso::IsolationType) const override final
virtual CP::CorrectionCode applyCorrection(xAOD::Egamma &) override final
static const unsigned int m_Run2Run3runNumberTransition
SG::ReadHandleKey< xAOD::EventShape > m_centralEventShapeKey
virtual float GetDDCorrection(const xAOD::Egamma &, xAOD::Iso::IsolationType) override final
virtual CP::SystematicSet recommendedSystematics() const override final
the list of all systematics this tool recommends to use
std::map< xAOD::Iso::IsolationType, std::unique_ptr< TGraph > > m_map_isotype_zetaPU
virtual StatusCode applySystematicVariation(const CP::SystematicSet &systConfig) override final
effects: configure this tool for the given list of systematic variations.
This module implements the central registry for handling systematic uncertainties with CP tools.
static SystematicRegistry & getInstance()
Get the singleton instance of the registry for the curren thread.
StatusCode registerSystematics(const IReentrantSystematicsTool &tool)
effects: register all the systematics from the tool
Class to wrap a set of SystematicVariations.
SG::Accessor< T, ALLOC > Accessor
Definition AuxElement.h:572
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
const_pointer_type ptr()
Dereference the pointer.
uint32_t runNumber() const
The current event's run number.
bool getDensity(EventDensityID id, double &v) const
Get a density variable from the object.
Select isolated Photons, Electrons and Muons.
@ Photon
The object is a photon.
Definition ObjectType.h:47
@ Electron
The object is an electron.
Definition ObjectType.h:46
IsolationType
Overall enumeration for isolation types in xAOD files.
@ topoetcone20
Topo-cluster ET-sum.
@ etcone20
Calorimeter isolation.
@ topoetcone
Topo-cluster ET-sum.
static const char * toCString(IsolationConeSize conesize)
float coneSize(IsolationConeSize type)
convert Isolation Size into cone size
EventInfo_v1 EventInfo
Definition of the latest event info version.
Egamma_v1 Egamma
Definition of the current "egamma version".
Definition Egamma.h:17
Photon_v1 Photon
Definition of the current "egamma version".
EventShape_v1 EventShape
Definition of the current event format version.
Definition EventShape.h:16
Electron_v1 Electron
Definition of the current "egamma version".
MsgStream & msg
Definition testRead.cxx:32