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  const EventContext& ctx = Gaudi::Hive::currentContext();
89 
90  // For debug
91  static const std::vector<CaloSampling::CaloSample> s_sam
102 
103  // Create the relevant cluster output and register it.
105  m_outClusterContainerKey,
106  ctx
107  );
109 
110  SG::WriteHandle<CaloClusterCellLinkContainer> outClusterContainerCellLink(
111  m_outClusterContainerCellLinkKey,
112  ctx
113  );
114  ATH_CHECK(outClusterContainerCellLink.record(
115  std::make_unique<CaloClusterCellLinkContainer>())
116  );
117 
118  // Retrieve electron container
120  ctx);
121  const std::size_t nF = electronContainer.ptr()->size();
122  if (nF == 0) {
123  return StatusCode::SUCCESS;
124  }
125 
126  std::vector<SG::WriteDecorHandle<xAOD::EgammaContainer, float>> decoM;
127  decoM.reserve(m_nDecor);
128  for (int i = 0; i < m_nDecor - 1; i++) {
129  decoM.emplace_back(m_SGKey_electrons_decorations[i], ctx);
130  }
131 
132  if (msgLevel(MSG::DEBUG)) {
133  std::call_once(m_Seen, [this,&decoM]() {
134  for (int i = 0; i < m_nDecor - 1; i++) {
135  ATH_MSG_DEBUG("Decor " << i << " out of " << m_nDecor
136  << " " << m_SGKey_electrons_decorations[i].key()
137  << " " << decoM[i].decorKey());
138  }
139  });
140  }
143  decoEl(m_SGKey_electrons_decorations[m_nDecor-1],ctx);
144 
145  // Calorimeter description.
146  SG::ReadCondHandle<CaloDetDescrManager> caloDetDescrMgrHandle{
147  m_caloDetDescrMgrKey, ctx
148  };
149  ATH_CHECK(caloDetDescrMgrHandle.isValid());
150  const CaloDetDescrManager* calodetdescrmgr = *caloDetDescrMgrHandle;
151 
152  // Decorate electrons
153  int iel = 0;
154  std::vector<bool> success(nF,true);
155  ATH_MSG_VERBOSE("Will analyze " << nF << " forward electrons");
156  for (const auto* electron : *electronContainer.ptr()) {
157 
158  const xAOD::CaloCluster *cluster = electron->caloCluster();
159  ATH_MSG_DEBUG("Electron " << electron->index() << " cluster"
160  << " pT = " << cluster->pt()
161  << " eta = " << cluster->eta());
162 
163  const DataLink<CaloCellContainer>& cellCont =
164  cluster->getCellLinks()->getCellContainerLink();
165 
166  std::unique_ptr<xAOD::CaloCluster> newCluster =
167  egammaClusterCookieCut::cookieCut(*cluster, *calodetdescrmgr,
168  cellCont, m_CookieCutPars);
169 
170  if (!newCluster || newCluster->getCellLinks()->size() == 0) {
171  ATH_MSG_DEBUG("No able to build a new cluster for electron "
172  << electron->index()
173  << " pT = " << electron->pt()
174  << " eta = " << electron->eta()
175  << " original cluster " << cluster->index()
176  << " pT = " << cluster->pt()
177  << " eta = " << cluster->eta()
178  << " has EME2 or FCAL0"
179  << " " << cluster->hasSampling(CaloSampling::EME2)
180  << " " << cluster->hasSampling(CaloSampling::FCAL0)
181  << " reason : "
182  << (newCluster ? " no cells in cluster" : " no cluster"));
183  if (!newCluster) {
184  ATH_MSG_VERBOSE("Energies in various samplings :");
185  for (auto s : s_sam)
186  ATH_MSG_VERBOSE("Sampling " << s << " E = " << cluster->eSample(s));
187  }
189  success[iel] = false;
190  }
191 
192  if (success[iel]) {
193  if (newCluster) {
194  ATH_MSG_DEBUG("Cookie cut cluster"
195  << " pT = " << newCluster->pt()
196  << " eta = " << newCluster->eta());
197  }
198  outClusterContainer->push_back(std::move(newCluster));
199  size_t index = outClusterContainer->size() - 1;
201  clusterLink(*outClusterContainer, index, ctx);
202  // Now decorate the electron with the link to cookie cut cluster
203  decoEl(*electron) = clusterLink;
204  }
205 
206  // Eventually decorate the electron with the original moment
207  if (m_storeOrigMom) {
208  for (size_t i = 0; i < m_vecM.size(); i++) {
209  int indexDecor = m_storeCookMom ? 2*i+1 : i;
210  double m = 0.;
211  bool gotM = cluster->retrieveMoment(m_vecM.at(i), m);
212  if (!gotM) {
213  ATH_MSG_VERBOSE(m_vecMName[i]
214  << " does not exist for the original cluster");
215  }
216  decoM[indexDecor](*electron) = float(m);
217  ATH_MSG_VERBOSE("Decorated electron " << electron->index()
218  << " with original moment "
219  << i << " " << m_vecMName[i]
220  << " = " << m << " (decoration index =" << indexDecor
221  << " key = " << decoM[indexDecor].decorKey() << ")");
222  }
223  }
224  iel++;
225  }
226 
227  if (!m_clusterCorrectionTools.empty()) {
228  ToolHandleArray<CaloClusterCollectionProcessor>::const_iterator
229  toolIt = m_clusterCorrectionTools.begin(),
230  toolIt_e = m_clusterCorrectionTools.end();
231  for (; toolIt != toolIt_e; ++toolIt) {
232  ATH_CHECK((*toolIt)->execute(ctx, outClusterContainer.ptr()));
233  }
234 
235  if (m_storeCookMom) {
236  static const SG::AuxElement::Accessor<
238  cookClusLinkAcc( "cookiecutClusterLink" );
239  iel = 0;
240  for (const auto* electron : *electronContainer.ptr()) {
241  const xAOD::CaloCluster *cluster = nullptr;
242  if (success[iel] && cookClusLinkAcc.isAvailable(*electron)) {
244  cookClusLinkAcc(*electron);
245  if (link.isValid()) {
246  cluster = *link;
247  }
248  }
249  if (success[iel] && cluster == nullptr) {
250  ATH_MSG_WARNING("CookieCut cluster was build successfully, but"
251  "could not be retrieved");
252  }
253 
254  for (size_t i = 0; i < m_vecM.size(); i++) {
255  int indexDecor = m_storeOrigMom ? 2*i : i;
256  double m = 0.;
257  if (cluster) {
258  bool gotM = cluster->retrieveMoment(m_vecM.at(i), m);
259  if (!gotM) {
260  ATH_MSG_VERBOSE(m_vecMName[i]
261  << " does not exist for the new cluster");
262  }
263  }
264  decoM[indexDecor](*electron) = float(m);
265  ATH_MSG_VERBOSE("Decorated electron " << electron->index()
266  << " with new moment "
267  << i << " " << m_vecMName[i]
268  << " = " << m << " (decoration index = " << indexDecor
269  << " key = " << decoM[indexDecor].decorKey() << ")");
270  }
271  }
272  }
273  }
274 
276  ctx,
277  outClusterContainer,
278  outClusterContainerCellLink);
279 
280  ATH_MSG_DEBUG("Built " << outClusterContainer.ptr()->size()
281  << " cookie cut clusters");
282 
283  return StatusCode::SUCCESS;
284 }
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
DerivationFramework::EGammaCookieCutClusterTool::addBranches
virtual StatusCode addBranches() const override final
Definition: EGammaCookieCutClusterTool.cxx:86
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:692
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:859
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
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