ATLAS Offline Software
Loading...
Searching...
No Matches
eflowCellSubtractionFacilitator.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Athena Headers
7//#include "eflowCellPosition.h"
8
10#include "CaloEvent/CaloCell.h"
11#include "GaudiKernel/Bootstrap.h"
12#include "GaudiKernel/IMessageSvc.h"
13#include "GaudiKernel/ISvcLocator.h"
15
16// C++ Headers
17#include <map>
18
22
23double
25 eflowRingSubtractionManager& cellSubtractionManager,
26 eflowRecTrack& theTrack,
27 xAOD::CaloCluster* tracksCluster,
28 eflowCellList& orderedCells,
29 bool& annFlag, bool addCPData) const
30{
31 std::vector<std::pair<xAOD::CaloCluster*, bool>> localClusterBoolPairVec(
32 1, std::pair(tracksCluster, false));
33 return subtractCells(
34 cellSubtractionManager, theTrack, localClusterBoolPairVec, orderedCells, annFlag, addCPData);
35}
36
37void
39 std::vector<std::pair<xAOD::CaloCluster*, bool>>& tracksClusters)
40{
41 for (auto& thisPair : tracksClusters)
42 updateClusterKinematics(thisPair.first);
43}
44
45void
47 xAOD::CaloCluster* theCluster)
48{
49 float oldEnergy = theCluster->e();
50 CaloClusterKineHelper::calculateKine(theCluster, true, true);
51 if (0.0 != oldEnergy) {
52 float energyAdjustment = theCluster->e() / oldEnergy;
53 theCluster->setRawE(theCluster->rawE() * energyAdjustment);
54 theCluster->setRawEta(theCluster->eta());
55 theCluster->setRawPhi(theCluster->phi());
56 }
57}
58
59double
61 const std::vector<std::pair<xAOD::CaloCluster*, bool>>& tracksClusters)
62{
63 double eClustersOld = 0;
64 /* Summed energy of all clusters before subtraction */
65 for (auto& thisPair : tracksClusters)
66 eClustersOld += (thisPair.first)->e();
67 return eClustersOld;
68}
69
70double
72 std::vector<std::pair<xAOD::CaloCluster*, bool>>& tracksClusters,
73 CellIt beginRing,
74 CellIt endRing)
75{
76 /* Get total energy of ringes from beginRing to endRing */
77
78 double eRing(0.0);
79 for (CellIt it = beginRing; it != endRing; ++it) {
80 /* Loop over Rings */
81 for (const std::pair<const CaloCell*, int>& thisPair : it->second) {
82 /* Loop over Cells */
83 xAOD::CaloCluster* clus = tracksClusters[thisPair.second].first;
86 double cellWeight = theIterator.weight();
87 eRing += thisPair.first->energy() * cellWeight;
88 }
89 }
90
91 return eRing;
92}
93
94void
96 std::vector<std::pair<xAOD::CaloCluster*, bool>>& tracksClusters, bool& annFlag,
97 eflowRecTrack& theTrack, bool addCPData)
98{
99 for (auto& thisPair : tracksClusters) {
100 xAOD::CaloCluster* thisCluster = thisPair.first;
101 CaloClusterCellLink* theCellLink = thisCluster->getOwnCellLinks();
102 CaloClusterCellLink::iterator theFirstCell = theCellLink->begin();
103 CaloClusterCellLink::iterator theLastCell = theCellLink->end();
104
105 //We don't advance the iterator, theCell, because we call removeCell. This avoids issues with
106 //invalid iterators that would otherwise occur and cause only a subset of cells to be processed.
107 //We also have to reset the lastCell iterator after each call to ensure the loop exits at the end,
108 //instead of being stuck in an infinite loop.
109 for (; theFirstCell != theLastCell;){
110 if (addCPData) theTrack.addSubtractedCaloCell(ElementLink<CaloCellContainer>("AllCalo",theFirstCell.index()),theFirstCell.weight());
111 thisCluster->removeCell(*theFirstCell);
112 theLastCell = theCellLink->end();
113 }
114 thisCluster->setCalE(0.0);
115 thisCluster->setRawE(0.0);
116 // set the subtracted status to true
117 thisPair.second = true;
118 }
119 annFlag = true;
120}
121
122void
124 std::vector<std::pair<xAOD::CaloCluster*, bool>>& tracksClusters,
125 CellIt beginRing,
126 CellIt endRing,
127 double targetRingEnergy,
128 double eRings, eflowRecTrack& theTrack,
129 bool addCPData) const
130{
131 for (CellIt itRing = beginRing; itRing != endRing; ++itRing) {
132 /* Loop over Rings */
133 for (const std::pair<const CaloCell*, int>& thisPair : itRing->second) {
134 /* Loop over Cells */
135 xAOD::CaloCluster* cluster = tracksClusters[thisPair.second].first;
136 // flag this cluster as having had subtraction applied to it
137 tracksClusters[thisPair.second].second = true;
138 const CaloCell* cell = thisPair.first;
141 double oldCellWeight = theIterator.weight();
142 double ringWeight = targetRingEnergy / eRings;
143 const double newCellWeight = oldCellWeight * ringWeight;
144 ATH_MSG_DEBUG("eflowCellSubtractionFacilitator: Cluster with e "
145 << cluster->e()
146 << " is changing weight of cell with energy " << cell->e()
147 << " from " << oldCellWeight << " to " << newCellWeight);
148 theIterator.reweight(newCellWeight);
149 if (addCPData) theTrack.addSubtractedCaloCell(ElementLink<CaloCellContainer>("AllCalo",theIterator.index()),newCellWeight);
150 }
151 }
152}
153
154void
156 std::vector<std::pair<xAOD::CaloCluster*, bool>>& tracksClusters,
157 CellIt beginRing,
158 CellIt endRing, eflowRecTrack& theTrack,
159 bool addCPData) const
160{
161 /* Subtract full ring */
162
163 for (CellIt itRing = beginRing; itRing != endRing; ++itRing) {
164 /* Loop over Rings */
165 for (const std::pair<const CaloCell*, int>& thisPair : itRing->second) {
166 /* Loop over Cells */
167 xAOD::CaloCluster* cluster = tracksClusters[thisPair.second].first;
168 // flag this cluster as having had subtraction applied to it
169 tracksClusters[thisPair.second].second = true;
170 ATH_MSG_DEBUG("eflowCellSubtractionFacilitator: Cluster with e "
171 << cluster->e() << " is removing cell with e "
172 << thisPair.first->e());
173 CaloClusterCellLink::iterator theIterator = this->getCellIterator(cluster, thisPair.first);
174 if (addCPData) theTrack.addSubtractedCaloCell(ElementLink<CaloCellContainer>("AllCalo",theIterator.index()),theIterator.weight());
175 cluster->removeCell(thisPair.first);
176 }
177 }
178}
179
180bool
182 eflowRingSubtractionManager& cellSubtractionManager,
183 const std::pair<eflowCaloENUM, short>& ring,
184 double& eSubtracted,
185 const double eExpect,
186 eflowCellList& orderedCells,
187 std::vector<std::pair<xAOD::CaloCluster*, bool>>& tracksClusters,
188 bool& annFlag, eflowRecTrack& theTrack,
189 bool addCPData ) const
190{
191 /* Subtract energy from ring, return TRUE if the whole expected energy is
192 * subtracted */
193
194 const eflowCaloENUM subtLayer = ring.first;
195 const short ringNo = ring.second;
196
197 const double r1 = ringNo * cellSubtractionManager.ringThickness(subtLayer);
198 const double r2 =
199 (ringNo + 1) * cellSubtractionManager.ringThickness(subtLayer);
200
201 CellIt beginRing = orderedCells.getLowerBound(subtLayer, r1);
202 CellIt endRing = orderedCells.getLowerBound(subtLayer, r2);
203
204 /* Get total energy of Rings from beginRing to endRing */
205 double eRings = getRingsEnergy(tracksClusters, beginRing, endRing);
206
207 if (eSubtracted + eRings > eExpect) {
208 /* Subtract partial ring */
209
210 ATH_MSG_DEBUG("eflowCellSubtractionFacilitator: Subtracting partial ring, "
211 "eSubtracted, eRings and eExpect are "
212 << eSubtracted << ", " << eRings << ", " << eExpect);
213
214 /* Target ring energy is ring energy minus the energy that still needs to be
215 * subtracted */
216 double targetRingEnergy = eRings - (eExpect - eSubtracted);
217 ATH_MSG_DEBUG("eflowCellSubtractionFacilitator: targetRingEnergy is "
218 << targetRingEnergy);
220 tracksClusters, beginRing, endRing, targetRingEnergy, eRings, theTrack, addCPData);
221 eSubtracted = eExpect;
222
223 /* Update the cluster four-momenta having done the subtraction */
224 updateClusterKinematics(tracksClusters);
225
226 return true;
227
228 } else {
229 /* Subtract full ring */
230
231 ATH_MSG_DEBUG("eflowCellSubtractionFacilitator: Subtracting full ring ");
232
233 subtractFullRings(tracksClusters, beginRing, endRing, theTrack, addCPData);
234 orderedCells.deleteFromList(beginRing, endRing);
235 eSubtracted += eRings;
236
237 /* If no energy left */
238 double eClustersOld = getTotalEnergy(tracksClusters);
239 if (std::fabs(eClustersOld - eSubtracted) < 1.0e-6 * eClustersOld) {
240 /* Annihilate clusters, clear orderedCells, and update subtracted cluster
241 * kinematics */
242 annihilateClusters(tracksClusters,annFlag, theTrack, addCPData);
243 orderedCells.eraseList();
244 updateClusterKinematics(tracksClusters);
245
246 return true;
247 }
248
249 return false;
250 }
251}
252
253bool
255 const double eExpect,
256 xAOD::CaloCluster* cluster,
257 const CaloCell* cell,
258 eflowRecTrack& theTrack,
259 bool addCPData)
260{
261
264 double oldCellWeight = theIterator.weight();
265 double oldCellEnergy = cell->energy() * oldCellWeight;
266
267 if (oldCellEnergy != 0. && eSubtracted + oldCellEnergy > eExpect) {
268 /* Target cell energy is cell energy minus the energy that still needs to be
269 * subtracted */
270 double targetCellEnergy = oldCellEnergy - (eExpect - eSubtracted);
271
272 double energyWeight = targetCellEnergy / oldCellEnergy;
273 double newCellWeight = oldCellWeight * energyWeight;
274 theIterator.reweight(newCellWeight);
275 if (addCPData) theTrack.addSubtractedCaloCell(ElementLink<CaloCellContainer>("AllCalo",theIterator.index()), energyWeight*theIterator.weight());
276
277 eSubtracted = eExpect;
278
279 /* Update the cluster four-momenta having done the subtraction */
281
282 return true;
283
284 } else {
285 if (addCPData) theTrack.addSubtractedCaloCell(ElementLink<CaloCellContainer>("AllCalo",theIterator.index()),theIterator.weight());
286 cluster->removeCell(cell);
287 eSubtracted += oldCellEnergy;
288
289 /* Update the clusters having done the subtraction */
291 return false;
292 }
293}
294
295bool
297 std::vector<std::pair<xAOD::CaloCluster*, bool>>& tracksClusters,
298 double eSubtracted,
299 const double eExpect,
300 eflowCellList& reorderedCells,
301 eflowRecTrack& theTrack,
302 bool addCPData)
303{
304 CellIt itCellPosition = reorderedCells.begin();
305 CellIt endCellPosition = reorderedCells.end();
306 while (itCellPosition != endCellPosition) {
307 /* Loop cells */
308 std::vector<std::pair<const CaloCell*, int>>::iterator itEntry =
309 itCellPosition->second.begin();
310 std::vector<std::pair<const CaloCell*, int>>::iterator endEntry =
311 itCellPosition->second.end();
312 for (; itEntry != endEntry; ++itEntry) {
313 const std::pair<const CaloCell*, int> thisPair = *itEntry;
314 xAOD::CaloCluster* cluster = tracksClusters[thisPair.second].first;
315 // flag this cluster as having had subtraction applied to it
316 tracksClusters[thisPair.second].second = true;
317 const CaloCell* cell = thisPair.first;
318 bool isFinished = subtractCaloCell(eSubtracted, eExpect, cluster, cell, theTrack, addCPData);
319 if (isFinished)
320 return true;
321 }
322 /* Erase the CellPosition from the cell list */
323 CellIt tmp = itCellPosition;
324 ++itCellPosition;
325 reorderedCells.deleteFromList(tmp);
326 }
327 return false;
328}
329
330double
332 eflowRingSubtractionManager& cellSubtractionManager,
333 eflowRecTrack& theTrack,
334 std::vector<std::pair<xAOD::CaloCluster*, bool>>& tracksClusters,
335 eflowCellList& orderedCells,
336 bool& annFlag, bool addCPData) const
337{
338
339 const double trackEnergy = theTrack.getTrack()->e();
340 const double eExpect = cellSubtractionManager.fudgeMean() * trackEnergy;
341 const double sigmaEExpect =
342 cellSubtractionManager.fudgeStdDev() * trackEnergy;
343 ATH_MSG_DEBUG("eflowCellSubtractionFacilitator: For track with trackEnergy "
344 << trackEnergy << " expect to subtract " << eExpect
345 << " with width of " << sigmaEExpect);
346
347 double eSubtracted = 0.0;
348
349 /*
350 * Ring subtraction
351 */
352 std::map<double, RingId>::const_iterator ringIt =
353 cellSubtractionManager.rankBegin();
354 std::map<double, RingId>::const_iterator ringEnd =
355 cellSubtractionManager.rankEnd();
356 for (; ringIt != ringEnd; ++ringIt) {
357 bool isFinished = subtractRings(cellSubtractionManager,
358 ringIt->second,
359 eSubtracted,
360 eExpect,
361 orderedCells,
362 tracksClusters,
363 annFlag,
364 theTrack,
365 addCPData);
366 if (isFinished) {
367 return sigmaEExpect;
368 }
369 }
370
371 /* Update the cluster four-momenta */
372 updateClusterKinematics(tracksClusters);
373
374 if (orderedCells.mapSize() <= 0 || eSubtracted >= eExpect) {
375 return sigmaEExpect;
376 }
377
378 /*
379 * Cell subtraction
380 */
381 /* Increasing dR (not by layer) for cell subtraction */
382 orderedCells.reorderWithoutLayers();
383
384 bool isFinished =
385 subtractReorderedCells(tracksClusters, eSubtracted, eExpect, orderedCells, theTrack, addCPData);
386 if (isFinished) {
387 return sigmaEExpect;
388 }
389
390 /* Update the cluster four-momenta */
391 updateClusterKinematics(tracksClusters);
392
393 return sigmaEExpect;
394}
395
398 xAOD::CaloCluster* thisCluster,
399 const CaloCell* thisCell)
400{
401
402 // SLOW! Can we move to directly work with iterators in future?
403
404 // We have to use non-const iterators so that we are allowed to modify the
405 // cell weights
406 CaloClusterCellLink* theCells = thisCluster->getOwnCellLinks();
407
408 CaloClusterCellLink::iterator itCell = theCells->begin();
409 CaloClusterCellLink::iterator endCell = theCells->end();
410 for (; itCell != endCell; ++itCell) {
411 const CaloCell* pCell = (*itCell);
412 if (pCell == thisCell) { // Pointer comparison!
413 return itCell;
414 }
415 }
416
417 // if no match is found then return end of container
418 return endCell;
419}
#define ATH_MSG_DEBUG(x)
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
static void calculateKine(xAOD::CaloCluster *clu, const bool useweight=true, const bool updateLayers=true, const bool useGPUCriteria=false)
Helper class to calculate cluster kinematics based on cells.
AsgMessaging(const std::string &name)
Constructor with a name.
Concrete class derived class from pure virtual eflowAbstractCellList.
CellIt getLowerBound(eflowCaloENUM layer, double r)
void reorderWithoutLayers()
void deleteFromList(CellIt &start, CellIt &end)
bool subtractRings(eflowRingSubtractionManager &ringSubtractionManager, const std::pair< eflowCaloENUM, short > &ring, double &eSubtracted, const double eExpect, eflowCellList &orderedCells, std::vector< std::pair< xAOD::CaloCluster *, bool > > &tracksClusters, bool &annFlag, eflowRecTrack &theTrack, bool addCPData) const
static void updateClusterKinematics(std::vector< std::pair< xAOD::CaloCluster *, bool > > &tracksClusters)
double subtractCells(eflowRingSubtractionManager &ringSubtractionManager, eflowRecTrack &theTrack, xAOD::CaloCluster *tracksClus, eflowCellList &orderedCells, bool &annFlag, bool addCPData) const
static bool subtractCaloCell(double &eSubtracted, const double eExpect, xAOD::CaloCluster *cluster, const CaloCell *cell, eflowRecTrack &theTrack, bool addCPData)
void subtractPartialRings(std::vector< std::pair< xAOD::CaloCluster *, bool > > &tracksClusters, CellIt beginRing, CellIt endRing, double targetRingEnergy, double eRing, eflowRecTrack &theTrack, bool addCPData) const
static CaloClusterCellLink::iterator getCellIterator(xAOD::CaloCluster *thisCluster, const CaloCell *thisCell)
static double getRingsEnergy(std::vector< std::pair< xAOD::CaloCluster *, bool > > &tracksClusters, CellIt beginRing, CellIt endRing)
static bool subtractReorderedCells(std::vector< std::pair< xAOD::CaloCluster *, bool > > &tracksClusters, double eSubtracted, const double eExpect, eflowCellList &orderedCells, eflowRecTrack &theTrack, bool addCPData)
void subtractFullRings(std::vector< std::pair< xAOD::CaloCluster *, bool > > &tracksClusters, CellIt beginRing, CellIt endRing, eflowRecTrack &theTrack, bool addCPData) const
static double getTotalEnergy(const std::vector< std::pair< xAOD::CaloCluster *, bool > > &tracksClusters)
static void annihilateClusters(std::vector< std::pair< xAOD::CaloCluster *, bool > > &tracksClusters, bool &annFlag, eflowRecTrack &theTrack, bool addCPData)
This class extends the information about a xAOD::Track.
const xAOD::TrackParticle * getTrack() const
void addSubtractedCaloCell(ElementLink< CaloCellContainer > theCellLink, const double &weight)
This stores information, a rank and ring thickness, about cell rings in an ordered way.
std::map< double, RingId >::const_iterator rankBegin() const
std::map< double, RingId >::const_iterator rankEnd() const
double ringThickness(eflowCaloENUM layer) const
void setRawEta(flt_t)
Set for signal state UNCALIBRATED.
flt_t rawE() const
void setRawPhi(flt_t)
Set for signal state UNCALIBRATED.
void setRawE(flt_t)
Set Energy for signal state UNCALIBRATED.
virtual double eta() const
The pseudorapidity ( ) of the particle.
virtual double e() const
The total energy of the particle.
virtual double phi() const
The azimuthal angle ( ) of the particle.
CaloClusterCellLink * getOwnCellLinks()
Get a pointer to the owned CaloClusterCellLink object (non-const version).
void setCalE(flt_t)
Set Energy for signal state CALIBRATED.
bool removeCell(const CaloCell *ptr)
Method to remove a cell to the cluster (slow!) (Beware: Kinematics not updated!).
virtual double e() const override final
The total energy of the particle.
std::map< eflowCellPosition, std::vector< std::pair< constCaloCell *, int > > >::iterator CellIt
eflowCalo::LAYER eflowCaloENUM
singleton-like access to IMessageSvc via open function and helper
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.