ATLAS Offline Software
EGammaCookieCutClusterTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // EGammaCookieCutClusterTool.cxx, (c) ATLAS Detector software
8 // Decorate egamma objects with cluster moments from a cookie-cut cluster
9 
11 
14 
15 namespace {
16  constexpr float cellEtaSize = 0.1;
17  constexpr float cellPhiSize = 0.1;
18 }
19 
20 // Constructor
22  const std::string& t,
23  const std::string& n,
24  const IInterface* p)
25  : base_class(t, n, p)
26 {
27 }
28 
29 
30 // Athena initialize and finalize
33 {
34  ATH_MSG_VERBOSE("initialize() ...");
35 
36  ATH_CHECK(m_caloDetDescrMgrKey.initialize());
37 
38  ATH_MSG_DEBUG("Will store cookie cut clusters in this container "
39  << m_outClusterContainerKey.key());
40  ATH_CHECK(m_outClusterContainerKey.initialize());
41  m_outClusterContainerCellLinkKey = m_outClusterContainerKey.key() + "_links";
42  ATH_CHECK(m_outClusterContainerCellLinkKey.initialize());
43 
44  ATH_MSG_DEBUG("Using " << m_SGKey_electrons << " for electrons");
45  ATH_CHECK(m_SGKey_electrons.initialize());
46 
47  const std::string containerKey = m_SGKey_electrons.key();
48  for (const auto& e : m_vecMName) {
49  std::string key;
50  if (m_storeCookMom) {
51  key = containerKey + ".cookiecut" + e;
52  m_SGKey_electrons_decorations.emplace_back(key);
53  }
54  if (m_storeOrigMom) {
55  key = containerKey + ".original" + e;
56  m_SGKey_electrons_decorations.emplace_back(key);
57  }
58  }
59  m_SGKey_electrons_decorations.emplace_back(
60  containerKey + ".cookiecutClusterLink");
61  //
62  m_nDecor = m_SGKey_electrons_decorations.size();
63  ATH_MSG_DEBUG("Initialize nDecor = " << m_nDecor);
64  ATH_CHECK(m_SGKey_electrons_decorations.initialize());
65  if (msgLvl(MSG::DEBUG)) {
66  ATH_MSG_DEBUG("Decorations for " << containerKey);
67  for (const auto& s : m_SGKey_electrons_decorations)
68  { ATH_MSG_DEBUG(s.key()); }
69  }
70 
71  m_CookieCutPars.maxDelEta = m_maxDelEtaCells * cellEtaSize * 0.5;
72  m_CookieCutPars.maxDelPhi = m_maxDelPhiCells * cellPhiSize * 0.5;
73  m_CookieCutPars.maxDelR2 = m_maxDelR * m_maxDelR;
74 
75  // Retrieve cluster moment maker in case we cookie cut and want to recompute
76  if (!m_clusterCorrectionTools.empty()) {
77  ATH_CHECK(m_clusterCorrectionTools.retrieve());
78  m_CookieCutPars.recomputeMoments = true;
79  }
80 
81  return StatusCode::SUCCESS;
82 }
83 
84 // The decoration itself
87 {
88 
89  // For debug
90  static const std::vector<CaloSampling::CaloSample> s_sam
101 
102  // Create the relevant cluster output and register it.
104  m_outClusterContainerKey,
105  ctx
106  );
108 
109  SG::WriteHandle<CaloClusterCellLinkContainer> outClusterContainerCellLink(
110  m_outClusterContainerCellLinkKey,
111  ctx
112  );
113  ATH_CHECK(outClusterContainerCellLink.record(
114  std::make_unique<CaloClusterCellLinkContainer>())
115  );
116 
117  // Retrieve electron container
119  ctx);
120  const std::size_t nF = electronContainer.ptr()->size();
121  if (nF == 0) {
122  return StatusCode::SUCCESS;
123  }
124 
125  std::vector<SG::WriteDecorHandle<xAOD::EgammaContainer, float>> decoM;
126  decoM.reserve(m_nDecor);
127  for (int i = 0; i < m_nDecor - 1; i++) {
128  decoM.emplace_back(m_SGKey_electrons_decorations[i], ctx);
129  }
130 
131  if (msgLevel(MSG::DEBUG)) {
132  std::call_once(m_Seen, [this,&decoM]() {
133  for (int i = 0; i < m_nDecor - 1; i++) {
134  ATH_MSG_DEBUG("Decor " << i << " out of " << m_nDecor
135  << " " << m_SGKey_electrons_decorations[i].key()
136  << " " << decoM[i].decorKey());
137  }
138  });
139  }
142  decoEl(m_SGKey_electrons_decorations[m_nDecor-1],ctx);
143 
144  // Calorimeter description.
145  SG::ReadCondHandle<CaloDetDescrManager> caloDetDescrMgrHandle{
146  m_caloDetDescrMgrKey, ctx
147  };
148  ATH_CHECK(caloDetDescrMgrHandle.isValid());
149  const CaloDetDescrManager* calodetdescrmgr = *caloDetDescrMgrHandle;
150 
151  // Decorate electrons
152  int iel = 0;
153  std::vector<bool> success(nF,true);
154  ATH_MSG_VERBOSE("Will analyze " << nF << " forward electrons");
155  for (const auto* electron : *electronContainer.ptr()) {
156 
157  const xAOD::CaloCluster *cluster = electron->caloCluster();
158  ATH_MSG_DEBUG("Electron " << electron->index() << " cluster"
159  << " pT = " << cluster->pt()
160  << " eta = " << cluster->eta());
161 
162  const DataLink<CaloCellContainer>& cellCont =
163  cluster->getCellLinks()->getCellContainerLink();
164 
165  std::unique_ptr<xAOD::CaloCluster> newCluster =
166  egammaClusterCookieCut::cookieCut(*cluster, *calodetdescrmgr,
167  cellCont, m_CookieCutPars);
168 
169  if (!newCluster || newCluster->getCellLinks()->size() == 0) {
170  ATH_MSG_DEBUG("No able to build a new cluster for electron "
171  << electron->index()
172  << " pT = " << electron->pt()
173  << " eta = " << electron->eta()
174  << " original cluster " << cluster->index()
175  << " pT = " << cluster->pt()
176  << " eta = " << cluster->eta()
177  << " has EME2 or FCAL0"
178  << " " << cluster->hasSampling(CaloSampling::EME2)
179  << " " << cluster->hasSampling(CaloSampling::FCAL0)
180  << " reason : "
181  << (newCluster ? " no cells in cluster" : " no cluster"));
182  if (!newCluster) {
183  ATH_MSG_VERBOSE("Energies in various samplings :");
184  for (auto s : s_sam)
185  ATH_MSG_VERBOSE("Sampling " << s << " E = " << cluster->eSample(s));
186  }
188  success[iel] = false;
189  }
190 
191  if (success[iel]) {
192  if (newCluster) {
193  ATH_MSG_DEBUG("Cookie cut cluster"
194  << " pT = " << newCluster->pt()
195  << " eta = " << newCluster->eta());
196  }
197  outClusterContainer->push_back(std::move(newCluster));
198  size_t index = outClusterContainer->size() - 1;
200  clusterLink(*outClusterContainer, index, ctx);
201  // Now decorate the electron with the link to cookie cut cluster
202  decoEl(*electron) = clusterLink;
203  }
204 
205  // Eventually decorate the electron with the original moment
206  if (m_storeOrigMom) {
207  for (size_t i = 0; i < m_vecM.size(); i++) {
208  int indexDecor = m_storeCookMom ? 2*i+1 : i;
209  double m = 0.;
210  bool gotM = cluster->retrieveMoment(m_vecM.at(i), m);
211  if (!gotM) {
212  ATH_MSG_VERBOSE(m_vecMName[i]
213  << " does not exist for the original cluster");
214  }
215  decoM[indexDecor](*electron) = float(m);
216  ATH_MSG_VERBOSE("Decorated electron " << electron->index()
217  << " with original moment "
218  << i << " " << m_vecMName[i]
219  << " = " << m << " (decoration index =" << indexDecor
220  << " key = " << decoM[indexDecor].decorKey() << ")");
221  }
222  }
223  iel++;
224  }
225 
226  if (!m_clusterCorrectionTools.empty()) {
227  ToolHandleArray<CaloClusterCollectionProcessor>::const_iterator
228  toolIt = m_clusterCorrectionTools.begin(),
229  toolIt_e = m_clusterCorrectionTools.end();
230  for (; toolIt != toolIt_e; ++toolIt) {
231  ATH_CHECK((*toolIt)->execute(ctx, outClusterContainer.ptr()));
232  }
233 
234  if (m_storeCookMom) {
235  static const SG::AuxElement::Accessor<
237  cookClusLinkAcc( "cookiecutClusterLink" );
238  iel = 0;
239  for (const auto* electron : *electronContainer.ptr()) {
240  const xAOD::CaloCluster *cluster = nullptr;
241  if (success[iel] && cookClusLinkAcc.isAvailable(*electron)) {
243  cookClusLinkAcc(*electron);
244  if (link.isValid()) {
245  cluster = *link;
246  }
247  }
248  if (success[iel] && cluster == nullptr) {
249  ATH_MSG_WARNING("CookieCut cluster was build successfully, but"
250  "could not be retrieved");
251  }
252 
253  for (size_t i = 0; i < m_vecM.size(); i++) {
254  int indexDecor = m_storeOrigMom ? 2*i : i;
255  double m = 0.;
256  if (cluster) {
257  bool gotM = cluster->retrieveMoment(m_vecM.at(i), m);
258  if (!gotM) {
259  ATH_MSG_VERBOSE(m_vecMName[i]
260  << " does not exist for the new cluster");
261  }
262  }
263  decoM[indexDecor](*electron) = float(m);
264  ATH_MSG_VERBOSE("Decorated electron " << electron->index()
265  << " with new moment "
266  << i << " " << m_vecMName[i]
267  << " = " << m << " (decoration index = " << indexDecor
268  << " key = " << decoM[indexDecor].decorKey() << ")");
269  }
270  }
271  }
272  }
273 
275  ctx,
276  outClusterContainer,
277  outClusterContainerCellLink);
278 
279  ATH_MSG_DEBUG("Built " << outClusterContainer.ptr()->size()
280  << " cookie cut clusters");
281 
282  return StatusCode::SUCCESS;
283 }
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
electronContainer
xAOD::ElectronContainer * electronContainer
Definition: TrigGlobEffCorrValidation.cxx:187
CaloClusterStoreHelper::finalizeClusters
static StatusCode finalizeClusters(SG::WriteHandle< CaloClusterCellLinkContainer > &h, xAOD::CaloClusterContainer *pClusterColl)
Finalize clusters (move CaloClusterCellLink to a separate container).
Definition: CaloClusterStoreHelper.cxx:64
CaloCell_ID_FCS::TileExt2
@ TileExt2
Definition: FastCaloSim_CaloCell_ID.h:39
constants.EMB1
int EMB1
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:53
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
CaloClusterStoreHelper::AddContainerWriteHandle
static StatusCode AddContainerWriteHandle(SG::WriteHandle< xAOD::CaloClusterContainer > &clusColl)
Creates a new xAOD::CaloClusterContainer in the given WriteHandle + CaloClusterAuxContainer and recor...
Definition: CaloClusterStoreHelper.cxx:53
SG::Accessor
Helper class to provide type-safe access to aux data.
Definition: Control/AthContainers/AthContainers/Accessor.h:68
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
index
Definition: index.py:1
CaloCell_ID_FCS::TileExt0
@ TileExt0
Definition: FastCaloSim_CaloCell_ID.h:37
CaloCell_ID_FCS::TileBar1
@ TileBar1
Definition: FastCaloSim_CaloCell_ID.h:32
CaloCell_ID_FCS::FCAL1
@ FCAL1
Definition: FastCaloSim_CaloCell_ID.h:41
CaloCell_ID_FCS::HEC2
@ HEC2
Definition: FastCaloSim_CaloCell_ID.h:29
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
CaloCell_ID_FCS::TileGap3
@ TileGap3
Definition: FastCaloSim_CaloCell_ID.h:36
DerivationFramework::EGammaCookieCutClusterTool::initialize
StatusCode initialize() override final
Definition: EGammaCookieCutClusterTool.cxx:32
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:62
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:209
CaloCell_ID_FCS::HEC1
@ HEC1
Definition: FastCaloSim_CaloCell_ID.h:28
constants.EMB2
int EMB2
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:54
xAOD::CaloCluster_v1::eta
virtual double eta() const
The pseudorapidity ( ) of the particle.
Definition: CaloCluster_v1.cxx:251
lumiFormat.i
int i
Definition: lumiFormat.py:85
CaloCell_ID_FCS::TileBar0
@ TileBar0
Definition: FastCaloSim_CaloCell_ID.h:31
beamspotman.n
n
Definition: beamspotman.py:727
egammaClusterCookieCut::cookieCut
std::unique_ptr< xAOD::CaloCluster > cookieCut(const xAOD::CaloCluster &cluster, const CaloDetDescrManager &mgr, const DataLink< CaloCellContainer > &cellCont, const egammaClusterCookieCut::CookieCutPars &pars)
Definition: egammaClusterCookieCut.cxx:28
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
SG::WriteHandle::ptr
pointer_type ptr()
Dereference the pointer.
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
CaloCell_ID_FCS::TileGap2
@ TileGap2
Definition: FastCaloSim_CaloCell_ID.h:35
SG::WriteDecorHandle
Handle class for adding a decoration to an object.
Definition: StoreGate/StoreGate/WriteDecorHandle.h:100
EGammaCookieCutClusterTool.h
xAOD::EgammaContainer
EgammaContainer_v1 EgammaContainer
Definition of the current "egamma container version".
Definition: EgammaContainer.h:17
constants.EME1
int EME1
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:55
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
xAOD::CaloCluster_v1::retrieveMoment
bool retrieveMoment(MomentType type, double &value) const
Retrieve individual moment.
Definition: CaloCluster_v1.cxx:662
SG::AuxElement::index
size_t index() const
Return the index of this element within its container.
CaloCell_ID_FCS::TileGap1
@ TileGap1
Definition: FastCaloSim_CaloCell_ID.h:34
xAOD::CaloCluster_v1::getCellLinks
const CaloClusterCellLink * getCellLinks() const
Get a pointer to the CaloClusterCellLink object (const version)
Definition: CaloCluster_v1.cxx:829
xAOD::CaloCluster_v1::pt
virtual double pt() const
The transverse momentum ( ) of the particle (negative for negative-energy clusters)
Definition: CaloCluster_v1.cxx:247
WriteCellNoiseToCool.nF
nF
Definition: WriteCellNoiseToCool.py:541
CaloCell_ID_FCS::TileExt1
@ TileExt1
Definition: FastCaloSim_CaloCell_ID.h:38
CaloCell_ID_FCS::EME3
@ EME3
Definition: FastCaloSim_CaloCell_ID.h:26
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
DerivationFramework::EGammaCookieCutClusterTool::EGammaCookieCutClusterTool
EGammaCookieCutClusterTool(const std::string &t, const std::string &n, const IInterface *p)
Definition: EGammaCookieCutClusterTool.cxx:21
CaloCellContainer.h
CaloCell_ID_FCS::HEC0
@ HEC0
Definition: FastCaloSim_CaloCell_ID.h:27
CaloClusterStoreHelper.h
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
xAOD::CaloCluster_v1::eSample
float eSample(const CaloSample sampling) const
Definition: CaloCluster_v1.cxx:514
CaloDetDescrManager
This class provides the client interface for accessing the detector description information common to...
Definition: CaloDetDescrManager.h:473
DerivationFramework::EGammaCookieCutClusterTool::addBranches
virtual StatusCode addBranches(const EventContext &ctx) const override final
Definition: EGammaCookieCutClusterTool.cxx:86
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
CaloCell_ID_FCS::PreSamplerE
@ PreSamplerE
Definition: FastCaloSim_CaloCell_ID.h:23
CaloCell_ID_FCS::PreSamplerB
@ PreSamplerB
Definition: FastCaloSim_CaloCell_ID.h:19
DEBUG
#define DEBUG
Definition: page_access.h:11
xAOD::EgammaParameters::electron
@ electron
Definition: EgammaEnums.h:18
python.SystemOfUnits.s
float s
Definition: SystemOfUnits.py:147
CaloCell_ID_FCS::FCAL2
@ FCAL2
Definition: FastCaloSim_CaloCell_ID.h:42
xAOD::CaloCluster_v1::hasSampling
bool hasSampling(const CaloSample s) const
Checks if certain smapling contributes to cluster.
Definition: CaloCluster_v1.h:882
CaloCell_ID_FCS::HEC3
@ HEC3
Definition: FastCaloSim_CaloCell_ID.h:30
CaloCell_ID_FCS::FCAL0
@ FCAL0
Definition: FastCaloSim_CaloCell_ID.h:40
CaloCell_ID_FCS::EMB3
@ EMB3
Definition: FastCaloSim_CaloCell_ID.h:22
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
CaloCell_ID_FCS::TileBar2
@ TileBar2
Definition: FastCaloSim_CaloCell_ID.h:33
constants.EME2
int EME2
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:56
python.SystemOfUnits.m
float m
Definition: SystemOfUnits.py:106
python.LArMinBiasAlgConfig.float
float
Definition: LArMinBiasAlgConfig.py:65
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37