ATLAS Offline Software
Loading...
Searching...
No Matches
Photons.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 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 }
53 std::pair<xAOD::PhotonContainer*, xAOD::ShallowAuxContainer*> shallowcopy = xAOD::shallowCopyContainer(*photons);
54 copy = shallowcopy.first;
55 copyaux = shallowcopy.second;
56 bool setLinks = xAOD::setOriginalObjectLink(*photons, *copy);
57 if (!setLinks) {
58 ATH_MSG_WARNING("Failed to set original object links on " << photonkey);
59 }
60 } else { // use the user-supplied collection instead
61 ATH_MSG_DEBUG("Not retrieving photon collecton, using existing one provided by user");
62 photons=copy;
63 }
64
65 for (const auto photon : *copy) {
68 }
69
70 if (recordSG) {
71 ATH_CHECK( evtStore()->record(copy, "STCalib" + photonkey + m_currentSyst.name()) );
72 ATH_CHECK( evtStore()->record(copyaux, "STCalib" + photonkey + m_currentSyst.name() + "Aux.") );
73 }
74 return StatusCode::SUCCESS;
75}
76
77
78StatusCode SUSYObjDef_xAOD::FillPhoton(xAOD::Photon& input, float ptcut, float etacut) {
79
80 ATH_MSG_VERBOSE( "Starting FillPhoton on ph with pre-calibration pt=" << input.pt() );
81
82 if ( !input.caloCluster() ) {
83 ATH_MSG_WARNING( "FillPhoton: no caloCluster found: " << input.caloCluster() );
84 return StatusCode::SUCCESS;
85 }
86
87 //Check DeadHVCellRemoval
88 bool pass_deadHVTool = m_deadHVTool->accept(&input);
89
90 if (m_debug) {
91 ATH_MSG_INFO( "PHOTON eta: " << input.eta() );
92 ATH_MSG_INFO( "PHOTON phi: " << input.phi() );
93 ATH_MSG_INFO( "PHOTON cl eta: " << input.caloCluster()->eta() );
94 ATH_MSG_INFO( "PHOTON cl phi: " << input.caloCluster()->phi() );
95 ATH_MSG_INFO( "PHOTON cl e: " << input.caloCluster()->e() );
96 ATH_MSG_INFO( "PHOTON OQ: " << input.OQ() );
97 ATH_MSG_INFO( "PHOTON author: " << input.author() );
98 ATH_MSG_INFO( "PHOTON deadHVTools: " << pass_deadHVTool );
99 }
100
101 dec_baseline(input) = false;
102 dec_selected(input) = 0;
103 dec_isol(input) = false;
104 dec_isEM(input) = 0;
105
106 if (!pass_deadHVTool) return StatusCode::SUCCESS;
107
108 // Author cuts needed according to https://twiki.cern.ch/twiki/bin/view/AtlasProtected/EGammaIdentificationRun2#Photon_authors
110 return StatusCode::SUCCESS;
111
112 // calibrate the photon 4-vector here only if within eta window
113 if (std::abs(input.caloCluster()->etaBE(2)) >= etacut) return StatusCode::SUCCESS;
114
116 if ( std::abs( input.caloCluster()->etaBE(2) ) >1.37 && std::abs( input.caloCluster()->etaBE(2) ) <1.52) {
117 return StatusCode::SUCCESS;
118 }
119 }
120
121 if (m_egammaCalibTool->applyCorrection(input) != CP::CorrectionCode::Ok)
122 ATH_MSG_ERROR("FillPhoton: EgammaCalibTool applyCorrection failed");
123
124 if (m_isoCorrTool->applyCorrection(input) != CP::CorrectionCode::Ok)
125 ATH_MSG_ERROR("FillPhoton: IsolationCorrectionTool applyCorrection failed");
126
127 ATH_MSG_VERBOSE( "FillPhoton: post-calibration pt=" << input.pt() );
128
129 if (input.pt() < ptcut) return StatusCode::SUCCESS;
130
131 //Object quality cut as described at https://twiki.cern.ch/twiki/bin/view/AtlasProtected/EGammaIdentificationRun2#Object_quality_cut
132 if (!input.isGoodOQ(xAOD::EgammaParameters::BADCLUSPHOTON))
133 return StatusCode::SUCCESS;
134
135 //Photon quality as in https://twiki.cern.ch/twiki/bin/view/AtlasProtected/EGammaIdentificationRun2#Photon_cleaning
136 bool passPhCleaning = false;
137 if (acc_passPhCleaning.isAvailable(input) && acc_passPhCleaningNoTime.isAvailable(input)) {
138 if ( (!m_photonAllowLate && acc_passPhCleaning(input)) || (m_photonAllowLate && acc_passPhCleaningNoTime(input)) ) passPhCleaning = true;
139 } else {
140 ATH_MSG_VERBOSE ("DFCommonPhotonsCleaning is not found in DAOD..");
142 ( m_photonAllowLate && PhotonHelpers::passOQqualityDelayed(input)) ) passPhCleaning = true;
143 }
144 if (!passPhCleaning) return StatusCode::SUCCESS;
145
146
147 bool passBaseID = false;
148 if (m_acc_photonIdBaseline.isAvailable(input)) {
149 passBaseID = bool(m_acc_photonIdBaseline(input));
150 } else {
151 passBaseID = bool(m_photonSelIsEMBaseline->accept(&input));
152 }
153 if (!passBaseID) return StatusCode::SUCCESS;
154
155 //--- Do baseline isolation check
156 if ( !( m_photonBaselineIso_WP.empty() ) && !( m_isoBaselineTool->accept(input) ) ) return StatusCode::SUCCESS;
157
158 dec_baseline(input) = true;
159 dec_selected(input) = 2;
160 if (!m_photonIso_WP.empty()) dec_isol(input) = bool(m_isoTool->accept(input));
161
162 ATH_MSG_VERBOSE("FillPhoton: passed baseline selection.");
163 return StatusCode::SUCCESS;
164}
165
166
167bool SUSYObjDef_xAOD::IsSignalPhoton(const xAOD::Photon& input, float ptcut, float etacut) const
168{
169 dec_signal(input) = false;
170
171 if ( !acc_baseline(input) ) return false;
172
173 if ( !m_egammaAmbiguityTool->accept(input) ) return false;
174
175 if ( input.pt() < ptcut ) return false;
176 if ( etacut==DUMMYDEF ){
177 if(std::abs(input.caloCluster()->etaBE(2)) > m_photonEta ) return false;
178 }
179 else if ( std::abs(input.caloCluster()->etaBE(2)) > etacut ) return false;
180
182 if ( std::abs( input.caloCluster()->etaBE(2) ) >1.37 && std::abs( input.caloCluster()->etaBE(2) ) <1.52) {
183 return false;
184 }
185 }
186
187 if (acc_isol(input) || !m_doPhIsoSignal) {
188 ATH_MSG_VERBOSE( "IsSignalPhoton: passed isolation");
189 } else return false;
190
191 bool passID = false;
192 if (m_acc_photonId.isAvailable(input)) {
193 passID = m_acc_photonId(input);
194 } else {
195 ATH_MSG_VERBOSE ("DFCommonPhotonsIsEMxxx variables are not found. Calculating the ID from Photon ID tool..");
196 passID = bool(m_photonSelIsEM->accept(&input));
197 }
198 if ( !passID ) return false;
199
200 dec_signal(input) = true;
201
202 return true;
203}
204
205
206double SUSYObjDef_xAOD::GetSignalPhotonSF(const xAOD::Photon& ph, const bool effSF, const bool isoSF, const bool triggerSF) const
207{
208 double sf(1.);
209
210 if (effSF) {
211
212 double sf_eff = 1.;
213
214 CP::CorrectionCode res = m_photonEfficiencySFTool->getEfficiencyScaleFactor( ph, sf_eff );
215 if (res == CP::CorrectionCode::OutOfValidityRange) ATH_MSG_WARNING(" GetSignalPhotonSF: EfficiencyScaleFactor out of validity range");
216
217 sf *= sf_eff;
218 }
219
220 if (isoSF) {
221
222 double sf_iso = 1.;
223
224 CP::CorrectionCode res = m_photonIsolationSFTool->getEfficiencyScaleFactor( ph, sf_iso );
225 if (res == CP::CorrectionCode::OutOfValidityRange) ATH_MSG_WARNING(" GetSignalPhotonSF: IsolationScaleFactor out of validity range");
226
227 sf *= sf_iso;
228 }
229
230 if (triggerSF) {
231
232 double sf_trigger = 1.;
233
234 CP::CorrectionCode res = m_photonTriggerSFTool->getEfficiencyScaleFactor( ph, sf_trigger );
235 if (res == CP::CorrectionCode::OutOfValidityRange) ATH_MSG_WARNING(" GetSignalPhotonSF: TriggerScaleFactor out of validity range");
236
237 sf *= sf_trigger;
238 }
239
240 ATH_MSG_VERBOSE( "ScaleFactor " << sf );
241
242 dec_effscalefact(ph) = sf;
243 return sf;
244}
245
246
247double SUSYObjDef_xAOD::GetSignalPhotonSFsys(const xAOD::Photon& ph, const CP::SystematicSet& systConfig, const bool effSF, const bool isoSF, const bool triggerSF)
248{
249 double sf(1.);
250
251 //Set the new systematic variation
252 StatusCode ret = m_photonEfficiencySFTool->applySystematicVariation(systConfig);
253 if (ret != StatusCode::SUCCESS) {
254 ATH_MSG_ERROR("Cannot configure AsgPhotonEfficiencyCorrectionTool (reco) for systematic var. " << systConfig.name() );
255 }
256
257 ret = m_photonIsolationSFTool->applySystematicVariation(systConfig);
258 if (ret != StatusCode::SUCCESS) {
259 ATH_MSG_ERROR("Cannot configure AsgPhotonEfficiencyCorrectionTool (iso) for systematic var. " << systConfig.name() );
260 }
261
262 ret = m_photonTriggerSFTool->applySystematicVariation(systConfig);
263 if (ret != StatusCode::SUCCESS) {
264 ATH_MSG_ERROR("Cannot configure AsgPhotonEfficiencyCorrectionTool (trigger) for systematic var. " << systConfig.name() );
265 }
266
267 if (effSF) {
268
269 double sf_eff = 1.;
270
271 CP::CorrectionCode res = m_photonEfficiencySFTool->getEfficiencyScaleFactor( ph, sf_eff );
272 if (res == CP::CorrectionCode::OutOfValidityRange) ATH_MSG_WARNING(" GetSignalPhotonSF: getEfficiencyScaleFactor out of validity range");
273
274 sf *= sf_eff;
275 }
276
277 if (isoSF) {
278
279 double sf_iso = 1.;
280
281 CP::CorrectionCode res = m_photonIsolationSFTool->getEfficiencyScaleFactor( ph, sf_iso );
282 if (res == CP::CorrectionCode::OutOfValidityRange) ATH_MSG_WARNING(" GetSignalPhotonSF: getEfficiencyScaleFactor out of validity range");
283
284 sf *= sf_iso;
285 }
286
287 if (triggerSF) {
288
289 double sf_trigger = 1.;
290
291 CP::CorrectionCode res = m_photonTriggerSFTool->getEfficiencyScaleFactor( ph, sf_trigger );
292 if (res == CP::CorrectionCode::OutOfValidityRange) ATH_MSG_WARNING(" GetSignalPhotonSF: getEfficiencyScaleFactor out of validity range");
293
294 sf *= sf_trigger;
295 }
296
297 //Roll back to current sys
298 ret = m_photonEfficiencySFTool->applySystematicVariation(m_currentSyst);
299 if (ret != StatusCode::SUCCESS) {
300 ATH_MSG_ERROR("Cannot configure AsgPhotonEfficiencyCorrectionTool back to default.");
301 }
302
303 ret = m_photonIsolationSFTool->applySystematicVariation(m_currentSyst);
304 if (ret != StatusCode::SUCCESS) {
305 ATH_MSG_ERROR("Cannot configure AsgPhotonEfficiencyCorrectionTool (iso) for systematic var. " << systConfig.name() );
306 }
307
308 ret = m_photonTriggerSFTool->applySystematicVariation(m_currentSyst);
309 if (ret != StatusCode::SUCCESS) {
310 ATH_MSG_ERROR("Cannot configure AsgPhotonEfficiencyCorrectionTool (trigger) for systematic var. " << systConfig.name() );
311 }
312
313 ATH_MSG_VERBOSE( "ScaleFactor " << sf );
314
315 dec_effscalefact(ph) = sf;
316 return sf;
317}
318
319
320double SUSYObjDef_xAOD::GetTotalPhotonSF(const xAOD::PhotonContainer& photons, const bool effSF, const bool isoSF, const bool triggerSF) const
321{
322 double sf(1.);
323
324 for (const xAOD::Photon* photon : photons) {
325 if (acc_signal(*photon) && acc_passOR(*photon)) { sf *= this->GetSignalPhotonSF(*photon, effSF, isoSF, triggerSF); }
326 }
327
328 return sf;
329}
330
331
332double SUSYObjDef_xAOD::GetTotalPhotonSFsys(const xAOD::PhotonContainer& photons, const CP::SystematicSet& systConfig, const bool effSF, const bool isoSF, const bool triggerSF)
333{
334 double sf(1.);
335
336 for (const xAOD::Photon* photon : photons) {
337 if (acc_signal(*photon) && acc_passOR(*photon)) { sf *= this->GetSignalPhotonSFsys(*photon, systConfig, effSF, isoSF, triggerSF); }
338 }
339
340 return sf;
341}
342
343}
#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:206
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:332
asg::AnaToolHandle< CP::IIsolationCorrectionTool > m_isoCorrTool
StatusCode FillPhoton(xAOD::Photon &input, const float ptcut, const float etacut) override final
Definition Photons.cxx:78
bool IsSignalPhoton(const xAOD::Photon &input, const float ptcut, const float etacut=DUMMYDEF) const override final
Definition Photons.cxx:167
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:320
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:247
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
PhotonContainer_v1 PhotonContainer
Definition of the current "photon container version".
std::pair< std::unique_ptr< T >, std::unique_ptr< ShallowAuxContainer > > shallowCopyContainer(const T &cont, const EventContext &ctx)
Function making a shallow copy of a constant 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