ATLAS Offline Software
Loading...
Searching...
No Matches
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
5// Decorate egamma objects with cluster moments from a cookie-cut cluster
6
8
11
13
14namespace {
15 constexpr float cellEtaSize = 0.1;
16 constexpr float cellPhiSize = 0.1;
17}
18
19// Athena initialize
20StatusCode
22{
23 ATH_MSG_VERBOSE("initialize() ...");
24
25 ATH_CHECK(m_caloDetDescrMgrKey.initialize());
26
27 ATH_MSG_DEBUG("Will store cookie cut clusters in this container "
31
32 ATH_MSG_DEBUG("Using " << m_SGKey_electrons << " for electrons");
33 ATH_CHECK(m_SGKey_electrons.initialize());
34
36 ATH_MSG_DEBUG("Initialize nDecor = " << m_nDecor);
38 if (msgLvl(MSG::DEBUG)) {
39 ATH_MSG_DEBUG("Decorations for " << m_SGKey_electrons.key());
40 for (const auto& s : m_SGKey_electrons_decorations)
41 { ATH_MSG_DEBUG(s.key()); }
42 }
43
44 m_CookieCutPars.maxDelEta = m_maxDelEtaCells * cellEtaSize * 0.5;
45 m_CookieCutPars.maxDelPhi = m_maxDelPhiCells * cellPhiSize * 0.5;
47 m_CookieCutPars.fixCellWeights = m_fixCellWeights;
48
49 // Retrieve cluster moment maker in case we cookie cut and want to recompute
50 if (!m_clusterCorrectionTools.empty()) {
52 m_CookieCutPars.recomputeMoments = true;
53 }
54
55 return StatusCode::SUCCESS;
56}
57
58// The decoration itself
59StatusCode
61{
62
63 // For debug
64 static const std::vector<CaloSampling::CaloSample> s_sam
65 { CaloSampling::PreSamplerB, CaloSampling::EMB1,
66 CaloSampling::EMB2, CaloSampling::EMB3,
67 CaloSampling::PreSamplerE, CaloSampling::EME1,
68 CaloSampling::EME2, CaloSampling::EME3,
69 CaloSampling::TileBar0, CaloSampling::TileBar1, CaloSampling::TileBar2,
70 CaloSampling::TileExt0, CaloSampling::TileExt1, CaloSampling::TileExt2,
71 CaloSampling::TileGap1, CaloSampling::TileGap2, CaloSampling::TileGap3,
72 CaloSampling::HEC0, CaloSampling::HEC1,
73 CaloSampling::HEC2, CaloSampling::HEC3,
74 CaloSampling::FCAL0, CaloSampling::FCAL1, CaloSampling::FCAL2 };
75
76 // Create the relevant cluster output and register it.
79 ctx
80 );
82
83 SG::WriteHandle<CaloClusterCellLinkContainer> outClusterContainerCellLink(
85 ctx
86 );
87 ATH_CHECK(outClusterContainerCellLink.record(
88 std::make_unique<CaloClusterCellLinkContainer>())
89 );
90
91 // Retrieve electron container
93 ctx);
94 const std::size_t nF = electronContainer.ptr()->size();
95 if (nF == 0) {
96 return StatusCode::SUCCESS;
97 }
98
99 std::vector<SG::WriteDecorHandle<xAOD::EgammaContainer, float>> decoM;
100 decoM.reserve(m_nDecor);
101 for (int i = 0; i < m_nDecor - 1; i++) {
102 decoM.emplace_back(m_SGKey_electrons_decorations[i], ctx);
103 }
104
105 if (msgLevel(MSG::DEBUG)) {
106 std::call_once(m_Seen, [this,&decoM]() {
107 for (int i = 0; i < m_nDecor - 1; i++) {
108 ATH_MSG_DEBUG("Decor " << i << " out of " << m_nDecor
109 << " " << m_SGKey_electrons_decorations[i].key()
110 << " " << decoM[i].decorKey());
111 }
112 });
113 }
117
118 // Calorimeter description.
119 SG::ReadCondHandle<CaloDetDescrManager> caloDetDescrMgrHandle{
121 };
122 ATH_CHECK(caloDetDescrMgrHandle.isValid());
123 const CaloDetDescrManager* calodetdescrmgr = *caloDetDescrMgrHandle;
124
125 // Decorate electrons
126 int iel = 0;
127 std::vector<bool> success(nF,true);
128 ATH_MSG_VERBOSE("Will analyze " << nF << " forward electrons");
129 for (const auto* electron : *electronContainer.ptr()) {
130
131 const xAOD::CaloCluster *cluster = electron->caloCluster();
132 ATH_MSG_DEBUG("Electron " << electron->index() << " cluster"
133 << " pT = " << cluster->pt()
134 << " eta = " << cluster->eta());
135
136 const DataLink<CaloCellContainer>& cellCont =
138
139 std::unique_ptr<xAOD::CaloCluster> newCluster =
140 egammaClusterCookieCut::cookieCut(*cluster, *calodetdescrmgr,
141 cellCont, m_CookieCutPars);
142
143 if (!newCluster || newCluster->getCellLinks()->size() == 0) {
144 ATH_MSG_DEBUG("No able to build a new cluster for electron "
145 << electron->index()
146 << " pT = " << electron->pt()
147 << " eta = " << electron->eta()
148 << " original cluster " << cluster->index()
149 << " pT = " << cluster->pt()
150 << " eta = " << cluster->eta()
151 << " has EME2 or FCAL0"
152 << " " << cluster->hasSampling(CaloSampling::EME2)
153 << " " << cluster->hasSampling(CaloSampling::FCAL0)
154 << " reason : "
155 << (newCluster ? " no cells in cluster" : " no cluster"));
156 if (!newCluster) {
157 ATH_MSG_VERBOSE("Energies in various samplings :");
158 for (auto s : s_sam)
159 ATH_MSG_VERBOSE("Sampling " << s << " E = " << cluster->eSample(s));
160 }
161 decoEl(*electron) = ElementLink<xAOD::CaloClusterContainer>();
162 success[iel] = false;
163 }
164
165 if (success[iel]) {
166 if (newCluster) {
167 ATH_MSG_DEBUG("Cookie cut cluster"
168 << " pT = " << newCluster->pt()
169 << " eta = " << newCluster->eta());
170 }
171 outClusterContainer->push_back(std::move(newCluster));
172 size_t index = outClusterContainer->size() - 1;
174 clusterLink(*outClusterContainer, index, ctx);
175 // Now decorate the electron with the link to cookie cut cluster
176 decoEl(*electron) = clusterLink;
177 }
178
179 // Eventually decorate the electron with the original moment
180 if (m_storeOrigMom) {
181 for (size_t i = 0; i < m_vecM.size(); i++) {
182 int indexDecor = m_storeCookMom ? 2*i+1 : i;
183 double m = 0.;
184 bool gotM = cluster->retrieveMoment(
185 static_cast<xAOD::CaloCluster::MomentType>(m_vecM[i]), m);
186 if (!gotM) {
188 << " does not exist for the original cluster");
189 }
190 decoM[indexDecor](*electron) = float(m);
191 ATH_MSG_VERBOSE("Decorated electron " << electron->index()
192 << " with original moment "
193 << i << " " << m_vecMName[i]
194 << " = " << m << " (decoration index =" << indexDecor
195 << " key = " << decoM[indexDecor].decorKey() << ")");
196 }
197 }
198 iel++;
199 }
200
201 if (!m_clusterCorrectionTools.empty()) {
202 ToolHandleArray<CaloClusterCollectionProcessor>::const_iterator
203 toolIt = m_clusterCorrectionTools.begin(),
204 toolIt_e = m_clusterCorrectionTools.end();
205 for (; toolIt != toolIt_e; ++toolIt) {
206 ATH_CHECK((*toolIt)->execute(ctx, outClusterContainer.ptr()));
207 }
208
209 if (m_storeCookMom) {
210 static const SG::AuxElement::Accessor<
212 cookClusLinkAcc( "cookiecutClusterLink" );
213 iel = 0;
214 for (const auto* electron : *electronContainer.ptr()) {
215 const xAOD::CaloCluster *cluster = nullptr;
216 if (success[iel]) {
217 cluster = xAOD::EgammaHelpers::getCluster(electron);
218 }
219 if (success[iel] && cluster == nullptr) {
220 ATH_MSG_WARNING("CookieCut cluster was build successfully, but"
221 "could not be retrieved");
222 }
223
224 for (size_t i = 0; i < m_vecM.size(); i++) {
225 int indexDecor = m_storeOrigMom ? 2*i : i;
226 double m = 0.;
227 if (cluster) {
228 bool gotM = cluster->retrieveMoment(
229 static_cast<xAOD::CaloCluster::MomentType>(m_vecM[i]), m);
230 if (!gotM) {
232 << " does not exist for the new cluster");
233 }
234 }
235 decoM[indexDecor](*electron) = float(m);
236 ATH_MSG_VERBOSE("Decorated electron " << electron->index()
237 << " with new moment "
238 << i << " " << m_vecMName[i]
239 << " = " << m << " (decoration index = " << indexDecor
240 << " key = " << decoM[indexDecor].decorKey() << ")");
241 }
242 iel++;
243 }
244 }
245 }
246
248 ctx,
249 outClusterContainer,
250 outClusterContainerCellLink);
251
252 ATH_MSG_DEBUG("Built " << outClusterContainer.ptr()->size()
253 << " cookie cut clusters");
254
255 return StatusCode::SUCCESS;
256}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
xAOD::ElectronContainer * electronContainer
static StatusCode AddContainerWriteHandle(SG::WriteHandle< xAOD::CaloClusterContainer > &clusColl)
Creates a new xAOD::CaloClusterContainer in the given WriteHandle + CaloClusterAuxContainer and recor...
static StatusCode finalizeClusters(SG::WriteHandle< CaloClusterCellLinkContainer > &h, xAOD::CaloClusterContainer *pClusterColl)
Finalize clusters (move CaloClusterCellLink to a separate container).
This class provides the client interface for accessing the detector description information common to...
ToolHandleArray< CaloClusterCollectionProcessor > m_clusterCorrectionTools
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloDetDescrMgrKey
Calorimeter description.
Gaudi::Property< bool > m_storeOrigMom
Decide whether or not to store input cluster moments.
SG::WriteHandleKey< CaloClusterCellLinkContainer > m_outClusterContainerCellLinkKey
Output cluster container cell links: should match output containter name.
Gaudi::Property< bool > m_fixCellWeights
if true, use cell weights = 1 for cookie-cut cluster
Gaudi::Property< int > m_maxDelEtaCells
Size of maximum search window in eta.
Gaudi::Property< std::vector< std::string > > m_vecMName
Name of the cluster moments to be added.
SG::WriteDecorHandleKeyArray< xAOD::EgammaContainer > m_SGKey_electrons_decorations
SG::ReadHandleKey< xAOD::EgammaContainer > m_SGKey_electrons
Gaudi::Property< int > m_maxDelPhiCells
Size of maximum search window in phi.
egammaClusterCookieCut::CookieCutPars m_CookieCutPars
virtual StatusCode addBranches(const EventContext &ctx) const override final
SG::WriteHandleKey< xAOD::CaloClusterContainer > m_outClusterContainerKey
Output cluster container.
Gaudi::Property< float > m_maxDelR
Size of cone to cookie cut on FCal.
Gaudi::Property< std::vector< int > > m_vecM
The cluster moments to be added.
Gaudi::Property< bool > m_storeCookMom
Decide whether or not to store cooked cluster moments.
SG::Accessor< T, ALLOC > Accessor
Definition AuxElement.h:572
size_t index() const
Return the index of this element within its container.
Handle class for adding a decoration to an object.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
pointer_type ptr()
Dereference the pointer.
bool retrieveMoment(MomentType type, double &value) const
Retrieve individual moment.
const CaloClusterCellLink * getCellLinks() const
Get a pointer to the CaloClusterCellLink object (const version)
virtual double pt() const
The transverse momentum ( ) of the particle (negative for negative-energy clusters)
virtual double eta() const
The pseudorapidity ( ) of the particle.
float eSample(const CaloSample sampling) const
MomentType
Enums to identify different moments.
bool hasSampling(const CaloSample s) const
Checks if certain smapling contributes to cluster.
std::unique_ptr< xAOD::CaloCluster > cookieCut(const xAOD::CaloCluster &cluster, const CaloDetDescrManager &mgr, const DataLink< CaloCellContainer > &cellCont, const egammaClusterCookieCut::CookieCutPars &pars)
Definition index.py:1
const xAOD::CaloCluster * getCluster(const xAOD::Egamma *eg, bool cook=true)
return the associated egamma cluster, that might be cookie-cut cluster (fwd electron)
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
EgammaContainer_v1 EgammaContainer
Definition of the current "egamma container version".