ATLAS Offline Software
Loading...
Searching...
No Matches
HIEventShapeFillerTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
14#include "CaloDetDescr/CaloDetDescrElement.h"
15
16#include <iostream>
17#include <iomanip>
18
19HIEventShapeFillerTool::HIEventShapeFillerTool(const std::string& myname) : asg::AsgTool(myname),
20m_index(nullptr)
21{
22}
23
25{
26
27 ATH_MSG_INFO("In HIEventShapeFillerTool::initialize()");
28
29 ATH_CHECK( detStore()->retrieve(m_calo_id, "CaloCell_ID") );
31
32 return StatusCode::SUCCESS;
33}
34
35
37{
39 return StatusCode::SUCCESS;
40}
41
42
43StatusCode HIEventShapeFillerTool::initializeEventShapeContainer(std::unique_ptr<xAOD::HIEventShapeContainer>& evtShape) const
44{
45 //use tool to initialize event shape object
46 if (!m_useClusters) m_index->initializeEventShapeContainer(evtShape, m_numOrders);
47 return StatusCode::SUCCESS;
48}
49
50
51StatusCode HIEventShapeFillerTool::fillCollectionFromTowers(std::unique_ptr<xAOD::HIEventShapeContainer>& evtShape, const SG::ReadHandleKey<xAOD::CaloClusterContainer>& tower_container_key, const SG::ReadHandleKey<INavigable4MomentumCollection>& navi_container_key, const EventContext& ctx) const
52{
53 //retrieve the tower container from store
54 if (m_useClusters)
55 {
56 SG::ReadHandle<xAOD::CaloClusterContainer> readHandleCaloClus(tower_container_key, ctx);
57 ATH_CHECK(readHandleCaloClus.isValid());
58 return fillCollectionFromClusterContainer(evtShape, readHandleCaloClus.cptr(),ctx);
59 }
60 SG::ReadHandle<INavigable4MomentumCollection> readHandleINav(navi_container_key, ctx);
61 ATH_CHECK(readHandleINav.isValid());
62 return fillCollectionFromTowerContainer(evtShape, readHandleINav.cptr());
63}
64
65
66StatusCode HIEventShapeFillerTool::fillCollectionFromTowerContainer(std::unique_ptr<xAOD::HIEventShapeContainer>& evtShape, const INavigable4MomentumCollection* navInColl) const
67{
68
70 //loop on towers
71 for (INavigable4MomentumCollection::const_iterator towerItr = navInColl->begin();
72 towerItr != navInColl->end(); ++towerItr)
73 {
74 //navigate back to cells
75 //Default is to sort the cells by either pointer values leading to irreproducible output
76 //CaloCellIDFcn ensures cells are ordered by their IDs
78 (*towerItr)->fillToken(cellToken, double(1.));
79
80 // Use eta/phi of tower in shape calculation
81 float eta0 = (*towerItr)->eta();
82 float phi0 = (*towerItr)->phi();
83
84 if (cellToken.size() == 0) continue;
86 cellItr != cellToken.end(); ++cellItr)
87 {
88
89 const CaloCell* cell=*cellItr;
90 std::unique_ptr<const CaloCell> mirroredCell{};
91
92 bool isDeadFEB = (!cell->caloDDE()->is_tile() && LArProv::test(cell->provenance(),LArProv::DEADFEB));
93
94 if (isDeadFEB) {
95 mirroredCell=getMirroredCell(cell,cellContainer.cptr());
96 if (mirroredCell)
97 cell=mirroredCell.get();
98 else {
99 ATH_MSG_WARNING("Failed to obtain mirrored cell for deadFEB cell with id" << std::hex << cell->ID().get_compact());
100 }
101
102 }//end if dead FEB
103
104 updateShape(evtShape, m_index, cell, cellToken.getParameter(*cellItr), eta0, phi0);
105 }
106 }//end tower loop
107 return StatusCode::SUCCESS;
108}
109
110
111StatusCode HIEventShapeFillerTool::fillCollectionFromClusterContainer(std::unique_ptr<xAOD::HIEventShapeContainer>& evtShape, const xAOD::CaloClusterContainer* theClusters, const EventContext& ctx) const
112{
113 constexpr float area_slice = HI::TowerBins::getBinArea() * HI::TowerBins::numPhiBins();
114 evtShape->reserve(HI::TowerBins::numEtaBins());
115 for (unsigned int eb = 0; eb < HI::TowerBins::numEtaBins(); eb++)
116 {
118 evtShape->push_back(e);
119 e->setLayer(0);
120 e->setEtaMin(HI::TowerBins::getBinLowEdgeEta(eb));
121 e->setEtaMax(HI::TowerBins::getBinUpEdgeEta(eb));
122 e->etCos().assign(m_numOrders, 0);
123 e->etSin().assign(m_numOrders, 0);
124 e->setArea(area_slice);
125 e->setNCells(HI::TowerBins::numPhiBins());
126 }
127
128
129 static const SG::AuxElement::Decorator< float > decorator("HIEtaPhiWeight");
130 static const SG::AuxElement::Decorator< float > cm_decorator("HIMag");
131 static const SG::AuxElement::Accessor<float> acc_mcell_sumE("mcell_sumE");
132
133 constexpr float area_cluster = HI::TowerBins::getBinArea();
134 int runIndex = -1;
135 if(!theClusters->empty() && m_towerWeightTool)
136 {
137 runIndex = m_towerWeightTool->getRunIndex(ctx);
138 }
139
140 for (auto cl : *theClusters) {
141
142 double mcell_sumE = 0;
143 if (acc_mcell_sumE.isAvailable(*cl)) {
144 if(acc_mcell_sumE(*cl) > 1) {
145 mcell_sumE = acc_mcell_sumE(*cl);
146 ATH_MSG_DEBUG("Energy corrected from mirror cell to cluster: " << mcell_sumE);
147 }
148 }
149
150 double ET = (cl->e()+mcell_sumE) / std::cosh(cl->eta0());
151 double phi = cl->phi0();
152 double eta = cl->eta0();
153 unsigned int eb = HI::TowerBins::findBinEta(eta);
154 xAOD::HIEventShape* slice = evtShape->at(eb);
155 float weight = 1;
157 {
158 float recip = m_towerWeightTool->getEtaPhiResponse(eta, phi, runIndex);
159 if (recip != 0.) weight = 1. / recip;
160 }
161 decorator(*cl) = weight;
162
163 //HIMag back in rel 22 (removed by mistake in 21)
164 float etot2 = 0;
165 float er2 = 0;
166
167 for (unsigned int sample = 0; sample < 24; sample++)
168 {
169 CaloSampling::CaloSample s = static_cast<CaloSampling::CaloSample>(sample);
170 if (!cl->hasSampling(s)) continue;
171 float esamp = std::abs(cl->eSample(s));
172 float w1 = m_towerWeightTool->getWeight(eta, phi, s);
173 float wr = m_towerWeightTool->getWeightMag(eta, phi, s);
174 etot2 += esamp * w1;
175 er2 += esamp * wr;
176
177 }
178 float cm = 0;
179 if (etot2 != 0) cm = er2 / etot2;
180 //float cm=er2/etot2;
181 cm_decorator(*cl) = cm;
182
183 //update members
184 slice->setEt(slice->et() + weight * ET);
185 slice->setRho(slice->rho() + weight * ET / area_cluster);
186
187 for (unsigned int i = 0; i < static_cast<unsigned int>(m_numOrders); i++)
188 {
189 float nn = i + 1;
190 float tmp_cos = slice->etCos().at(i);
191 slice->etCos()[i] = tmp_cos + weight * ET * std::cos(nn * phi);
192 float tmp_sin = slice->etSin().at(i);
193 slice->etSin()[i] = tmp_sin + weight * ET * std::sin(nn * phi);
194 }
195 }
196 ATH_MSG_DEBUG("DUMPING HIEVENTSHAPE");
197 for (auto es : *evtShape)
198 {
199 ATH_MSG_DEBUG(std::setw(10) << es->etaMin()
200 << std::setw(10) << es->etaMax()
201 << std::setw(15) << es->et() * 1e-3);
202
203 for (unsigned int i = 0; i < static_cast<unsigned int>(m_numOrders); i++)
204 {
205 ATH_MSG_DEBUG(std::setw(40) << i
206 << std::setw(15) << es->etCos().at(i)
207 << std::setw(15) << es->etSin().at(i));
208 }
209
210 }
211 return StatusCode::SUCCESS;
212}
213
214
215StatusCode HIEventShapeFillerTool::fillCollectionFromCells(std::unique_ptr<xAOD::HIEventShapeContainer>& evtShape, const SG::ReadHandleKey<CaloCellContainer>& cell_container_key, const EventContext& ctx) const
216{
217 //retrieve the cell container from store
218 SG::ReadHandle<CaloCellContainer> read_handle_caloCell(cell_container_key, ctx);
219 const CaloCellContainer* CellContainer = read_handle_caloCell.get();
220 return fillCollectionFromCellContainer(evtShape, CellContainer);
221}
222
223
224StatusCode HIEventShapeFillerTool::fillCollectionFromCellContainer(std::unique_ptr<xAOD::HIEventShapeContainer>& evtShape, const CaloCellContainer* CellContainer) const
225{
226 //loop on Cells
227 for (const auto cellItr : *CellContainer) {
228 const CaloCell* cell=cellItr;
229 std::unique_ptr<const CaloCell> mirroredCell{};
230 bool isDeadFEB = (!cell->caloDDE()->is_tile() && LArProv::test(cell->provenance(),LArProv::DEADFEB));
231 if (isDeadFEB) {
232 mirroredCell=getMirroredCell(cell,CellContainer);
233 if (mirroredCell)
234 cell=mirroredCell.get();
235 else {
236 ATH_MSG_WARNING("Failed to obtain mirrored cell for deadFEB cell with id" << std::hex << cell->ID().get_compact());
237 }
238 }
239
240
241 updateShape(evtShape, m_index, cell, 1., cellItr->eta(), cellItr->phi());
242 }
243
244 return StatusCode::SUCCESS;
245}
246
247
248void HIEventShapeFillerTool::updateShape(std::unique_ptr<xAOD::HIEventShapeContainer>& shape, const HIEventShapeIndex* index, const CaloCell* theCell, float geoWeight, float eta0, float phi0, bool isNeg) const
249{
250 float sgn = (isNeg) ? -1 : 1;
251
252 int layer = theCell->caloDDE()->getSampling();
253 float cell_et = theCell->et();
254
255 xAOD::HIEventShape* slice = index->getShape(eta0, layer, shape);
256 //update members
257 slice->setNCells(slice->nCells() + sgn);
258 slice->setEt(slice->et() + sgn * cell_et * geoWeight);
259 float deta = theCell->caloDDE()->deta();
260 float dphi = theCell->caloDDE()->dphi();
261 float area = std::abs(deta * dphi);
262 float rho = 0;
263 if (area != 0.) rho = cell_et / area;
264 slice->setArea(slice->area() + sgn * area * geoWeight);
265 slice->setRho(slice->rho() + sgn * rho);
266
267 for (unsigned int ih = 0; ih < slice->etCos().size(); ih++)
268 {
269 float ih_f = ih + 1;
270 float tmp_cos = slice->etCos().at(ih);
271 slice->etCos()[ih] = tmp_cos + cell_et * cos(ih_f * phi0) * geoWeight;
272
273 float tmp_sin = slice->etSin().at(ih);
274 slice->etSin()[ih] = tmp_sin + cell_et * sin(ih_f * phi0) * geoWeight;
275 }
276}
277
278std::unique_ptr<const CaloCell> HIEventShapeFillerTool::getMirroredCell(const CaloCell* pCell, const CaloCellContainer* ccc) const {
279
280 const Identifier id = pCell->ID();
281 const int subCalo = m_calo_id->sub_calo(id);
282 const int pos_neg = m_calo_id->pos_neg(id);
283 const int sampling = m_calo_id->sampling(id);
284 const int region = m_calo_id->region(id);
285 const int eta = m_calo_id->eta(id);
286 const int phi = m_calo_id->phi(id);
287
288 ATH_MSG_VERBOSE("DeadFEB cell parameter: (" << subCalo << "," << pos_neg << "," << sampling << "," << region << "," << eta << "," << phi << ")");
289
290 const Identifier mirroredID = m_calo_id->cell_id(subCalo,
291 -pos_neg, // flip to get cell in oposite eta
292 sampling, region, eta, phi);
293
294 const CaloCell* mirroredCell = ccc->findCell(m_calo_id->calo_cell_hash(mirroredID));
295 if (!mirroredCell) {
296 return nullptr;
297 }
298 ATH_MSG_VERBOSE("DeadFEB cell (et,layer,deta,dphi): (" << pCell->et() << "," << pCell->caloDDE()->getSampling() << "," << pCell->caloDDE()->eta() << ","
299 << pCell->caloDDE()->phi() << ")");
300
301 ATH_MSG_VERBOSE("Mirror cell (et,layer,deta,dphi): " << mirroredCell->et() << "," << mirroredCell->caloDDE()->getSampling() << ","
302 << mirroredCell->caloDDE()->eta() << "," << mirroredCell->caloDDE()->phi() << ")");
303
304 // Build a fake-cell with the DDE of the cell we are replacing and
305 // energy,time,etc from the eta-mirrored cell
306 return std::make_unique<const CaloCell>(pCell->caloDDE(), mirroredCell->energy(), mirroredCell->time(), mirroredCell->quality(), mirroredCell->provenance(),
307 mirroredCell->gain());
308}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
This class provides an interface to generate or decode an identifier for the upper levels of the dete...
double area(double R)
DataVector< INavigable4Momentum > INavigable4MomentumCollection
const ServiceHandle< StoreGateSvc > & detStore() const
Container class for CaloCell.
const CaloCell * findCell(const IdentifierHash theHash) const
fast find method given identifier hash.
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
float time() const
get time (data member)
Definition CaloCell.h:368
double energy() const
get energy (data member)
Definition CaloCell.h:327
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
Definition CaloCell.h:321
uint16_t provenance() const
get provenance (data member)
Definition CaloCell.h:354
uint16_t quality() const
get quality (data member)
Definition CaloCell.h:348
CaloGain::CaloGain gain() const
get gain (data member )
Definition CaloCell.h:361
virtual double et() const override final
get et
Definition CaloCell.h:423
Identifier ID() const
get ID (from cached data member) non-virtual and inline for fast access
Definition CaloCell.h:295
CaloCell_ID::CaloSample getSampling() const
cell sampling
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
bool empty() const noexcept
Returns true if the collection is empty.
HIEventShapeFillerTool(const std::string &myname)
const HIEventShapeIndex * m_index
virtual StatusCode initialize() override
Dummy implementation of the initialisation function.
ToolHandle< IHITowerWeightTool > m_towerWeightTool
virtual StatusCode fillCollectionFromCellContainer(std::unique_ptr< xAOD::HIEventShapeContainer > &evtShape, const CaloCellContainer *CellContainer) const
ToolHandle< IHIEventShapeMapTool > m_eventShapeMapTool
virtual StatusCode fillCollectionFromTowers(std::unique_ptr< xAOD::HIEventShapeContainer > &evtShape, const SG::ReadHandleKey< xAOD::CaloClusterContainer > &tower_container_key, const SG::ReadHandleKey< INavigable4MomentumCollection > &navi_container_key, const EventContext &ctx) const override
Gaudi::Property< bool > m_useClusters
std::unique_ptr< const CaloCell > getMirroredCell(const CaloCell *pCell, const CaloCellContainer *ccc) const
virtual StatusCode initializeIndex() override
void updateShape(std::unique_ptr< xAOD::HIEventShapeContainer > &shape, const HIEventShapeIndex *index, const CaloCell *theCell, float geoWeight, float eta0, float phi0, bool isNeg=false) const
virtual StatusCode fillCollectionFromClusterContainer(std::unique_ptr< xAOD::HIEventShapeContainer > &evtShape, const xAOD::CaloClusterContainer *theClusters, const EventContext &ctx) const
virtual StatusCode fillCollectionFromTowerContainer(std::unique_ptr< xAOD::HIEventShapeContainer > &evtShape, const INavigable4MomentumCollection *navInColl) const
SG::ReadHandleKey< CaloCellContainer > m_caloCellKey
Gaudi::Property< int > m_numOrders
virtual StatusCode initializeEventShapeContainer(std::unique_ptr< xAOD::HIEventShapeContainer > &evtShape) const override
const CaloCell_ID * m_calo_id
virtual StatusCode fillCollectionFromCells(std::unique_ptr< xAOD::HIEventShapeContainer > &evtShape, const SG::ReadHandleKey< CaloCellContainer > &cell_container_key, const EventContext &ctx) const override
const_iterator begin() const
CHILDPAR getParameter(const_child_ptr data) const
NavigationTokenIterator const_iterator
const_iterator end() const
unsigned int size()
SG::Decorator< T, ALLOC > Decorator
Definition AuxElement.h:575
SG::Accessor< T, ALLOC > Accessor
Definition AuxElement.h:572
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
Property holding a SG store/key/clid from which a ReadHandle is made.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
const_pointer_type get() const
Dereference the pointer, but don't cache anything.
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
float getBinUpEdgeEta(unsigned int eb)
Definition HIEventDefs.h:39
float getBinLowEdgeEta(unsigned int eb)
Definition HIEventDefs.h:38
constexpr float getBinArea()
Definition HIEventDefs.h:34
constexpr unsigned int numPhiBins()
Definition HIEventDefs.h:22
unsigned int findBinEta(float eta)
Definition HIEventDefs.h:46
constexpr unsigned int numEtaBins()
Definition HIEventDefs.h:19
@ COMPACT
Definition HIEventDefs.h:16
bool test(const uint16_t prov, const LArProvenance check)
Definition index.py:1
CaloClusterContainer_v1 CaloClusterContainer
Define the latest version of the calorimeter cluster container.
HIEventShape_v2 HIEventShape
Definition of the latest event info version.