ATLAS Offline Software
Loading...
Searching...
No Matches
TElectronTestAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
6
9//
12//
13#include "xAODEgamma/Electron.h"
14//
15#include <cmath>
16#include <optional>
17
18namespace ADD_CMODE(CP)
19{
20
21StatusCode TElectronTestAlg::initialize() {
22
23 // input
24 ATH_CHECK(m_electronContainer.initialize());
25
26 // Decorations
27 m_pimpl = std::make_unique<Root::TElectronEfficiencyCorrectionTool>(
28 (this->name() + ".TElectronEfficiencyCorrection").c_str());
29 //
30 m_pimpl->msg().setLevel(this->msg().level());
31 //
32 std::string mapFileName = PathResolverFindCalibFile(m_mapFile);
33 std::string key = ElRecomFileHelpers::convertToOneKey(m_recoKey, m_idKey,
34 m_isoKey, m_triggerKey);
35 std::string value = ElRecomFileHelpers::getValueByKey(mapFileName, key);
36 std::string filename = PathResolverFindCalibFile(value);
37 if (filename.empty()) {
38 ATH_MSG_ERROR("Could NOT resolve file name " << value);
39 return StatusCode::FAILURE;
40 } else {
41 ATH_MSG_INFO(" Using recommendations file = " << filename);
42 }
43 m_pimpl->addFileName(filename);
44 //
45 if (m_mode == Toys || m_mode == All) {
46 m_pimpl->bookCombToyMCScaleFactors(m_number_of_toys);
47 }
48 // We use 0 as failure ...
49 if (m_pimpl->initialize() == 0) {
51 "Could not initialize the TElectronEfficiencyCorrectionTool!");
52 return StatusCode::FAILURE;
53 }
54
55 // Auxiliary info
56 m_numberCorr = m_pimpl->getNSyst();
57 std::map<float, std::vector<float>> tmp;
58 m_pimpl->getNbins(tmp);
59 m_lowestEt = tmp.begin()->first;
60 m_doDetail = (m_mode != Toys && m_mode != Total);
61 m_doToys = (m_mode == Toys || m_mode == All);
62
63 // decorations if requested
64 const std::string baseName = m_electronContainer.key();
65 m_SF = baseName + ".EFF_" + key + "_SF";
66 m_TotalUp = baseName + ".EFF_" + key + "_Total__Up";
67 m_TotalDown = baseName + ".EFF_" + key + "_Total__Down";
68 m_uncorrUp = baseName + ".EFF_" + key + "_UnCorr__Up";
69 m_uncorrDown = baseName + ".EFF_" + key + "_UnCorr__Down";
70 m_HistIndex = baseName + ".EFF_" + key + "_HistIndex";
71 m_HistBin = baseName + ".EFF_" + key + "_HistBin";
72 m_corrUp = baseName + ".EFF_" + key + "_Corr__Up";
73 m_corrDown = baseName + ".EFF_" + key + "_Corr__Down";
74 m_toys = baseName + ".EFF_" + key + "__toys";
75
76 ATH_CHECK(m_SF.initialize(m_decorate));
77 ATH_CHECK(m_TotalUp.initialize(m_decorate));
78 ATH_CHECK(m_TotalDown.initialize(m_decorate));
79 ATH_CHECK(m_uncorrUp.initialize(m_decorate && m_doDetail));
80 ATH_CHECK(m_uncorrDown.initialize(m_decorate && m_doDetail));
81 ATH_CHECK(m_HistIndex.initialize(m_decorate && m_doDetail));
82 ATH_CHECK(m_HistBin.initialize(m_decorate && m_doDetail));
83 ATH_CHECK(m_corrUp.initialize(m_decorate && m_doDetail));
84 ATH_CHECK(m_corrDown.initialize(m_decorate && m_doDetail));
85 ATH_CHECK(m_toys.initialize(m_decorate && m_doToys));
86
87 return StatusCode::SUCCESS;
88}
89
90StatusCode TElectronTestAlg::execute(const EventContext& ctx) const {
91
92 //
93 unsigned int runNumber = 428648; // use a dummy default for testing
94
95 int dataType = m_dataType;
96 //
97 SG::ReadHandle<xAOD::ElectronContainer> electrons{m_electronContainer, ctx};
98
99 std::optional<SG::WriteDecorHandle<xAOD::ElectronContainer, double>> SF;
100 std::optional<SG::WriteDecorHandle<xAOD::ElectronContainer, double>> TotalUp;
101 std::optional<SG::WriteDecorHandle<xAOD::ElectronContainer, double>>
102 TotalDown;
103 std::optional<SG::WriteDecorHandle<xAOD::ElectronContainer, double>> uncorrUp;
104 std::optional<SG::WriteDecorHandle<xAOD::ElectronContainer, double>>
105 uncorrDown;
106 std::optional<SG::WriteDecorHandle<xAOD::ElectronContainer, int>> HistIndex;
107 std::optional<SG::WriteDecorHandle<xAOD::ElectronContainer, int>> HistBin;
108 std::optional<
110 corrUp;
111 std::optional<
113 corrDown;
114 std::optional<
116 toys;
117
118 if (m_decorate) {
119 SF.emplace(m_SF, ctx);
120 TotalUp.emplace(m_TotalUp, ctx);
121 TotalDown.emplace(m_TotalDown, ctx);
122 if (m_doDetail) {
123 uncorrUp.emplace(m_uncorrUp, ctx);
124 uncorrDown.emplace(m_uncorrDown, ctx);
125 HistIndex.emplace(m_HistIndex, ctx);
126 HistBin.emplace(m_HistBin, ctx);
127 corrUp.emplace(m_corrUp, ctx);
128 corrDown.emplace(m_corrDown, ctx);
129 }
130 if (m_doToys) {
131 toys.emplace(m_toys, ctx);
132 }
133 }
134
135 for (const xAOD::Electron* el : *electrons) {
136
138
139 // In case we fail
140 if (std::abs(el->eta()) > 2.469 || el->pt() < 10000) {
141 // if we decorate we need to set everything to dummy
142 // avoid decorating partially the collection ...
143 if (m_decorate) {
144 SF.value()(*el) = result.SF;
145 TotalUp.value()(*el) = result.SF + result.Total;
146 TotalDown.value()(*el) = result.SF - result.Total;
147 if (m_doDetail) {
148 uncorrUp.value()(*el) = result.SF + result.UnCorr;
149 uncorrDown.value()(*el) = result.SF - result.UnCorr;
150 HistIndex.value()(*el) = result.histIndex;
151 HistBin.value()(*el) = result.histBinNum;
152 corrUp.value()(*el) = result.Corr;
153 corrDown.value()(*el) = result.Corr;
154 }
155 if (m_doToys) {
156 toys.value()(*el) = result.toys;
157 }
158 }
159 continue;
160 }
161
162 // Some logic for validity
163 double cluster_eta(-9999.9);
164 const xAOD::CaloCluster* cluster = el->caloCluster();
165 if (!cluster) {
166 ATH_MSG_ERROR("ERROR no cluster associated to the Electron \n");
167 return StatusCode::FAILURE;
168 }
169 // we need to use different variables for central and forward electrons
170 static const SG::ConstAccessor<uint16_t> accAuthor("author");
171 if (accAuthor.isAvailable(*el) &&
173 cluster_eta = cluster->eta();
174 } else {
175 cluster_eta = cluster->etaBE(2);
176 }
177
178 // use et from cluster because it is immutable under syst variations of
179 // electron energy scale
180 const double energy = cluster->e();
181 const double parEta = el->eta();
182 const double coshEta = std::cosh(parEta);
183 double et = (coshEta != 0.) ? energy / coshEta : 0.;
184 // allow for a 5% margin at the lowest pT bin boundary
185 if (et < m_lowestEt) {
186 et = et * 1.05;
187 }
188
189 // do the calculations
190 const int status = m_pimpl->calculate(
191 static_cast<PATCore::ParticleDataType::DataType>(dataType), runNumber,
192 cluster_eta, et, /* in MeV */
193 result, (m_mode == Total) /* do work only for Total*/);
194 if (!status) {
195 ATH_MSG_ERROR("Something went wrong in the calculation");
196 return StatusCode::FAILURE;
197 }
198
199 // print outs
200 ATH_MSG_INFO("--------------------------------------------");
201 ATH_MSG_INFO("Electron pt : " << el->pt() << " eta " << el->eta());
202 ATH_MSG_INFO("SF = " << result.SF << " +- " << result.Total);
203 if (m_doDetail) {
204 ATH_MSG_INFO("SF = " << result.SF << " +- " << result.UnCorr
205 << " stat only ");
206 ATH_MSG_INFO("At histo " << result.histIndex << " at bin "
207 << result.histBinNum);
208 ATH_MSG_INFO("Num correlated " << result.Corr.size());
209 for (double res : result.Corr) {
210 ATH_MSG_INFO("+- " << res);
211 }
212 }
213 if (m_doToys) {
214 ATH_MSG_INFO("Run " << result.toys.size() << " Toys ");
215 for (double res : result.toys) {
216 ATH_MSG_INFO("+- " << res);
217 }
218 }
219 if (m_decorate) {
220 SF.value()(*el) = result.SF;
221 TotalUp.value()(*el) = result.SF + result.Total;
222 TotalDown.value()(*el) = result.SF - result.Total;
223 if (m_doDetail) {
224 uncorrUp.value()(*el) = result.SF + result.UnCorr;
225 uncorrDown.value()(*el) = result.SF - result.UnCorr;
226 HistIndex.value()(*el) = result.histIndex;
227 HistBin.value()(*el) = result.histBinNum;
228 const size_t corrsize = result.Corr.size();
229 std::vector<double> up(corrsize, 0);
230 std::vector<double> down(corrsize, 0);
231 for (size_t i = 0; i < corrsize; ++i) {
232 up[i] = result.SF + result.Corr[i];
233 down[i] = result.SF - result.Corr[i];
234 }
235 corrUp.value()(*el) = std::move(up);
236 corrDown.value()(*el) = std::move(down);
237 }
238 if (m_doToys) {
239 toys.value()(*el) = std::move(result.toys);
240 }
241 }
242
243 } // end of loop over electrons
244 return StatusCode::SUCCESS;
245}
246
247} // namespace ADD_CMODE(CP)
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_INFO(x,...)
Handle class for reading from StoreGate.
Handle class for adding a decoration to an object.
std::pair< std::vector< unsigned int >, bool > res
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
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.
Handle class for adding a decoration to an object.
virtual double eta() const
The pseudorapidity ( ) of the particle.
virtual double e() const
The total energy of the particle.
float etaBE(const unsigned layer) const
Get the eta in one layer of the EM Calo.
std::string getValueByKey(const std::string &mapFile, const std::string &key)
std::string convertToOneKey(const std::string &recokey, const std::string &idkey, const std::string &isokey, const std::string &trigkey)
const uint16_t AuthorFwdElectron
Electron reconstructed by the Forward cluster-based algorithm.
Definition EgammaDefs.h:30
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
Electron_v1 Electron
Definition of the current "egamma version".
Definition Electron.h:17
Extra patterns decribing particle interation process.
MsgStream & msg
Definition testRead.cxx:32