ATLAS Offline Software
Loading...
Searching...
No Matches
Photons.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// This source file implements all of the functions related to Photons
6// in the SUSYObjDef_xAOD class
7
8// Local include(s):
10
13
20
23
24// Helper for object quality
26
27#ifndef XAOD_STANDALONE // For now metadata is Athena-only
29#endif
30
31namespace ST {
32
33StatusCode SUSYObjDef_xAOD::GetPhotons(xAOD::PhotonContainer*& copy, xAOD::ShallowAuxContainer*& copyaux, bool recordSG, const std::string& photonkey, const xAOD::PhotonContainer* containerToBeCopied)
34{
35 if (!m_tool_init) {
36 ATH_MSG_ERROR("SUSYTools was not initialized!!");
37 return StatusCode::FAILURE;
38 }
39
40 if (m_isPHYSLITE && photonkey.find("AnalysisPhotons")==std::string::npos){
41 ATH_MSG_ERROR("You are running on PHYSLITE derivation. Please change the Photons container to 'AnalysisPhotons'");
42 return StatusCode::FAILURE;
43 }
44
45 const xAOD::PhotonContainer* photons = nullptr;
46 if (copy==nullptr) { // empty container provided
47 if (containerToBeCopied != nullptr) {
48 photons = containerToBeCopied;
49 }
50 else {
51 ATH_CHECK( evtStore()->retrieve(photons, photonkey) );
52 }
54 copy = shallowcopy.first.get();
55 copyaux = shallowcopy.second.get();
56 bool setLinks = xAOD::setOriginalObjectLink(*photons, *copy);
57 if (!setLinks) {
58 ATH_MSG_WARNING("Failed to set original object links on " << photonkey);
59 }
60 if (recordSG) {
61 ATH_CHECK( evtStore()->record(std::move(shallowcopy.first), "STCalib" + photonkey + m_currentSyst.name()) );
62 ATH_CHECK( evtStore()->record(std::move(shallowcopy.second), "STCalib" + photonkey + m_currentSyst.name() + "Aux.") );
63 } else {
64 ATH_MSG_ERROR("Shallow copy not recorded in StoreGate!");
65 return StatusCode::FAILURE;
66 }
67 } else { // use the user-supplied collection instead
68 ATH_MSG_DEBUG("Not retrieving photon collecton, using existing one provided by user");
69 photons=copy;
70 }
71
72 for (const auto photon : *copy) {
75 }
76
77 return StatusCode::SUCCESS;
78}
79
80
81StatusCode SUSYObjDef_xAOD::FillPhoton(xAOD::Photon& input, float ptcut, float etacut) {
82
83 ATH_MSG_VERBOSE( "Starting FillPhoton on ph with pre-calibration pt=" << input.pt() );
84
85 if ( !input.caloCluster() ) {
86 ATH_MSG_WARNING( "FillPhoton: no caloCluster found: " << input.caloCluster() );
87 return StatusCode::SUCCESS;
88 }
89
90 //Check DeadHVCellRemoval
91 bool pass_deadHVTool = m_deadHVTool->accept(&input);
92
93 if (m_debug) {
94 ATH_MSG_INFO( "PHOTON eta: " << input.eta() );
95 ATH_MSG_INFO( "PHOTON phi: " << input.phi() );
96 ATH_MSG_INFO( "PHOTON cl eta: " << input.caloCluster()->eta() );
97 ATH_MSG_INFO( "PHOTON cl phi: " << input.caloCluster()->phi() );
98 ATH_MSG_INFO( "PHOTON cl e: " << input.caloCluster()->e() );
99 ATH_MSG_INFO( "PHOTON OQ: " << input.OQ() );
100 ATH_MSG_INFO( "PHOTON author: " << input.author() );
101 ATH_MSG_INFO( "PHOTON deadHVTools: " << pass_deadHVTool );
102 }
103
104 dec_baseline(input) = false;
105 dec_selected(input) = 0;
106 dec_isol(input) = false;
107 dec_isEM(input) = 0;
108
109 if (!pass_deadHVTool) return StatusCode::SUCCESS;
110
111 // Author cuts needed according to https://twiki.cern.ch/twiki/bin/view/AtlasProtected/EGammaIdentificationRun2#Photon_authors
113 return StatusCode::SUCCESS;
114
115 // calibrate the photon 4-vector here only if within eta window
116 if (std::abs(input.caloCluster()->etaBE(2)) >= etacut) return StatusCode::SUCCESS;
117
119 if ( std::abs( input.caloCluster()->etaBE(2) ) >1.37 && std::abs( input.caloCluster()->etaBE(2) ) <1.52) {
120 return StatusCode::SUCCESS;
121 }
122 }
123
124 if (m_egammaCalibTool->applyCorrection(input) != CP::CorrectionCode::Ok)
125 ATH_MSG_ERROR("FillPhoton: EgammaCalibTool applyCorrection failed");
126
127 if (m_isoCorrTool->applyCorrection(input) != CP::CorrectionCode::Ok)
128 ATH_MSG_ERROR("FillPhoton: IsolationCorrectionTool applyCorrection failed");
129
130 ATH_MSG_VERBOSE( "FillPhoton: post-calibration pt=" << input.pt() );
131
132 if (input.pt() < ptcut) return StatusCode::SUCCESS;
133
134 //Object quality cut as described at https://twiki.cern.ch/twiki/bin/view/AtlasProtected/EGammaIdentificationRun2#Object_quality_cut
135 if (!input.isGoodOQ(xAOD::EgammaParameters::BADCLUSPHOTON))
136 return StatusCode::SUCCESS;
137
138 //Photon quality as in https://twiki.cern.ch/twiki/bin/view/AtlasProtected/EGammaIdentificationRun2#Photon_cleaning
139 bool passPhCleaning = false;
140 if (acc_passPhCleaning.isAvailable(input) && acc_passPhCleaningNoTime.isAvailable(input)) {
141 if ( (!m_photonAllowLate && acc_passPhCleaning(input)) || (m_photonAllowLate && acc_passPhCleaningNoTime(input)) ) passPhCleaning = true;
142 } else {
143 ATH_MSG_VERBOSE ("DFCommonPhotonsCleaning is not found in DAOD..");
145 ( m_photonAllowLate && PhotonHelpers::passOQqualityDelayed(input)) ) passPhCleaning = true;
146 }
147 if (!passPhCleaning) return StatusCode::SUCCESS;
148
149
150 bool passBaseID = false;
151 if (m_acc_photonIdBaseline.isAvailable(input)) {
152 passBaseID = bool(m_acc_photonIdBaseline(input));
153 } else {
154 passBaseID = bool(m_photonSelIsEMBaseline->accept(&input));
155 }
156 if (!passBaseID) return StatusCode::SUCCESS;
157
158 //--- Do baseline isolation check
159 if ( !( m_photonBaselineIso_WP.empty() ) && !( m_isoBaselineTool->accept(input) ) ) return StatusCode::SUCCESS;
160
161 dec_baseline(input) = true;
162 dec_selected(input) = 2;
163 if (!m_photonIso_WP.empty()) dec_isol(input) = bool(m_isoTool->accept(input));
164
165 ATH_MSG_VERBOSE("FillPhoton: passed baseline selection.");
166 return StatusCode::SUCCESS;
167}
168
169
170bool SUSYObjDef_xAOD::IsSignalPhoton(const xAOD::Photon& input, float ptcut, float etacut) const
171{
172 dec_signal(input) = false;
173
174 if ( !acc_baseline(input) ) return false;
175
176 if ( !m_egammaAmbiguityTool->accept(input) ) return false;
177
178 if ( input.pt() < ptcut ) return false;
179 if ( etacut==DUMMYDEF ){
180 if(std::abs(input.caloCluster()->etaBE(2)) > m_photonEta ) return false;
181 }
182 else if ( std::abs(input.caloCluster()->etaBE(2)) > etacut ) return false;
183
185 if ( std::abs( input.caloCluster()->etaBE(2) ) >1.37 && std::abs( input.caloCluster()->etaBE(2) ) <1.52) {
186 return false;
187 }
188 }
189
190 if (acc_isol(input) || !m_doPhIsoSignal) {
191 ATH_MSG_VERBOSE( "IsSignalPhoton: passed isolation");
192 } else return false;
193
194 bool passID = false;
195 if (m_acc_photonId.isAvailable(input)) {
196 passID = m_acc_photonId(input);
197 } else {
198 ATH_MSG_VERBOSE ("DFCommonPhotonsIsEMxxx variables are not found. Calculating the ID from Photon ID tool..");
199 passID = bool(m_photonSelIsEM->accept(&input));
200 }
201 if ( !passID ) return false;
202
203 dec_signal(input) = true;
204
205 return true;
206}
207
208
209double SUSYObjDef_xAOD::GetSignalPhotonSF(const xAOD::Photon& ph, const bool effSF, const bool isoSF, const bool triggerSF) const
210{
211 double sf(1.);
212
213 if (effSF) {
214
215 double sf_eff = 1.;
216
217 CP::CorrectionCode res = m_photonEfficiencySFTool->getEfficiencyScaleFactor( ph, sf_eff );
218 if (res == CP::CorrectionCode::OutOfValidityRange) ATH_MSG_WARNING(" GetSignalPhotonSF: EfficiencyScaleFactor out of validity range");
219
220 sf *= sf_eff;
221 }
222
223 if (isoSF) {
224
225 double sf_iso = 1.;
226
227 CP::CorrectionCode res = m_photonIsolationSFTool->getEfficiencyScaleFactor( ph, sf_iso );
228 if (res == CP::CorrectionCode::OutOfValidityRange) ATH_MSG_WARNING(" GetSignalPhotonSF: IsolationScaleFactor out of validity range");
229
230 sf *= sf_iso;
231 }
232
233 if (triggerSF) {
234
235 double sf_trigger = 1.;
236
237 CP::CorrectionCode res = m_photonTriggerSFTool->getEfficiencyScaleFactor( ph, sf_trigger );
238 if (res == CP::CorrectionCode::OutOfValidityRange) ATH_MSG_WARNING(" GetSignalPhotonSF: TriggerScaleFactor out of validity range");
239
240 sf *= sf_trigger;
241 }
242
243 ATH_MSG_VERBOSE( "ScaleFactor " << sf );
244
245 dec_effscalefact(ph) = sf;
246 return sf;
247}
248
249
250double SUSYObjDef_xAOD::GetSignalPhotonSFsys(const xAOD::Photon& ph, const CP::SystematicSet& systConfig, const bool effSF, const bool isoSF, const bool triggerSF)
251{
252 double sf(1.);
253
254 //Set the new systematic variation
255 StatusCode ret = m_photonEfficiencySFTool->applySystematicVariation(systConfig);
256 if (ret != StatusCode::SUCCESS) {
257 ATH_MSG_ERROR("Cannot configure AsgPhotonEfficiencyCorrectionTool (reco) for systematic var. " << systConfig.name() );
258 }
259
260 ret = m_photonIsolationSFTool->applySystematicVariation(systConfig);
261 if (ret != StatusCode::SUCCESS) {
262 ATH_MSG_ERROR("Cannot configure AsgPhotonEfficiencyCorrectionTool (iso) for systematic var. " << systConfig.name() );
263 }
264
265 ret = m_photonTriggerSFTool->applySystematicVariation(systConfig);
266 if (ret != StatusCode::SUCCESS) {
267 ATH_MSG_ERROR("Cannot configure AsgPhotonEfficiencyCorrectionTool (trigger) for systematic var. " << systConfig.name() );
268 }
269
270 if (effSF) {
271
272 double sf_eff = 1.;
273
274 CP::CorrectionCode res = m_photonEfficiencySFTool->getEfficiencyScaleFactor( ph, sf_eff );
275 if (res == CP::CorrectionCode::OutOfValidityRange) ATH_MSG_WARNING(" GetSignalPhotonSF: getEfficiencyScaleFactor out of validity range");
276
277 sf *= sf_eff;
278 }
279
280 if (isoSF) {
281
282 double sf_iso = 1.;
283
284 CP::CorrectionCode res = m_photonIsolationSFTool->getEfficiencyScaleFactor( ph, sf_iso );
285 if (res == CP::CorrectionCode::OutOfValidityRange) ATH_MSG_WARNING(" GetSignalPhotonSF: getEfficiencyScaleFactor out of validity range");
286
287 sf *= sf_iso;
288 }
289
290 if (triggerSF) {
291
292 double sf_trigger = 1.;
293
294 CP::CorrectionCode res = m_photonTriggerSFTool->getEfficiencyScaleFactor( ph, sf_trigger );
295 if (res == CP::CorrectionCode::OutOfValidityRange) ATH_MSG_WARNING(" GetSignalPhotonSF: getEfficiencyScaleFactor out of validity range");
296
297 sf *= sf_trigger;
298 }
299
300 //Roll back to current sys
301 ret = m_photonEfficiencySFTool->applySystematicVariation(m_currentSyst);
302 if (ret != StatusCode::SUCCESS) {
303 ATH_MSG_ERROR("Cannot configure AsgPhotonEfficiencyCorrectionTool back to default.");
304 }
305
306 ret = m_photonIsolationSFTool->applySystematicVariation(m_currentSyst);
307 if (ret != StatusCode::SUCCESS) {
308 ATH_MSG_ERROR("Cannot configure AsgPhotonEfficiencyCorrectionTool (iso) for systematic var. " << systConfig.name() );
309 }
310
311 ret = m_photonTriggerSFTool->applySystematicVariation(m_currentSyst);
312 if (ret != StatusCode::SUCCESS) {
313 ATH_MSG_ERROR("Cannot configure AsgPhotonEfficiencyCorrectionTool (trigger) for systematic var. " << systConfig.name() );
314 }
315
316 ATH_MSG_VERBOSE( "ScaleFactor " << sf );
317
318 dec_effscalefact(ph) = sf;
319 return sf;
320}
321
322
323double SUSYObjDef_xAOD::GetTotalPhotonSF(const xAOD::PhotonContainer& photons, const bool effSF, const bool isoSF, const bool triggerSF) const
324{
325 double sf(1.);
326
327 for (const xAOD::Photon* photon : photons) {
328 if (acc_signal(*photon) && acc_passOR(*photon)) { sf *= this->GetSignalPhotonSF(*photon, effSF, isoSF, triggerSF); }
329 }
330
331 return sf;
332}
333
334
335double SUSYObjDef_xAOD::GetTotalPhotonSFsys(const xAOD::PhotonContainer& photons, const CP::SystematicSet& systConfig, const bool effSF, const bool isoSF, const bool triggerSF)
336{
337 double sf(1.);
338
339 for (const xAOD::Photon* photon : photons) {
340 if (acc_signal(*photon) && acc_passOR(*photon)) { sf *= this->GetSignalPhotonSFsys(*photon, systConfig, effSF, isoSF, triggerSF); }
341 }
342
343 return sf;
344}
345
346}
#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)
std::pair< std::vector< unsigned int >, bool > res
ServiceHandle< StoreGateSvc > & evtStore()
Return value from object correction CP tools.
@ 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.
asg::AnaToolHandle< CP::IIsolationSelectionTool > m_isoBaselineTool
asg::AnaToolHandle< IAsgPhotonIsEMSelector > m_photonSelIsEM
SG::ConstAccessor< char > m_acc_photonId
asg::AnaToolHandle< CP::IIsolationSelectionTool > m_isoTool
std::string m_photonBaselineIso_WP
StatusCode GetPhotons(xAOD::PhotonContainer *&copy, xAOD::ShallowAuxContainer *&copyaux, const bool recordSG=true, const std::string &photonkey="Photons", const xAOD::PhotonContainer *containerToBeCopied=nullptr) override final
Definition Photons.cxx:33
SG::ConstAccessor< char > m_acc_photonIdBaseline
asg::AnaToolHandle< IAsgDeadHVCellRemovalTool > m_deadHVTool
double GetSignalPhotonSF(const xAOD::Photon &ph, const bool effSF=true, const bool isoSF=true, const bool triggerSF=false) const override final
Definition Photons.cxx:209
CP::SystematicSet m_currentSyst
asg::AnaToolHandle< IEGammaAmbiguityTool > m_egammaAmbiguityTool
asg::AnaToolHandle< IAsgPhotonEfficiencyCorrectionTool > m_photonIsolationSFTool
double GetTotalPhotonSFsys(const xAOD::PhotonContainer &photons, const CP::SystematicSet &systConfig, const bool effSF=true, const bool isoSF=true, const bool triggerSF=false) override final
Definition Photons.cxx:335
asg::AnaToolHandle< CP::IIsolationCorrectionTool > m_isoCorrTool
StatusCode FillPhoton(xAOD::Photon &input, const float ptcut, const float etacut) override final
Definition Photons.cxx:81
bool IsSignalPhoton(const xAOD::Photon &input, const float ptcut, const float etacut=DUMMYDEF) const override final
Definition Photons.cxx:170
asg::AnaToolHandle< IAsgPhotonIsEMSelector > m_photonSelIsEMBaseline
double GetTotalPhotonSF(const xAOD::PhotonContainer &photons, const bool effSF=true, const bool isoSF=true, const bool triggerSF=false) const override final
Definition Photons.cxx:323
asg::AnaToolHandle< IAsgPhotonEfficiencyCorrectionTool > m_photonTriggerSFTool
double GetSignalPhotonSFsys(const xAOD::Photon &ph, const CP::SystematicSet &systConfig, const bool effSF=true, const bool isoSF=true, const bool triggerSF=false) override final
Definition Photons.cxx:250
asg::AnaToolHandle< CP::IEgammaCalibrationAndSmearingTool > m_egammaCalibTool
Combined electron collection.
asg::AnaToolHandle< IAsgPhotonEfficiencyCorrectionTool > m_photonEfficiencySFTool
Class creating a shallow copy of an existing auxiliary container.
bool passOQqualityDelayed(const xAOD::Photon &ph)
Helpers to ease the implementation of the pass Quality requirements.
bool passOQquality(const xAOD::Photon &ph)
Helper to ease the implemmantation of the pass Quality requirements.
static const SG::Decorator< double > dec_effscalefact("effscalefact")
static const SG::Decorator< char > dec_baseline("baseline")
static const SG::ConstAccessor< char > acc_passPhCleaning("DFCommonPhotonsCleaning")
static const SG::Decorator< unsigned > dec_isEM("isEM")
static const SG::ConstAccessor< char > acc_passPhCleaningNoTime("DFCommonPhotonsCleaningNoTime")
static const SG::ConstAccessor< char > acc_signal("signal")
static const SG::ConstAccessor< char > acc_baseline("baseline")
static const double DUMMYDEF
static const SG::ConstAccessor< char > acc_passOR("passOR")
static const SG::ConstAccessor< char > acc_isol("isol")
static const SG::Decorator< char > dec_isol("isol")
static const SG::Decorator< char > dec_signal("signal")
static const SG::Decorator< char > dec_selected("selected")
const uint16_t AuthorPhoton
Object Reconstructed by standard cluster-based algorithm.
Definition EgammaDefs.h:28
const uint32_t BADCLUSPHOTON
Definition EgammaDefs.h:124
const uint16_t AuthorAmbiguous
Object Reconstructed by standard cluster-based algorithm.
Definition EgammaDefs.h:32
typename ShallowCopyResult< T >::type ShallowCopyResult_t
Return type of xAOD::shallowCopy.
Definition ShallowCopy.h:68
PhotonContainer_v1 PhotonContainer
Definition of the current "photon container version".
ShallowCopyResult_t< T > shallowCopy(const T &cont, const EventContext &ctx)
Create a shallow copy of an existing container.
bool setOriginalObjectLink(const IParticle &original, IParticle &copy)
This function should be used by CP tools when they make a deep copy of an object in their correctedCo...
Photon_v1 Photon
Definition of the current "egamma version".
setBGCode setTAP setLVL2ErrorBits bool