ATLAS Offline Software
Loading...
Searching...
No Matches
EgammaCalibrationAndSmearingTool.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5#ifndef EGAMMA_CALIB_TOOL_H_
6#define EGAMMA_CALIB_TOOL_H_
7
8#include <array>
9#include <functional>
10#include <map>
11#include <memory>
12#include <string>
13
17#include "AsgTools/AsgTool.h"
36#include "xAODEgamma/Egamma.h"
37#include "xAODEgamma/Electron.h"
38#include "xAODEgamma/Photon.h"
40
41// Forward declarations
43namespace egGain {
44class GainTool;
45class GainUncertainty;
46} // namespace egGain
47class LinearityADC;
48class TH2;
49
50namespace xAOD {
51inline float get_phi_calo(const xAOD::CaloCluster& cluster, int author,
52 bool do_throw = false) {
53 static const SG::ConstAccessor<float> phiCaloAcc("phiCalo");
54 double phi_calo;
56 phi_calo = cluster.phi();
58 phi_calo)) {
59 } else if (phiCaloAcc.isAvailable(cluster)) {
60 phi_calo = phiCaloAcc(cluster);
61 } else {
62 asg::AsgMessaging msg("get_phi_calo");
63 msg.msg(MSG::ERROR) << "phiCalo not available as auxilliary variable"
64 << endmsg;
65 if (do_throw) {
66 throw std::runtime_error("phiCalo not available as auxilliary variable");
67 }
68 msg.msg(MSG::WARNING) << "using phi as phiCalo" << endmsg;
69 phi_calo = cluster.phi();
70 }
71 return phi_calo;
72}
73
74inline float get_eta_calo(const xAOD::CaloCluster& cluster, int author,
75 bool do_throw = false) {
76 double eta_calo;
77 static const SG::ConstAccessor<float> etaCaloAcc("etaCalo");
79 eta_calo = cluster.eta();
81 eta_calo)) {
82 } else if (etaCaloAcc.isAvailable(cluster)) {
83 eta_calo = etaCaloAcc(cluster);
84 } else {
85 asg::AsgMessaging msg("get_eta_calo");
86 msg.msg(MSG::ERROR) << "etaCalo not available as auxilliary variable"
87 << endmsg;
88 if (do_throw) {
89 throw std::runtime_error("etaCalo not available as auxilliary variable");
90 }
91 msg.msg(MSG::WARNING) << "using eta as etaCalo" << endmsg;
92 }
93 return eta_calo;
94}
95} // namespace xAOD
96
97
98// the columnar accessor variant of the above functions. I'm not sure
99// if they are used anywhere else, so I'm keeping both.
100namespace columnar {
101 namespace ClusterHelpers {
102
103 template<ContainerIdConcept CI = ContainerId::cluster,typename CM=ColumnarModeDefault>
104 class PhiCaloAccessor final
105 {
109
110 public:
111
113 : m_phiCaloAcc (columnarTool, "phiCalo", {.isOptional = true}),
114 m_phiAcc (columnarTool, "calPhi"),
115 m_phicaloframeAcc (columnarTool, "PHICALOFRAME", {.isOptional = true})
116 {}
117
118 float operator () (ClusterId cluster, int author, bool do_throw=false) const
119 {
120 double phi_calo;
122 phi_calo = m_phiAcc (cluster);
123 }
124 else if (m_phicaloframeAcc.isAvailable (cluster)) {
125 phi_calo = m_phicaloframeAcc (cluster);
126 }
127 else if (m_phiCaloAcc.isAvailable(cluster)) {
128 phi_calo = m_phiCaloAcc(cluster);
129 }
130 else {
131 asg::AsgMessaging msg("get_phi_calo");
132 msg.msg(MSG::ERROR) << "phiCalo not available as auxilliary variable" << endmsg;
133 if (do_throw) { throw std::runtime_error("phiCalo not available as auxilliary variable"); }
134 msg.msg(MSG::WARNING) << "using phi as phiCalo" << endmsg;
135 phi_calo = m_phiAcc (cluster);
136 }
137 return phi_calo;
138 }
139 };
140
141 template<ContainerIdConcept CI = ContainerId::cluster,typename CM=ColumnarModeDefault>
142 class EtaCaloAccessor final
143 {
147
148 public:
149
151 : m_etaCaloAcc (columnarTool, "etaCalo", {.isOptional = true}),
152 m_etaAcc (columnarTool, "calEta"),
153 m_etacaloframeAcc (columnarTool, "ETACALOFRAME", {.isOptional = true})
154 {}
155
156 float operator () (ClusterId cluster, int author, bool do_throw=false) const
157 {
158 double eta_calo;
160 eta_calo = m_etaAcc (cluster);
161 }
162 else if (m_etacaloframeAcc.isAvailable(cluster)) {
163 eta_calo = m_etacaloframeAcc(cluster);
164 }
165 else if (m_etaCaloAcc.isAvailable(cluster)) {
166 eta_calo = m_etaCaloAcc(cluster);
167 }
168 else {
169 asg::AsgMessaging msg("get_eta_calo");
170 msg.msg(MSG::ERROR) << "etaCalo not available as auxilliary variable" << endmsg;
171 if (do_throw) { throw std::runtime_error("etaCalo not available as auxilliary variable"); }
172 msg.msg(MSG::WARNING) << "using eta as etaCalo" << endmsg;
173 eta_calo = m_etaAcc (cluster);
174 }
175 return eta_calo;
176 }
177 };
178 }
179}
180
181namespace CP {
182
184 : virtual public IEgammaCalibrationAndSmearingTool,
186 // Create a proper constructor for Athena
190
191 public:
192 enum class ScaleDecorrelation {
193 FULL,
194 ONENP,
195 FULL_ETA_CORRELATED,
196 ONENP_PLUS_UNCONR
197 };
199 static const int AUTO = 2; // this is used as a third state for boolean
200 // properties (true/false/automatic)
201 typedef unsigned int RandomNumber;
202 typedef std::function<int(const EgammaCalibrationAndSmearingTool&,
206
207 EgammaCalibrationAndSmearingTool(const std::string& name);
209
210 StatusCode initialize() override;
211
212 // Apply the correction on a modifyable egamma object
213 virtual CP::CorrectionCode applyCorrection(xAOD::Egamma&) const override;
215 void setPt(columnar::MutableEgammaId input, double energy) const;
216
217 // Create a corrected copy from a constant egamma object
218 // virtual CP::CorrectionCode correctedCopy(const xAOD::Egamma&,
219 // xAOD::Egamma*&);
221 xAOD::Electron*&) const override;
223 xAOD::Photon*&) const override;
224 double getEnergy(const xAOD::Photon&) const; // for python usage
225 double getEnergy(const xAOD::Electron&) const; // for python usage
226
227 // systematics
228 // Which systematics have an effect on the tool's behaviour?
229 virtual CP::SystematicSet affectingSystematics() const override;
230 // Is the tool affected by a specific systematic?
231 virtual bool isAffectedBySystematic(
232 const CP::SystematicVariation& systematic) const override;
233 // Systematics to be used for physics analysis
234 virtual CP::SystematicSet recommendedSystematics() const override;
235 // Use specific systematic
236 virtual StatusCode applySystematicVariation(
237 const CP::SystematicSet& systConfig) override;
238 virtual void setRandomSeedFunction(const IdFunction&& function) {
239 m_set_seed_function = function;
240 }
242
243 virtual double resolution(
244 double energy, double cl_eta, double cl_etaCalo,
246 bool withCT = false) const override;
247
248 private:
249 static const unsigned int m_Run2Run3runNumberTransition = 400000;
250
251 std::string m_ESModel;
255 ScaleDecorrelation m_decorrelation_model_scale = ScaleDecorrelation::FULL;
261 double m_varSF;
262 std::string m_ResolutionType;
268 // flags duplicated from the underlying ROOT tool
288
289 // 2D histrogram (eta,phi) for a correction to cope with calo distortion
290 // (sagging)
291 std::unique_ptr<TH2> m_caloDistPhiUnifCorr;
292
293 Gaudi::Property<bool> m_fixForMissingCells{
294 this, "FixForMissingCells", true,
295 "AOD fix for cell recovery in core egamma cluster"};
296
297 Gaudi::Property<bool> m_doFwdCalib{
298 this, "DoFwdElectronCalibration", false,
299 "MVA calibration of the forward electron"};
300
301 Gaudi::Property<std::string> m_pVtxKey{
302 this, "PrimaryVerticesKey", "PrimaryVertices",
303 "Name of the primary vertex container"};
304
305 void setupSystematics();
306
307 // if using eta not abs_eta
309 {
310 EtaCaloPredicate(double eta_min, double eta_max) : m_eta_min(eta_min), m_eta_max(eta_max) {}
312 const Accessors& acc = *tool.m_accessors;
313 const double eta = acc.etaCaloAcc(acc.caloClusterAcc(p)[0].value(),acc.authorAcc (p));
314 return (eta >= m_eta_min and eta < m_eta_max);
315 }
316 private:
318 };
319
320 const EgammaPredicate EtaCaloPredicateFactory(double eta_min, double eta_max) const
321 {
322 return EtaCaloPredicate(eta_min, eta_max);
323 }
324
325 // this is needed (instead of a simpler lambda since a clang bug, see
326 // https://its.cern.ch/jira/browse/ATLASG-688)
328 AbsEtaCaloPredicate(double eta_min, double eta_max)
329 : m_eta_min(eta_min), m_eta_max(eta_max) {}
331 const Accessors& acc = *tool.m_accessors;
332 const double aeta =
333 std::abs(acc.etaCaloAcc(acc.caloClusterAcc(p)[0].value(),acc.authorAcc (p)));
334 return (aeta >= m_eta_min and aeta < m_eta_max);
335 }
336
337 private:
339 };
340
342 double eta_max) const {
343 /*return [eta_min, eta_max](const xAOD::Egamma& p) {
344 const double aeta = std::abs(xAOD::get_eta_calo(*p.caloCluster()));
345 return (aeta >= eta_min and aeta < eta_max); };*/
346 return AbsEtaCaloPredicate(eta_min, eta_max);
347 }
348
350 std::pair<double, double> edges) const {
351 return AbsEtaCaloPredicateFactory(edges.first, edges.second);
352 }
353
354 const std::vector<EgammaPredicate> AbsEtaCaloPredicatesFactory(
355 const std::vector<std::pair<double, double>>& edges) const {
356 std::vector<EgammaPredicate> result;
357 result.reserve(edges.size());
358 for (const auto& it : edges) {
359 result.push_back(AbsEtaCaloPredicateFactory(it.first, it.second));
360 }
361 return result;
362 }
363
364 const std::vector<EgammaPredicate> AbsEtaCaloPredicatesFactory(
365 const std::vector<double>& edges) const {
366 std::vector<EgammaPredicate> result;
367 result.reserve(edges.size() - 1);
368 auto it2 = edges.begin();
369 auto it = it2++;
370 for (; it2 != edges.end(); ++it, ++it2) {
371 result.push_back(AbsEtaCaloPredicateFactory(*it, *it2));
372 }
373 return result;
374 }
375
377 DoubleOrAbsEtaCaloPredicate(double eta1_min, double eta1_max,
378 double eta2_min, double eta2_max)
379 : m_eta1_min(eta1_min),
380 m_eta1_max(eta1_max),
381 m_eta2_min(eta2_min),
382 m_eta2_max(eta2_max) {}
383
385 const Accessors& acc = *tool.m_accessors;
386 const double aeta =
387 std::abs(acc.etaCaloAcc(acc.caloClusterAcc(p)[0].value(),acc.authorAcc (p)));
388 return ((aeta >= m_eta1_min and aeta < m_eta1_max) or
389 (aeta >= m_eta2_min and aeta < m_eta2_max));
390 }
391
392 private:
394 };
395
397 double eta1_min, double eta1_max, double eta2_min,
398 double eta2_max) const {
399 return DoubleOrAbsEtaCaloPredicate(eta1_min, eta1_max, eta2_min, eta2_max);
400 }
401
403
404 public:
405 virtual double getEnergy(xAOD::Egamma*, const xAOD::EventInfo*);
406 virtual double getElectronMomentum(const xAOD::Electron*,
407 const xAOD::EventInfo*);
408 double getResolution(const xAOD::Egamma& particle,
409 bool withCT = true) const override;
410 double intermodule_correction(double Ecl, double phi, double eta) const;
411 double correction_phi_unif(double eta, double phi) const;
412
413 private:
415 "calibration service"};
416 std::unique_ptr<egGain::GainUncertainty> m_gain_tool_run2;
417 std::shared_ptr<LinearityADC> m_ADCLinearity_tool;
421
422 // A pointer to the underlying ROOT tool
423 std::unique_ptr<AtlasRoot::egammaEnergyCorrectionTool> m_rootTool;
424 std::string m_MVAfolder;
425
430
431 std::map<CP::SystematicVariation, SysInfo> m_syst_description;
432 std::map<CP::SystematicVariation, egEnergyCorr::Resolution::Variation>
434
435 // These are modified by the ISystematicsTool methods
440
442
444
446 columnar::EgammaId p, columnar::EventInfoId event_info) const;
448 columnar::EgammaId p, columnar::EventInfoId event_info) const;
449
450 // columnar data handles
451public:
452 Gaudi::Property<bool> m_onlyElectrons {this, "onlyElectrons", false, "the tool will only be applied to electrons"};
453 Gaudi::Property<bool> m_onlyPhotons {this, "onlyPhotons", false, "the tool will only be applied to photons"};
455 {
456 Accessors(columnar::ColumnarTool<>& tool) : columnar::ColumnarTool<>(&tool) {}
457
461 columnar::EgammaDecorator<float> ptOutDec {*this, "ptOut", {.replacesColumn = "pt"}};
470 columnar::ClusterAccessor<double> Es0Acc {*this, "correctedcl_Es0", {.isOptional = true}};
471 columnar::ClusterAccessor<double> Es1Acc {*this, "correctedcl_Es1", {.isOptional = true}};
472 columnar::ClusterAccessor<double> Es2Acc {*this, "correctedcl_Es2", {.isOptional = true}};
473 columnar::ClusterAccessor<double> Es3Acc {*this, "correctedcl_Es3", {.isOptional = true}};
480 columnar::EventInfoAccessor<columnar::ObjectColumn> m_eventHandle {*this, "EventInfo", {.addMTDependency=true}};
485 columnar::EventInfoAccessor<float> actIntPerXingAcc {*this, "actualInteractionsPerCrossing"};
486 };
487 std::unique_ptr<Accessors> m_accessors;
488
490 void callEvents (columnar::EventContextRange events) const override;
491};
492
493} // namespace CP
494#endif
Scalar eta() const
pseudorapidity method
#define endmsg
#define ASG_TOOL_CLASS3(CLASSNAME, INT1, INT2, INT3)
Helper class to provide constant type-safe access to aux data.
Return value from object correction CP tools.
egEnergyCorr::Resolution::Variation m_currentResolutionVariation_MC
egEnergyCorr::Scale::Variation m_currentScaleVariation_data
virtual double resolution(double energy, double cl_eta, double cl_etaCalo, PATCore::ParticleType::Type ptype=PATCore::ParticleType::Electron, bool withCT=false) const override
void callSingleEvent(columnar::MutableEgammaRange egammas, columnar::EventInfoId event) const
virtual CP::SystematicSet recommendedSystematics() const override
the list of all systematics this tool recommends to use
const EgammaPredicate DoubleOrAbsEtaCaloPredicateFactory(double eta1_min, double eta1_max, double eta2_min, double eta2_max) const
std::map< CP::SystematicVariation, SysInfo > m_syst_description
PATCore::ParticleDataType::DataType m_simulation
void setPt(columnar::MutableEgammaId input, double energy) const
const EgammaPredicate EtaCaloPredicateFactory(double eta_min, double eta_max) const
double intermodule_correction(double Ecl, double phi, double eta) const
egEnergyCorr::Scale::Variation m_currentScaleVariation_MC
virtual bool isAffectedBySystematic(const CP::SystematicVariation &systematic) const override
Declare the interface that this class provides.
egEnergyCorr::Scale::Variation oldtool_scale_flag_this_event(columnar::EgammaId p, columnar::EventInfoId event_info) const
std::unique_ptr< egGain::GainUncertainty > m_gain_tool_run2
PATCore::ParticleType::Type xAOD2ptype(columnar::EgammaId particle) const
virtual CP::CorrectionCode correctedCopy(const xAOD::Electron &, xAOD::Electron *&) const override
void callEvents(columnar::EventContextRange events) const override
egEnergyCorr::Resolution::resolutionType m_TResolutionType
double getResolution(const xAOD::Egamma &particle, bool withCT=true) const override
virtual CP::CorrectionCode applyCorrection(xAOD::Egamma &) const override
const EgammaPredicate AbsEtaCaloPredicateFactory(double eta_min, double eta_max) const
const std::vector< EgammaPredicate > AbsEtaCaloPredicatesFactory(const std::vector< std::pair< double, double > > &edges) const
double correction_phi_unif(double eta, double phi) const
virtual double getElectronMomentum(const xAOD::Electron *, const xAOD::EventInfo *)
const EgammaPredicate AbsEtaCaloPredicateFactory(std::pair< double, double > edges) const
std::map< CP::SystematicVariation, egEnergyCorr::Resolution::Variation > m_syst_description_resolution
const std::vector< EgammaPredicate > AbsEtaCaloPredicatesFactory(const std::vector< double > &edges) const
virtual StatusCode applySystematicVariation(const CP::SystematicSet &systConfig) override
effects: configure this tool for the given list of systematic variations.
egEnergyCorr::Resolution::Variation oldtool_resolution_flag_this_event(columnar::EgammaId p, columnar::EventInfoId event_info) const
std::function< int(const EgammaCalibrationAndSmearingTool &, columnar::EgammaId, columnar::EventInfoId)> IdFunction
std::unique_ptr< AtlasRoot::egammaEnergyCorrectionTool > m_rootTool
virtual void setRandomSeedFunction(const IdFunction &&function)
std::function< bool(const EgammaCalibrationAndSmearingTool &, columnar::EgammaId)> EgammaPredicate
egEnergyCorr::Resolution::Variation m_currentResolutionVariation_data
virtual CP::SystematicSet affectingSystematics() const override
the list of all systematics this tool can be affected by
interface for all CP tools supporting systematic variations within a reentrant algorithm
Interface for all CP tools supporting systematic variations.
Class to wrap a set of SystematicVariations.
parameterization of correction for ADC non linearity
Helper class to provide constant type-safe access to aux data.
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
Class mimicking the AthMessaging class from the offline software.
Base class for dual-use tools that provide file metadata access.
float operator()(ClusterId cluster, int author, bool do_throw=false) const
float operator()(ClusterId cluster, int author, bool do_throw=false) const
the base class for all columnar components
a handle to hold a IMomentumAccessors object
bool retrieveMoment(MomentType type, double &value) const
Retrieve individual moment.
virtual double eta() const
The pseudorapidity ( ) of the particle.
virtual double phi() const
The azimuthal angle ( ) of the particle.
@ ETACALOFRAME
Eta in the calo frame (for egamma)
@ PHICALOFRAME
Phi in the calo frame (for egamma)
Select isolated Photons, Electrons and Muons.
AccessorTemplate< CI, CT, ColumnAccessMode::input, CM > ColumnAccessor
AccessorTemplate< ContainerId::egamma, CT, ColumnAccessMode::output, CM > EgammaDecorator
Definition EgammaDef.h:53
ObjectId< ContainerId::cluster > ClusterId
Definition ClusterDef.h:26
AccessorTemplate< ContainerId::eventInfo, CT, ColumnAccessMode::input, CM > EventInfoAccessor
ObjectId< ContainerId::egamma > EgammaId
Definition EgammaDef.h:50
ObjectRange< ContainerId::eventContext > EventContextRange
AccessorTemplate< ContainerId::egamma, CT, ColumnAccessMode::input, CM > EgammaAccessor
Definition EgammaDef.h:52
AccessorTemplate< ContainerId::mutableEgamma, CT, ColumnAccessMode::input, CM > MutableEgammaAccessor
Definition EgammaDef.h:58
ObjectRange< ContainerId::mutableEgamma > MutableEgammaRange
Definition EgammaDef.h:55
ObjectId< ContainerId::mutableEgamma > MutableEgammaId
Definition EgammaDef.h:56
AccessorTemplate< ContainerId::cluster, CT, ColumnAccessMode::input, CM > ClusterAccessor
Definition ClusterDef.h:28
ObjectId< ContainerId::eventInfo > EventInfoId
const uint16_t AuthorFwdElectron
Electron reconstructed by the Forward cluster-based algorithm.
Definition EgammaDefs.h:30
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
float get_phi_calo(const xAOD::CaloCluster &cluster, int author, bool do_throw=false)
EventInfo_v1 EventInfo
Definition of the latest event info version.
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
setRawEt setRawPhi int
Egamma_v1 Egamma
Definition of the current "egamma version".
Definition Egamma.h:17
float get_eta_calo(const xAOD::CaloCluster &cluster, int author, bool do_throw=false)
Photon_v1 Photon
Definition of the current "egamma version".
setBGCode setTAP setLVL2ErrorBits bool
static const SG::AuxElement::Accessor< ElementLink< IParticleContainer > > acc("originalObjectLink")
Object used for setting/getting the dynamic decoration in question.
Electron_v1 Electron
Definition of the current "egamma version".
bool operator()(const EgammaCalibrationAndSmearingTool &tool, columnar::EgammaId p)
columnar::EventInfoAccessor< unsigned int > randomrunnumber_getter
columnar::MomentumAccessors< columnar::ContainerId::egamma > momAcc
columnar::EgammaAccessor< std::vector< columnar::OptTrackId > > electronTrackAcc
columnar::ClusterAccessor< columnar::ObjectColumn > m_clusterHandle
columnar::ClusterAccessor< columnar::RetypeColumn< double, float > > clusterPhiAcc
columnar::EventInfoAccessor< columnar::ObjectColumn > m_eventHandle
columnar::EgammaAccessor< columnar::RetypeColumn< double, float > > etaAcc
columnar::EgammaAccessor< std::vector< columnar::OptVertexId > > photonVertexAcc
columnar::MutableEgammaAccessor< columnar::ObjectColumn > m_egammaHandle
columnar::EgammaAccessor< columnar::RetypeColumn< double, float > > phiAcc
columnar::EgammaAccessor< columnar::RetypeColumn< double, float > > ptAcc
columnar::EventInfoHelpers::EventTypeAccessor eventTypeAcc
columnar::EgammaAccessor< std::vector< columnar::OptClusterId > > caloClusterAcc
columnar::ClusterAccessor< columnar::RetypeColumn< double, float > > clusterEtaAcc
DoubleOrAbsEtaCaloPredicate(double eta1_min, double eta1_max, double eta2_min, double eta2_max)
bool operator()(const EgammaCalibrationAndSmearingTool &tool, columnar::EgammaId p)
bool operator()(const EgammaCalibrationAndSmearingTool &tool, columnar::EgammaId p)
MsgStream & msg
Definition testRead.cxx:32