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  // This tool needs the calo cells linked to the clusters...
66  ATH_CHECK(m_SGKey_CaloCells.initialize());
67 
68  if (!m_SGKey_photons.key().empty()) {
69  ATH_MSG_DEBUG("Using " << m_SGKey_photons << " for photons");
70  ATH_CHECK(m_SGKey_photons.initialize());
71 
72  const std::string containerKey = m_SGKey_photons.key();
73  for (int i = 2; i <= 3; i++) {
74  for (int t = 0; t <= 1 ; t++) {
75  m_SGKey_photons_decorations.emplace_back(
76  Form("%s.%sadded_Lr%d", containerKey.c_str(), (t == 0 ? "n" : "E"), i));
77  }
78  }
79  ATH_CHECK(m_SGKey_photons_decorations.initialize());
80  if (msgLvl(MSG::DEBUG)) {
81  ATH_MSG_DEBUG("Decorations for " << containerKey);
82  for (const auto& s : m_SGKey_photons_decorations)
83  { ATH_MSG_DEBUG(s.key()); }
84  }
85  }
86 
87  return StatusCode::SUCCESS;
88 }
89 
90 
91 // The decoration itself
94 {
95  const EventContext& ctx = Gaudi::Hive::currentContext();
96 
97  std::vector<SG::WriteDecorHandle<xAOD::EgammaContainer, char>> decon;
98  std::vector<SG::WriteDecorHandle<xAOD::EgammaContainer, float>> decoE;
99  decon.reserve(2);
100  decoE.reserve(2);
101 
102  // Photon decorations
103  if (!m_SGKey_photons.key().empty()) {
104 
105  for (int i = 0; i < 2; i++) {
106  decon.emplace_back(m_SGKey_photons_decorations[i * 2], ctx);
107  decoE.emplace_back(m_SGKey_photons_decorations[i * 2 + 1], ctx);
108  }
109 
110  // Retrieve photon container
112 
113  // Decorate photons
114  for (const auto* photon : *photonContainer.ptr()) {
115  IegammaCellRecoveryTool::Info res = decorateObject(photon);
116  for (int i = 0; i < 2; i++) {
117  decon[i](*photon) = res.nCells[i];
118  decoE[i](*photon) = res.eCells[i];
119  }
120  }
121  }
122 
123  // Electron decorations
124  if (!m_SGKey_electrons.key().empty()) {
125 
126  decon.clear(); decon.reserve(2);
127  decoE.clear(); decoE.reserve(2);
128 
129  for (int i = 0; i < 2; i++) {
130  decon.emplace_back(m_SGKey_electrons_decorations[i * 2], ctx);
131  decoE.emplace_back(m_SGKey_electrons_decorations[i * 2 + 1], ctx);
132  }
133 
134  // Retrieve electron container
136  ctx);
137 
138  // Decorate electrons
139  for (const auto* electron : *electronContainer.ptr()) {
140  IegammaCellRecoveryTool::Info res = decorateObject(electron);
141  for (int i = 0; i < 2; i++) {
142  decon[i](*electron) = res.nCells[i];
143  decoE[i](*electron) = res.eCells[i];
144  }
145  }
146  }
147 
148  return StatusCode::SUCCESS;
149 }
150 
153  const xAOD::Egamma*& egamma) const
154 {
156 
157  ATH_MSG_DEBUG("Trying to recover cell for object of type " << egamma->type()
158  << " pT = " << egamma->pt()
159  << " eta = " << egamma->eta()
160  << " phi = " << egamma->phi());
161 
162  const xAOD::CaloCluster *clus = egamma->caloCluster();
163  if (!clus) {
164  ATH_MSG_WARNING("No associated egamma cluster. Do nothing");
165  return info;
166  }
167 
168  // Find max energy cell in layer 2
169  double etamax = -999., phimax = -999.;
170  if (findMaxECell(clus,etamax,phimax).isFailure()) {
171  ATH_MSG_WARNING("Problem in finding maximum energy cell in layer 2");
172  return info;
173  }
174 
175  info.etamax = etamax;
176  info.phimax = phimax;
177  if (m_egammaCellRecoveryTool->execute(*clus,info).isFailure()) {
178  ATH_MSG_WARNING("Issue trying to recover cells");
179  }
180  return info;
181 }
182 
185  const xAOD::CaloCluster *clus, double &etamax, double &phimax) const
186 {
187  const CaloClusterCellLink* cellLinks = clus->getCellLinks();
188  if (!cellLinks) {
189  ATH_MSG_WARNING("No cell link for cluster. Do nothing");
190  return StatusCode::FAILURE;
191  }
192 
193  // First check :
194  // if we run in MT, this would be nullptr without initializing a ReadHandleKey
195  const CaloCellContainer *caloCells = cellLinks->getCellContainer();
196  if (!caloCells) {
197  ATH_MSG_WARNING("No cells for cluster. Do nothing");
198  return StatusCode::FAILURE;
199  }
200 
201  // Second check :
202  // one might have used a custom cell container for the linked cells
203  if (cellLinks->getCellContainerLink().dataID() != m_SGKey_CaloCells.key()) {
204  ATH_MSG_ERROR("Wrong key for the calo cells");
205  return StatusCode::FAILURE;
206  }
207 
208  CaloClusterCellLink::const_iterator it_cell = cellLinks->begin(),
209  it_cell_e = cellLinks->end();
210 
211  // find maximum cell energy in layer 2
212  double emax = 0.;
213  std::pair<const CaloCell*,double> maxcell{nullptr,0}; //just for debug
214  for(; it_cell != it_cell_e; ++it_cell) {
215  const CaloCell* cell = (*it_cell);
216  if (cell) {
217  if (!cell->caloDDE()) {
218  ATH_MSG_WARNING("Calo cell without detector element ?? eta = "
219  << cell->eta() << " phi = " << cell->phi());
220  continue;
221  }
222  int layer = cell->caloDDE()->getSampling();
224  double w = it_cell.weight();
225  double eCell = cell->energy();
226  if (m_UseWeightForMaxCell) eCell *= w;
227  if (eCell > emax) {
228  emax = eCell;
229  maxcell.first = cell;
230  maxcell.second = w;
231  }
232  }
233  }
234  }
235 
236  if (emax > 0) {
237  etamax = maxcell.first->caloDDE()->eta_raw();
238  phimax = maxcell.first->caloDDE()->phi_raw();
239  if (msgLvl(MSG::DEBUG)) {
240  CaloSampling::CaloSample sam = maxcell.first->caloDDE()->getSampling();
241  double etaAmax = clus->etamax(sam);
242  double phiAmax = clus->phimax(sam);
243  double vemax = clus->energy_max(sam);
244  ATH_MSG_DEBUG("Cluster energy in sampling 2 = " << clus->energyBE(2)
245  << " maximum layer 2 energy cell, E = " << maxcell.first->energy()
246  << " check E = " << vemax
247  << " w = " << maxcell.second << "\n"
248  << " in calo frame, eta = " << etamax << " phi = " << phimax << "\n"
249  << " in ATLAS frame, eta = " << etaAmax << " phi = " << phiAmax);
250  }
251  } else {
252  ATH_MSG_WARNING("No layer 2 cell with positive energy ! Should never happen");
253  return StatusCode::FAILURE;
254  }
255  return StatusCode::SUCCESS;
256 }
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
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:93
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:152
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
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
DerivationFramework::EGammaClusterCoreCellRecovery::EGammaClusterCoreCellRecovery
EGammaClusterCoreCellRecovery(const std::string &t, const std::string &n, const IInterface *p)
Definition: EGammaClusterCoreCellRecovery.cxx:22
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
constants.EMB2
int EMB2
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:54
lumiFormat.i
int i
Definition: lumiFormat.py:85
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
CaloCellContainer
Container class for CaloCell.
Definition: CaloCellContainer.h:55
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:184
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