ATLAS Offline Software
Loading...
Searching...
No Matches
CaloTowerBuilderTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5
6#include "CLHEP/Units/SystemOfUnits.h"
7
8#include "GaudiKernel/MsgStream.h"
9#include "Gaudi/Property.h"
10#include "GaudiKernel/Service.h"
11#include "GaudiKernel/IToolSvc.h"
12//#include "GaudiKernel/IChronoStatSvc.h"
13
15
18#include "CaloEvent/CaloCell.h"
20#include "CaloEvent/CaloTower.h"
21#include "CaloEvent/CaloTowerContainer.h"
24
25#include <string>
26#include <cmath>
27
29 const std::string& type,
30 const IInterface* parent)
31 : CaloTowerBuilderToolBase(name,type,parent)
32 // , m_errorCounter(0)
33{
34 declareInterface<ICaloTowerBuilderToolBase>(this);
35 m_includedCalos.resize(4);
36 m_includedCalos[0] = "LAREM";
37 m_includedCalos[1] = "LARHEC";
38 m_includedCalos[2] = "LARFCAL";
39 m_includedCalos[3] = "TILE";
40 // common properties
41 declareProperty("IncludedCalos",m_includedCalos);
42}
43
45= default;
46
48// Specific Initialization //
50
51// protected!
56
58// Tower Builder Helpers //
60
61
62inline
63void
65 const ElementLink<CaloCellContainer>& cellsEL,
66 CaloTower* tower)
67{
68 CaloTowerStore::cell_iterator firstC = tower_it.firstCell();
69 CaloTowerStore::cell_iterator lastC = tower_it.lastCell();
70 int ts = tower_it.size();
71 double wsumE = tower->getBasicEnergy(); // this is not 0 since some towers already have cells from other calos.
72 const CaloCellContainer* cells = cellsEL.getDataPtr();
73 for (; firstC != lastC; ++firstC) {
74
75 unsigned int ci = firstC.hash();
76 double weightC = firstC.weight();
77 int cndx = cells->findIndex(ci);
78 const CaloCell* cellPtr = nullptr;
79 if (cndx >= 0)
80 cellPtr = (*cells)[cndx];
81 // get weights
82 if (cellPtr) {
83 wsumE += weightC * cellPtr->e(); // Summ up weighted energies .
84 tower->addUniqueCellNoKine(cellsEL, cndx, weightC, ts); // add cells to tower.
85 }
86 /* for debugging em+hec
87 if (t==5214) std::cout<<"N14\tc:"<<ci<<"\tw:"<<weightC<<"\te:"<<cellPtr->e()<<"\teta:"<<cellPtr->eta()<<"\td:"<<cellPtr->caloDDE()<<std::endl;
88 if (t==5279) std::cout<<"N79\tc:"<<ci<<"\tw:"<<weightC<<"\te:"<<cellPtr->e()<<"\teta:"<<cellPtr->eta()<<"\td:"<<cellPtr->caloDDE()<<std::endl;
89 */
90
91 }
92 tower->setE(wsumE); // update tower kinematics.
93}
94
95
96inline
97void
99 const ElementLink<CaloCellContainer>& cellsEL) const
100{
101 size_t sz = towers->size();
102 assert(m_cellStore.size() == sz);
104
105 for (unsigned int t = 0; t < sz; ++t, ++tower_it) {
106 CaloTower* aTower = towers->getTower(t);
107 addTower (tower_it, cellsEL, aTower);
108 }
109}
110
111
112inline
113void
115 const ElementLink<CaloCellContainer>& cellsEL,
116 const CaloTowerSeg::SubSeg* subseg) const
117{
118 size_t sz = towers->size();
119 assert(subseg->size() == sz);
120 CaloTowerStore::tower_subseg_iterator tower_it = m_cellStore.towers(*subseg);
121
122#if 0
123 for (unsigned int t = 0; t < sz; ++t, ++tower_it) {
124 CaloTower* aTower = towers->getTower(tower_it.itower());
125 addTower (tower_it, cellsEL, aTower);
126 }
127#endif
128 // This loop was originally written as above. However, if we increment
129 // tower_it at the end of the iteration, then it will end up doing
130 // an out-of-bounds read (in tower_iterator::operator+=).
131 // Best to just avoid incrementing it if we don't need to;
132 // that also saves a bit of useless work.
133 unsigned int t = 0;
134 while (true) {
135 CaloTower* aTower = towers->getTower(tower_it.itower());
136 addTower (tower_it, cellsEL, aTower);
137 ++t;
138 if (t >= sz) break;
139 ++tower_it;
140 }
141}
142
143
145// Tower Builder //
147
148
149void CaloTowerBuilderTool::runTimeInit(const EventContext& ctx) const {
150 //cast alway const-ness, acceptable since this is protected under a std::call_once
152 if( thisNC->rebuildLookup(ctx)!=StatusCode::SUCCESS )
153 throw std::runtime_error("LArFCalTowerBuilderTool::runTimeInit rebuildLookup table failed");
154 }
155
156
172StatusCode
173CaloTowerBuilderTool::execute(const EventContext& ctx,
174 CaloTowerContainer* theTowers,
175 const CaloCellContainer* theCells /*= 0*/,
176 const CaloTowerSeg::SubSeg* subseg /*= 0*/) const
177{
178
179
180 //Init internal structure m_cellStore on first invocation
181 //Alignment updates are not taken into account!
182 std::call_once(m_onceFlag,&CaloTowerBuilderTool::runTimeInit,this,ctx);
183
184 // CaloCellContainer
185 if (!theCells) {
186 theCells = getCells();
187 if (!theCells) {
188 return StatusCode::SUCCESS;
189 }
190 }
191
192 const ElementLink<CaloCellContainer> cellsEL (*theCells, 0, ctx);
193 if (subseg)
194 iterateSubSeg (theTowers, cellsEL, subseg);
195 else
196 iterateFull (theTowers, cellsEL);
197
198 for (unsigned int i = 0; i < m_caloIndices.size(); i++) {
199 theTowers->setCalo(m_caloIndices[i]);
200 }
201
202 ATH_MSG_DEBUG("Number of Towers in CaloTowerContainer: "<< theTowers->size());
203
204 /* for debug purposes
205 double summ=0;
206 std::cout << " Number of Towers in CaloTowerContainer: "<< theTowers->size() << std::endl;
207 for ( unsigned int t=0; t<theTowers->size(); ++t ) { // TOWER Loop
208 CaloTower* aTower = theTowers->getTower(t); // get tower
209 double E=aTower->getBasicEnergy();
210 summ+=E;
211 std::cout<<"Tower: "<<t<<"\te:"<<E<<std::endl;
212 }
213 std::cout<<"================ SUMM\t"<<summ<<std::endl;
214 */
215
216 return StatusCode::SUCCESS;
217}
218
219
228StatusCode CaloTowerBuilderTool::execute (const EventContext& ctx,
229 CaloTowerContainer* theContainer)
230{
231 if (m_cellStore.size() == 0) {
232 setTowerSeg (theContainer->towerseg());
233 ATH_CHECK( rebuildLookup(ctx) );
234 }
235
236 return execute (ctx, theContainer, nullptr, nullptr);
237}
238
239
241// Internal Helpers //
243
244// protected
245StatusCode CaloTowerBuilderTool::checkSetup(MsgStream& /*log*/) {
246 // any calos registered
247 if (m_caloIndices.empty()) {
248 ATH_MSG_ERROR("no match in requested calorimeter ranges ("
249 << m_includedCalos.size() << " requested)");
250 // print out requested keys
251 for (unsigned int iCalos = 0; iCalos < m_includedCalos.size(); iCalos++) {
252 if (iCalos == 0) {
253 msg(MSG::ERROR) << "requested key(s): " << m_includedCalos[iCalos];
254 } else if (iCalos == m_includedCalos.size() - 1) {
255 ATH_MSG_ERROR("," << m_includedCalos[iCalos] << " all not known!");
256 } else {
257 msg(MSG::ERROR) << "," << m_includedCalos[iCalos];
258 }
259 }
260 return StatusCode::FAILURE;
261 }
262 return StatusCode::SUCCESS;
263}
264
265void CaloTowerBuilderTool::setCalos(const std::vector<CaloCell_ID::SUBCALO>& v)
266{
267 if (m_caloIndices != v) {
268 if (m_cellStore.size() > 0) {
269 if (rebuildLookup(Gaudi::Hive::currentContext()).isFailure()) {
270 ATH_MSG_ERROR("rebuildLookup failed.");
271 }
272 }
273 m_caloIndices = v;
274 }
275}
276
277
282std::vector<CaloCell_ID::SUBCALO>
284 (const std::vector<std::string>& includedCalos) const
285{
286 // convert to enumerators
287 std::vector<CaloCell_ID::SUBCALO> indices;
288
289 for (const std::string& s : includedCalos) {
290 if (s == "LAREM") {
291 indices.push_back(CaloCell_ID::LAREM);
292 } else if (s == "LARHEC") {
293 indices.push_back(CaloCell_ID::LARHEC);
294 } else if (s == "LARFCAL") {
295 indices.push_back(CaloCell_ID::LARFCAL);
296 } else if (s == "TILE") {
297 indices.push_back(CaloCell_ID::TILE);
298 }
299 }
300
301 return indices;
302}
303
304
308StatusCode CaloTowerBuilderTool::rebuildLookup(const EventContext& ctx){
309 if (towerSeg().neta() != 0 && towerSeg().nphi() != 0) {
310 ATH_MSG_DEBUG("Building lookup table");
312 const CaloDetDescrManager* caloDDM=*caloMgrHandle;
313 if (m_cellStore.buildLookUp(*caloDDM, towerSeg(), m_caloIndices)) {
314 return StatusCode::SUCCESS;
315 }
316 }
317 return StatusCode::FAILURE;
318}
319
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)
Definition of CaloDetDescrManager.
CaloPhiRange class declaration.
static Double_t sz
#define ATLAS_THREAD_SAFE
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
Container class for CaloCell.
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
virtual double e() const override final
get energy (data member) (synonym to method energy()
Definition CaloCell.h:333
This class provides the client interface for accessing the detector description information common to...
void addUniqueCellNoKine(const CaloCellContainer *theContainer, index_type theIndex, double weight, size_t size_hint=0)
Add a cell (very fast)
const CaloTowerSeg & towerSeg() const
Return the tower segmentation.
virtual void setTowerSeg(const CaloTowerSeg &theTowerSeg) override
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloMgrKey
CaloTowerBuilderToolBase(const std::string &name, const std::string &type, const IInterface *parent)
AlgTool constructor.
const CaloCellContainer * getCells() const
Retrieve cells from StoreGate.
virtual StatusCode checkSetup(MsgStream &log)
void runTimeInit(const EventContext &ctx) const
virtual StatusCode execute(const EventContext &ctx, CaloTowerContainer *theContainer, const CaloCellContainer *theCell=0, const CaloTowerSeg::SubSeg *subseg=0) const override
Run tower building and add results to the tower container.
void iterateFull(CaloTowerContainer *towers, const ElementLink< CaloCellContainer > &cellsEL) const
std::vector< std::string > m_includedCalos
std::vector< CaloCell_ID::SUBCALO > m_caloIndices
static void addTower(const CaloTowerStore::tower_iterator tower_it, const ElementLink< CaloCellContainer > &cellsEL, CaloTower *tower)
virtual ~CaloTowerBuilderTool()
CaloTowerBuilderTool(const CaloTowerBuilderTool &)=delete
void iterateSubSeg(CaloTowerContainer *towers, const ElementLink< CaloCellContainer > &cellsEL, const CaloTowerSeg::SubSeg *subseg) const
virtual StatusCode initializeTool() override
StatusCode rebuildLookup(const EventContext &ctx)
Rebuild the cell lookup table.
virtual std::vector< CaloCell_ID::SUBCALO > parseCalos(const std::vector< std::string > &includedCalos) const
Convert calorimeter strings to enums.
virtual void setCalos(const std::vector< CaloCell_ID::SUBCALO > &v)
Storable container class for CaloTower.
void setCalo(const CaloCell_ID::SUBCALO &nCalo)
Adds a calorimeter index to the tower.
const CaloTowerSeg & towerseg() const
Return a copy of the attached CaloTowerSeg.
size_t itower() const
The tower index to which the iterator is referring.
A rectangular window within the segmentation.
size_t size() const
The number of towers in this window.
cell_iterator lastCell() const
cell_iterator firstCell() const
CaloTowerSeg::SubSegIterator< tower_iterator > tower_subseg_iterator
Data class for calorimeter cell towers.
virtual double getBasicEnergy() const override
Basic signal getter.
Definition CaloTower.cxx:51
size_type size() const noexcept
Returns the number of elements in the collection.
virtual void setE(double theE)
set energy data member
Definition P4EEtaPhiM.h:114
int ts
Definition globals.cxx:24
MsgStream & msg
Definition testRead.cxx:32