ATLAS Offline Software
Loading...
Searching...
No Matches
eflowCellSubtractionFacilitator.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Athena Headers
7//#include "eflowRec/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, const 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 (auto thisCell : it->second) {
82 /* Loop over Cells */
83 std::pair<const CaloCell*, int> thisPair = thisCell;
84 xAOD::CaloCluster* clus = tracksClusters[thisPair.second].first;
87 double cellWeight = theIterator.weight();
88 eRing += thisPair.first->energy() * cellWeight;
89 }
90 }
91
92 return eRing;
93}
94
95void
97 std::vector<std::pair<xAOD::CaloCluster*, bool>>& tracksClusters, bool& annFlag,
98 eflowRecTrack& theTrack, const bool& addCPData)
99{
100 for (auto& thisPair : tracksClusters) {
101 xAOD::CaloCluster* thisCluster = thisPair.first;
102 CaloClusterCellLink* theCellLink = thisCluster->getOwnCellLinks();
103 CaloClusterCellLink::iterator theFirstCell = theCellLink->begin();
104 CaloClusterCellLink::iterator theLastCell = theCellLink->end();
105
106 //We don't advance the iterator, theCell, because we call removeCell. This avoids issues with
107 //invalid iterators that would otherwise occur and cause only a subset of cells to be processed.
108 //We also have to reset the lastCell iterator after each call to ensure the loop exits at the end,
109 //instead of being stuck in an infinite loop.
110 for (; theFirstCell != theLastCell;){
111 if (addCPData) theTrack.addSubtractedCaloCell(ElementLink<CaloCellContainer>("AllCalo",theFirstCell.index()),theFirstCell.weight());
112 thisCluster->removeCell(*theFirstCell);
113 theLastCell = theCellLink->end();
114 }
115 thisCluster->setCalE(0.0);
116 thisCluster->setRawE(0.0);
117 // set the subtracted status to true
118 thisPair.second = true;
119 }
120 annFlag = true;
121}
122
123void
125 std::vector<std::pair<xAOD::CaloCluster*, bool>>& tracksClusters,
126 CellIt beginRing,
127 CellIt endRing,
128 double targetRingEnergy,
129 double eRings, eflowRecTrack& theTrack,
130 const bool& addCPData) const
131{
132 for (CellIt itRing = beginRing; itRing != endRing; ++itRing) {
133 /* Loop over Rings */
134 for (auto thisCell : itRing->second) {
135 /* Loop over Cells */
136 std::pair<const CaloCell*, int> thisPair = thisCell;
137 xAOD::CaloCluster* cluster = tracksClusters[thisPair.second].first;
138 // flag this cluster as having had subtraction applied to it
139 tracksClusters[thisPair.second].second = true;
140 const CaloCell* cell = thisPair.first;
143 double oldCellWeight = theIterator.weight();
144 double ringWeight = targetRingEnergy / eRings;
145 const double newCellWeight = oldCellWeight * ringWeight;
146 ATH_MSG_DEBUG("eflowCellSubtractionFacilitator: Cluster with e "
147 << cluster->e()
148 << " is changing weight of cell with energy " << cell->e()
149 << " from " << oldCellWeight << " to " << newCellWeight);
150 theIterator.reweight(newCellWeight);
151 if (addCPData) theTrack.addSubtractedCaloCell(ElementLink<CaloCellContainer>("AllCalo",theIterator.index()),newCellWeight);
152 }
153 }
154}
155
156void
158 std::vector<std::pair<xAOD::CaloCluster*, bool>>& tracksClusters,
159 CellIt beginRing,
160 CellIt endRing, eflowRecTrack& theTrack,
161 const bool& addCPData) const
162{
163 /* Subtract full ring */
164
165 for (CellIt itRing = beginRing; itRing != endRing; ++itRing) {
166 /* Loop over Rings */
167 for (auto thisCell : itRing->second) {
168 /* Loop over Cells */
169 std::pair<const CaloCell*, int> thisPair = thisCell;
170 xAOD::CaloCluster* cluster = tracksClusters[thisPair.second].first;
171 // flag this cluster as having had subtraction applied to it
172 tracksClusters[thisPair.second].second = true;
173 ATH_MSG_DEBUG("eflowCellSubtractionFacilitator: Cluster with e "
174 << cluster->e() << " is removing cell with e "
175 << thisPair.first->e());
176 CaloClusterCellLink::iterator theIterator = this->getCellIterator(cluster, thisPair.first);
177 if (addCPData) theTrack.addSubtractedCaloCell(ElementLink<CaloCellContainer>("AllCalo",theIterator.index()),theIterator.weight());
178 cluster->removeCell(thisPair.first);
179 }
180 }
181}
182
183bool
185 eflowRingSubtractionManager& cellSubtractionManager,
186 const std::pair<eflowCaloENUM, short>& ring,
187 double& eSubtracted,
188 const double eExpect,
189 eflowCellList& orderedCells,
190 std::vector<std::pair<xAOD::CaloCluster*, bool>>& tracksClusters,
191 bool& annFlag, eflowRecTrack& theTrack,
192 const bool& addCPData ) const
193{
194 /* Subtract energy from ring, return TRUE if the whole expected energy is
195 * subtracted */
196
197 const eflowCaloENUM subtLayer = ring.first;
198 const short ringNo = ring.second;
199
200 const double r1 = ringNo * cellSubtractionManager.ringThickness(subtLayer);
201 const double r2 =
202 (ringNo + 1) * cellSubtractionManager.ringThickness(subtLayer);
203
204 CellIt beginRing = orderedCells.getLowerBound(subtLayer, r1);
205 CellIt endRing = orderedCells.getLowerBound(subtLayer, r2);
206
207 /* Get total energy of Rings from beginRing to endRing */
208 double eRings = getRingsEnergy(tracksClusters, beginRing, endRing);
209
210 if (eSubtracted + eRings > eExpect) {
211 /* Subtract partial ring */
212
213 ATH_MSG_DEBUG("eflowCellSubtractionFacilitator: Subtracting partial ring, "
214 "eSubtracted, eRings and eExpect are "
215 << eSubtracted << ", " << eRings << ", " << eExpect);
216
217 /* Target ring energy is ring energy minus the energy that still needs to be
218 * subtracted */
219 double targetRingEnergy = eRings - (eExpect - eSubtracted);
220 ATH_MSG_DEBUG("eflowCellSubtractionFacilitator: targetRingEnergy is "
221 << targetRingEnergy);
223 tracksClusters, beginRing, endRing, targetRingEnergy, eRings, theTrack, addCPData);
224 eSubtracted = eExpect;
225
226 /* Update the cluster four-momenta having done the subtraction */
227 updateClusterKinematics(tracksClusters);
228
229 return true;
230
231 } else {
232 /* Subtract full ring */
233
234 ATH_MSG_DEBUG("eflowCellSubtractionFacilitator: Subtracting full ring ");
235
236 subtractFullRings(tracksClusters, beginRing, endRing, theTrack, addCPData);
237 orderedCells.deleteFromList(beginRing, endRing);
238 eSubtracted += eRings;
239
240 /* If no energy left */
241 double eClustersOld = getTotalEnergy(tracksClusters);
242 if (fabs(eClustersOld - eSubtracted) < 1.0e-6 * eClustersOld) {
243 /* Annihilate clusters, clear orderedCells, and update subtracted cluster
244 * kinematics */
245 annihilateClusters(tracksClusters,annFlag, theTrack, addCPData);
246 orderedCells.eraseList();
247 updateClusterKinematics(tracksClusters);
248
249 return true;
250 }
251
252 return false;
253 }
254}
255
256bool
258 const double eExpect,
259 xAOD::CaloCluster* cluster,
260 const CaloCell* cell,
261 eflowRecTrack& theTrack,
262 const bool& addCPData)
263{
264
267 double oldCellWeight = theIterator.weight();
268 double oldCellEnergy = cell->energy() * oldCellWeight;
269
270 if (oldCellEnergy != 0. && eSubtracted + oldCellEnergy > eExpect) {
271 /* Target cell energy is cell energy minus the energy that still needs to be
272 * subtracted */
273 double targetCellEnergy = oldCellEnergy - (eExpect - eSubtracted);
274
275 double energyWeight = targetCellEnergy / oldCellEnergy;
276 double newCellWeight = oldCellWeight * energyWeight;
277 theIterator.reweight(newCellWeight);
278 if (addCPData) theTrack.addSubtractedCaloCell(ElementLink<CaloCellContainer>("AllCalo",theIterator.index()), energyWeight*theIterator.weight());
279
280 eSubtracted = eExpect;
281
282 /* Update the cluster four-momenta having done the subtraction */
284
285 return true;
286
287 } else {
288 if (addCPData) theTrack.addSubtractedCaloCell(ElementLink<CaloCellContainer>("AllCalo",theIterator.index()),theIterator.weight());
289 cluster->removeCell(cell);
290 eSubtracted += oldCellEnergy;
291
292 /* Update the clusters having done the subtraction */
294 return false;
295 }
296}
297
298bool
300 std::vector<std::pair<xAOD::CaloCluster*, bool>>& tracksClusters,
301 double eSubtracted,
302 const double eExpect,
303 eflowCellList& reorderedCells,
304 eflowRecTrack& theTrack,
305 const bool& addCPData)
306{
307 CellIt itCellPosition = reorderedCells.begin();
308 CellIt endCellPosition = reorderedCells.end();
309 while (itCellPosition != endCellPosition) {
310 /* Loop cells */
311 std::vector<std::pair<const CaloCell*, int>>::iterator itEntry =
312 itCellPosition->second.begin();
313 std::vector<std::pair<const CaloCell*, int>>::iterator endEntry =
314 itCellPosition->second.end();
315 for (; itEntry != endEntry; ++itEntry) {
316 const std::pair<const CaloCell*, int> thisPair = *itEntry;
317 xAOD::CaloCluster* cluster = tracksClusters[thisPair.second].first;
318 // flag this cluster as having had subtraction applied to it
319 tracksClusters[thisPair.second].second = true;
320 const CaloCell* cell = thisPair.first;
321 bool isFinished = subtractCaloCell(eSubtracted, eExpect, cluster, cell, theTrack, addCPData);
322 if (isFinished)
323 return true;
324 }
325 /* Erase the CellPosition from the cell list */
326 CellIt tmp = itCellPosition;
327 ++itCellPosition;
328 reorderedCells.deleteFromList(tmp);
329 }
330 return false;
331}
332
333double
335 eflowRingSubtractionManager& cellSubtractionManager,
336 eflowRecTrack& theTrack,
337 std::vector<std::pair<xAOD::CaloCluster*, bool>>& tracksClusters,
338 eflowCellList& orderedCells,
339 bool& annFlag, const bool& addCPData) const
340{
341
342 const double trackEnergy = theTrack.getTrack()->e();
343 const double eExpect = cellSubtractionManager.fudgeMean() * trackEnergy;
344 const double sigmaEExpect =
345 cellSubtractionManager.fudgeStdDev() * trackEnergy;
346 ATH_MSG_DEBUG("eflowCellSubtractionFacilitator: For track with trackEnergy "
347 << trackEnergy << " expect to subtract " << eExpect
348 << " with width of " << sigmaEExpect);
349
350 double eSubtracted = 0.0;
351
352 /*
353 * Ring subtraction
354 */
355 std::map<double, RingId>::const_iterator ringIt =
356 cellSubtractionManager.rankBegin();
357 std::map<double, RingId>::const_iterator ringEnd =
358 cellSubtractionManager.rankEnd();
359 for (; ringIt != ringEnd; ++ringIt) {
360 bool isFinished = subtractRings(cellSubtractionManager,
361 ringIt->second,
362 eSubtracted,
363 eExpect,
364 orderedCells,
365 tracksClusters,
366 annFlag,
367 theTrack,
368 addCPData);
369 if (isFinished) {
370 return sigmaEExpect;
371 }
372 }
373
374 /* Update the cluster four-momenta */
375 updateClusterKinematics(tracksClusters);
376
377 if (orderedCells.mapSize() <= 0 || eSubtracted >= eExpect) {
378 return sigmaEExpect;
379 }
380
381 /*
382 * Cell subtraction
383 */
384 /* Increasing dR (not by layer) for cell subtraction */
385 orderedCells.reorderWithoutLayers();
386
387 bool isFinished =
388 subtractReorderedCells(tracksClusters, eSubtracted, eExpect, orderedCells, theTrack, addCPData);
389 if (isFinished) {
390 return sigmaEExpect;
391 }
392
393 /* Update the cluster four-momenta */
394 updateClusterKinematics(tracksClusters);
395
396 return sigmaEExpect;
397}
398
401 xAOD::CaloCluster* thisCluster,
402 const CaloCell* thisCell)
403{
404
405 // SLOW! Can we move to directly work with iterators in future?
406
407 // We have to use non-const iterators so that we are allowed to modify the
408 // cell weights
409 CaloClusterCellLink* theCells = thisCluster->getOwnCellLinks();
410
411 CaloClusterCellLink::iterator itCell = theCells->begin();
412 CaloClusterCellLink::iterator endCell = theCells->end();
413 for (; itCell != endCell; ++itCell) {
414 const CaloCell* pCell = (*itCell);
415 if (pCell == thisCell) { // Pointer comparison!
416 return itCell;
417 }
418 }
419
420 // if no match is found then return end of container
421 return endCell;
422}
#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)
static void updateClusterKinematics(std::vector< std::pair< xAOD::CaloCluster *, bool > > &tracksClusters)
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, const 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 void annihilateClusters(std::vector< std::pair< xAOD::CaloCluster *, bool > > &tracksClusters, bool &annFlag, eflowRecTrack &theTrack, const bool &addCPData)
void subtractFullRings(std::vector< std::pair< xAOD::CaloCluster *, bool > > &tracksClusters, CellIt beginRing, CellIt endRing, eflowRecTrack &theTrack, const bool &addCPData) const
static bool subtractCaloCell(double &eSubtracted, const double eExpect, xAOD::CaloCluster *cluster, const CaloCell *cell, eflowRecTrack &theTrack, const bool &addCPData)
double subtractCells(eflowRingSubtractionManager &ringSubtractionManager, eflowRecTrack &theTrack, xAOD::CaloCluster *tracksClus, eflowCellList &orderedCells, bool &annFlag, const bool &addCPData) const
void subtractPartialRings(std::vector< std::pair< xAOD::CaloCluster *, bool > > &tracksClusters, CellIt beginRing, CellIt endRing, double targetRingEnergy, double eRing, eflowRecTrack &theTrack, const bool &addCPData) const
static bool subtractReorderedCells(std::vector< std::pair< xAOD::CaloCluster *, bool > > &tracksClusters, double eSubtracted, const double eExpect, eflowCellList &orderedCells, eflowRecTrack &theTrack, const bool &addCPData)
static double getTotalEnergy(const std::vector< std::pair< xAOD::CaloCluster *, bool > > &tracksClusters)
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.