ATLAS Offline Software
EGammaClusterCoreCellRecovery.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 // EGammaClusterCoreCellRecovery.cxx, (c) ATLAS Detector software
8 // Author: G. Unal (Guillaume.Unal@cern.ch)
9 // Decorate egamma objects with the energies in L2 and L3 that are in cells
10 // not included in the original supercluser due to the timing cut in topocluster
11 // building. This is an AOD fix for data (and mc, but effect is small for mc)
12 // produced with rel23 (and 24 ?)
13 
15 #include "CaloEvent/CaloCell.h"
16 
17 #include <TString.h>
18 #include <string>
19 namespace {}
20 
21 // Constructor
23  const std::string& n,
24  const IInterface* p)
25  : AthAlgTool(t, n, p)
26 {
27  declareInterface<DerivationFramework::IAugmentationTool>(this);
28 }
29 
30 
31 // Athena initialize and finalize
34 {
35  ATH_MSG_VERBOSE("initialize() ...");
36 
37  // The main tool
38  ATH_CHECK(m_egammaCellRecoveryTool.retrieve());
39 
40  if (m_SGKey_photons.key().empty() && m_SGKey_electrons.key().empty()) {
41  ATH_MSG_FATAL("No e-gamma collection provided for thinning. At least one "
42  "egamma collection (photons/electrons) must be provided!");
43  return StatusCode::FAILURE;
44  }
45 
46  if (!m_SGKey_electrons.key().empty()) {
47  ATH_MSG_DEBUG("Using " << m_SGKey_electrons << " for electrons");
48  ATH_CHECK(m_SGKey_electrons.initialize());
49 
50  const std::string containerKey = m_SGKey_electrons.key();
51  for (int i = 2; i <= 3; i++) {
52  for (int t = 0; t <=1 ; t++) {
53  m_SGKey_electrons_decorations.emplace_back(
54  Form("%s.%sadded_Lr%d", containerKey.c_str(), (t == 0 ? "n" : "E"), i));
55  }
56  }
57  ATH_CHECK(m_SGKey_electrons_decorations.initialize());
58  if (msgLvl(MSG::DEBUG)) {
59  ATH_MSG_DEBUG("Decorations for " << containerKey);
60  for (const auto& s : m_SGKey_electrons_decorations)
61  { ATH_MSG_DEBUG(s.key()); }
62  }
63  }
64 
65  if (!m_SGKey_photons.key().empty()) {
66  ATH_MSG_DEBUG("Using " << m_SGKey_photons << " for photons");
67  ATH_CHECK(m_SGKey_photons.initialize());
68 
69  const std::string containerKey = m_SGKey_photons.key();
70  for (int i = 2; i <= 3; i++) {
71  for (int t = 0; t <= 1 ; t++) {
72  m_SGKey_photons_decorations.emplace_back(
73  Form("%s.%sadded_Lr%d", containerKey.c_str(), (t == 0 ? "n" : "E"), i));
74  }
75  }
76  ATH_CHECK(m_SGKey_photons_decorations.initialize());
77  if (msgLvl(MSG::DEBUG)) {
78  ATH_MSG_DEBUG("Decorations for " << containerKey);
79  for (const auto& s : m_SGKey_photons_decorations)
80  { ATH_MSG_DEBUG(s.key()); }
81  }
82  }
83 
84  return StatusCode::SUCCESS;
85 }
86 
87 
88 // The decoration itself
91 {
92  const EventContext& ctx = Gaudi::Hive::currentContext();
93 
94  std::vector<SG::WriteDecorHandle<xAOD::EgammaContainer, char>> decon;
95  std::vector<SG::WriteDecorHandle<xAOD::EgammaContainer, float>> decoE;
96  decon.reserve(2);
97  decoE.reserve(2);
98 
99  // Photon decorations
100  if (!m_SGKey_photons.key().empty()) {
101 
102  for (int i = 0; i < 2; i++) {
103  decon.emplace_back(m_SGKey_photons_decorations[i * 2], ctx);
104  decoE.emplace_back(m_SGKey_photons_decorations[i * 2 + 1], ctx);
105  }
106 
107  // Retrieve photon container
109 
110  // Decorate photons
111  for (const auto* photon : *photonContainer.ptr()) {
112  IegammaCellRecoveryTool::Info res = decorateObject(photon);
113  for (int i = 0; i < 2; i++) {
114  decon[i](*photon) = res.nCells[i];
115  decoE[i](*photon) = res.eCells[i];
116  }
117  }
118  }
119 
120  // Electron decorations
121  if (!m_SGKey_electrons.key().empty()) {
122 
123  decon.clear(); decon.reserve(2);
124  decoE.clear(); decoE.reserve(2);
125 
126  for (int i = 0; i < 2; i++) {
127  decon.emplace_back(m_SGKey_electrons_decorations[i * 2], ctx);
128  decoE.emplace_back(m_SGKey_electrons_decorations[i * 2 + 1], ctx);
129  }
130 
131  // Retrieve electron container
133  ctx);
134 
135  // Decorate electrons
136  for (const auto* electron : *electronContainer.ptr()) {
137  IegammaCellRecoveryTool::Info res = decorateObject(electron);
138  for (int i = 0; i < 2; i++) {
139  decon[i](*electron) = res.nCells[i];
140  decoE[i](*electron) = res.eCells[i];
141  }
142  }
143  }
144 
145  return StatusCode::SUCCESS;
146 }
147 
150  const xAOD::Egamma*& egamma) const
151 {
153 
154  ATH_MSG_DEBUG("Trying to recover cell for object of type " << egamma->type()
155  << " pT = " << egamma->pt()
156  << " eta = " << egamma->eta()
157  << " phi = " << egamma->phi());
158 
159  const xAOD::CaloCluster *clus = egamma->caloCluster();
160  if (!clus) {
161  ATH_MSG_WARNING("No associated egamma cluster. Do nothing");
162  return info;
163  }
164 
165  // Find max energy cell in layer 2
166  double etamax = -999., phimax = -999.;
167  if (findMaxECell(clus,etamax,phimax).isFailure()) {
168  ATH_MSG_WARNING("Problem in finding maximum energy cell in layer 2");
169  return info;
170  }
171 
172  info.etamax = etamax;
173  info.phimax = phimax;
174  if (m_egammaCellRecoveryTool->execute(*clus,info).isFailure()) {
175  ATH_MSG_WARNING("Issue trying to recover cells");
176  }
177  return info;
178 }
179 
182  const xAOD::CaloCluster *clus, double &etamax, double &phimax) const
183 {
184  const CaloClusterCellLink* cellLinks = clus->getCellLinks();
185  if (!cellLinks) {
186  ATH_MSG_WARNING("No cell link for cluster. Do nothing");
187  return StatusCode::FAILURE;
188  }
189 
190  CaloClusterCellLink::const_iterator it_cell = cellLinks->begin(),
191  it_cell_e = cellLinks->end();
192 
193  // find maximum cell energy in layer 2
194  double emax = 0.;
195  std::pair<const CaloCell*,double> maxcell{nullptr,0}; //just for debug
196  for(; it_cell != it_cell_e; ++it_cell) {
197  const CaloCell* cell = (*it_cell);
198  if (cell) {
199  if (!cell->caloDDE()) {
200  ATH_MSG_WARNING("Calo cell without detector element ?? eta = "
201  << cell->eta() << " phi = " << cell->phi());
202  continue;
203  }
204  int layer = cell->caloDDE()->getSampling();
206  double w = it_cell.weight();
207  double eCell = cell->energy();
208  if (m_UseWeightForMaxCell) eCell *= w;
209  if (eCell > emax) {
210  emax = eCell;
211  maxcell.first = cell;
212  maxcell.second = w;
213  }
214  }
215  }
216  }
217 
218  if (emax > 0) {
219  etamax = maxcell.first->caloDDE()->eta_raw();
220  phimax = maxcell.first->caloDDE()->phi_raw();
221  if (msgLvl(MSG::DEBUG)) {
222  CaloSampling::CaloSample sam = maxcell.first->caloDDE()->getSampling();
223  double etaAmax = clus->etamax(sam);
224  double phiAmax = clus->phimax(sam);
225  double vemax = clus->energy_max(sam);
226  ATH_MSG_DEBUG("Cluster energy in sampling 2 = " << clus->energyBE(2)
227  << " maximum layer 2 energy cell, E = " << maxcell.first->energy()
228  << " check E = " << vemax
229  << " w = " << maxcell.second << "\n"
230  << " in calo frame, eta = " << etamax << " phi = " << phimax << "\n"
231  << " in ATLAS frame, eta = " << etaAmax << " phi = " << phiAmax);
232  }
233  } else {
234  ATH_MSG_WARNING("No layer 2 cell with positive energy ! Should never happen");
235  return StatusCode::FAILURE;
236  }
237  return StatusCode::SUCCESS;
238 }
grepfile.info
info
Definition: grepfile.py:38
xAOD::CaloCluster_v1::phimax
float phimax(const CaloSample sampling) const
Retrieve of cell with maximum energy in given sampling.
Definition: CaloCluster_v1.cxx:589
electronContainer
xAOD::ElectronContainer * electronContainer
Definition: TrigGlobEffCorrValidation.cxx:187
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
ParticleImpl::pt
virtual double pt() const
transverse momentum
Definition: ParticleImpl.h:554
DerivationFramework::EGammaClusterCoreCellRecovery::initialize
StatusCode initialize()
Definition: EGammaClusterCoreCellRecovery.cxx:33
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
DerivationFramework::EGammaClusterCoreCellRecovery::addBranches
virtual StatusCode addBranches() const
Pass the thinning service
Definition: EGammaClusterCoreCellRecovery.cxx:90
IegammaCellRecoveryTool::Info
Definition: IegammaCellRecoveryTool.h:36
CaloCell.h
xAOD::Egamma_v1
Definition: Egamma_v1.h:56
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
DerivationFramework::EGammaClusterCoreCellRecovery::decorateObject
IegammaCellRecoveryTool::Info decorateObject(const xAOD::Egamma *&egamma) const
Definition: EGammaClusterCoreCellRecovery.cxx:149
xAOD::CaloCluster_v1::etamax
float etamax(const CaloSample sampling) const
Retrieve of cell with maximum energy in given sampling.
Definition: CaloCluster_v1.cxx:576
egamma
Definition: egamma.h:58
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:59
DerivationFramework::EGammaClusterCoreCellRecovery::EGammaClusterCoreCellRecovery
EGammaClusterCoreCellRecovery(const std::string &t, const std::string &n, const IInterface *p)
Definition: EGammaClusterCoreCellRecovery.cxx:22
constants.EMB2
int EMB2
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:54
lumiFormat.i
int i
Definition: lumiFormat.py:92
CaloSampling::CaloSample
CaloSample
Definition: Calorimeter/CaloGeoHelpers/CaloGeoHelpers/CaloSampling.h:22
xAOD::CaloCluster_v1::energy_max
float energy_max(const CaloSample sampling) const
Retrieve maximum cell energy in given sampling.
Definition: CaloCluster_v1.cxx:563
beamspotman.n
n
Definition: beamspotman.py:731
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
res
std::pair< std::vector< unsigned int >, bool > res
Definition: JetGroupProductTest.cxx:14
ParticleImpl::phi
virtual double phi() const
phi in [-pi,pi[
Definition: ParticleImpl.h:524
EGammaClusterCoreCellRecovery.h
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
ParticleImpl::eta
virtual double eta() const
pseudo rapidity
Definition: ParticleImpl.h:514
xAOD::CaloCluster_v1::getCellLinks
const CaloClusterCellLink * getCellLinks() const
Get a pointer to the CaloClusterCellLink object (const version)
Definition: CaloCluster_v1.cxx:905
photonContainer
xAOD::PhotonContainer * photonContainer
Definition: TrigGlobEffCorrValidation.cxx:189
xAOD::photon
@ photon
Definition: TrackingPrimitives.h:199
CaloCell
Data object for each calorimeter readout cell.
Definition: CaloCell.h:57
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
DerivationFramework::EGammaClusterCoreCellRecovery::findMaxECell
StatusCode findMaxECell(const xAOD::CaloCluster *clus, double &etamax, double &phimax) const
Definition: EGammaClusterCoreCellRecovery.cxx:181
DEBUG
#define DEBUG
Definition: page_access.h:11
xAOD::CaloCluster_v1::energyBE
float energyBE(const unsigned layer) const
Get the energy in one layer of the EM Calo.
Definition: CaloCluster_v1.cxx:630
xAOD::EgammaParameters::electron
@ electron
Definition: EgammaEnums.h:18
AthAlgTool
Definition: AthAlgTool.h:26
python.IoTestsLib.w
def w
Definition: IoTestsLib.py:200
constants.EME2
int EME2
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:56