ATLAS Offline Software
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 
14 #include "StoreGate/StoreGateSvc.h"
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)
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!
54  return this->checkSetup(msg());
55 }
56 
58 // Tower Builder Helpers //
60 
61 
62 inline
63 void
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 
96 inline
97 void
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 
112 inline
113 void
115  const ElementLink<CaloCellContainer>& cellsEL,
116  const CaloTowerSeg::SubSeg* subseg) const
117 {
118  size_t sz = towers->size();
119  assert(subseg->size() == sz);
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 
165 CaloTowerBuilderTool::execute(const EventContext& ctx,
166  CaloTowerContainer* theTowers,
167  const CaloCellContainer* theCells /*= 0*/,
168  const CaloTowerSeg::SubSeg* subseg /*= 0*/) const
169 {
170 
171 
172  //Init internal structure m_cellStore on first invocation
173  //Alignment updates are not taken into account!
174  if (!m_cellStoreInit.load()) {
175  //Aquire mutex before writing to m_cellStore
176  std::scoped_lock guard(m_cellStoreMutex);
177  //cast alway const-ness, acceptable since this is protected by a mutex
178  CaloTowerBuilderTool* thisNC ATLAS_THREAD_SAFE = const_cast<CaloTowerBuilderTool*>(this);
179  ATH_CHECK( thisNC->rebuildLookup(ctx) );
180  m_cellStoreInit.store(true);
181  }
182 
183  // CaloCellContainer
184  if (!theCells) {
185  theCells = getCells();
186  if (!theCells) {
187  return StatusCode::SUCCESS;
188  }
189  }
190 
191  const ElementLink<CaloCellContainer> cellsEL (*theCells, 0, ctx);
192  if (subseg)
193  iterateSubSeg (theTowers, cellsEL, subseg);
194  else
195  iterateFull (theTowers, cellsEL);
196 
197  for (unsigned int i = 0; i < m_caloIndices.size(); i++) {
198  theTowers->setCalo(m_caloIndices[i]);
199  }
200 
201  ATH_MSG_DEBUG("Number of Towers in CaloTowerContainer: "<< theTowers->size());
202 
203  /* for debug purposes
204  double summ=0;
205  std::cout << " Number of Towers in CaloTowerContainer: "<< theTowers->size() << std::endl;
206  for ( unsigned int t=0; t<theTowers->size(); ++t ) { // TOWER Loop
207  CaloTower* aTower = theTowers->getTower(t); // get tower
208  double E=aTower->getBasicEnergy();
209  summ+=E;
210  std::cout<<"Tower: "<<t<<"\te:"<<E<<std::endl;
211  }
212  std::cout<<"================ SUMM\t"<<summ<<std::endl;
213  */
214 
215  return StatusCode::SUCCESS;
216 }
217 
218 
227 StatusCode CaloTowerBuilderTool::execute (const EventContext& ctx,
228  CaloTowerContainer* theContainer)
229 {
230  if (m_cellStore.size() == 0) {
231  setTowerSeg (theContainer->towerseg());
232  ATH_CHECK( rebuildLookup(ctx) );
233  }
234 
235  return execute (ctx, theContainer, nullptr, nullptr);
236 }
237 
238 
240 // Internal Helpers //
242 
243 // protected
245  // any calos registered
246  if (m_caloIndices.empty()) {
247  ATH_MSG_ERROR("no match in requested calorimeter ranges ("
248  << m_includedCalos.size() << " requested)");
249  // print out requested keys
250  for (unsigned int iCalos = 0; iCalos < m_includedCalos.size(); iCalos++) {
251  if (iCalos == 0) {
252  msg(MSG::ERROR) << "requested key(s): " << m_includedCalos[iCalos];
253  } else if (iCalos == m_includedCalos.size() - 1) {
254  ATH_MSG_ERROR("," << m_includedCalos[iCalos] << " all not known!");
255  } else {
256  msg(MSG::ERROR) << "," << m_includedCalos[iCalos];
257  }
258  }
259  return StatusCode::FAILURE;
260  }
261  return StatusCode::SUCCESS;
262 }
263 
264 void CaloTowerBuilderTool::setCalos(const std::vector<CaloCell_ID::SUBCALO>& v)
265 {
266  if (m_caloIndices != v) {
267  if (m_cellStore.size() > 0) {
268  if (rebuildLookup(Gaudi::Hive::currentContext()).isFailure()) {
269  ATH_MSG_ERROR("rebuildLookup failed.");
270  }
271  }
272  m_caloIndices = v;
273  }
274 }
275 
276 
281 std::vector<CaloCell_ID::SUBCALO>
283  (const std::vector<std::string>& includedCalos) const
284 {
285  // convert to enumerators
286  std::vector<CaloCell_ID::SUBCALO> indices;
287 
288  for (const std::string& s : includedCalos) {
289  if (s == "LAREM") {
290  indices.push_back(CaloCell_ID::LAREM);
291  } else if (s == "LARHEC") {
292  indices.push_back(CaloCell_ID::LARHEC);
293  } else if (s == "LARFCAL") {
294  indices.push_back(CaloCell_ID::LARFCAL);
295  } else if (s == "TILE") {
296  indices.push_back(CaloCell_ID::TILE);
297  }
298  }
299 
300  return indices;
301 }
302 
303 
308  if (towerSeg().neta() != 0 && towerSeg().nphi() != 0) {
309  ATH_MSG_DEBUG("Building lookup table");
311  const CaloDetDescrManager* caloDDM=*caloMgrHandle;
312  if (m_cellStore.buildLookUp(*caloDDM, towerSeg(), m_caloIndices)) {
313  return StatusCode::SUCCESS;
314  }
315  }
316  return StatusCode::FAILURE;
317 }
318 
CaloTowerSeg::SubSegIterator
Iterator over a rectangular window of towers.
Definition: CaloTowerSeg.h:337
RunTileCalibRec.cells
cells
Definition: RunTileCalibRec.py:271
CaloTowerBuilderTool::CaloTowerBuilderTool
CaloTowerBuilderTool(const CaloTowerBuilderTool &)=delete
CaloCell_Base_ID::LARFCAL
@ LARFCAL
Definition: CaloCell_Base_ID.h:46
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
fitman.sz
sz
Definition: fitman.py:527
CaloTowerStore.h
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
Trk::indices
std::pair< long int, long int > indices
Definition: AlSymMatBase.h:24
CaloTowerBuilderTool::setCalos
virtual void setCalos(const std::vector< CaloCell_ID::SUBCALO > &v)
Definition: CaloTowerBuilderTool.cxx:264
CaloTowerBuilderTool::initializeTool
virtual StatusCode initializeTool() override
Definition: CaloTowerBuilderTool.cxx:52
CaloTowerStore::cell_iterator::hash
unsigned int hash()
Definition: CaloTowerStore.h:252
CaloCell.h
CaloTowerBuilderTool::parseCalos
virtual std::vector< CaloCell_ID::SUBCALO > parseCalos(const std::vector< std::string > &includedCalos) const
Convert calorimeter strings to enums.
Definition: CaloTowerBuilderTool.cxx:283
CaloCell::e
virtual double e() const override final
get energy (data member) (synonym to method energy()
Definition: CaloCell.h:317
CaloTowerBuilderToolBase::getCells
const CaloCellContainer * getCells() const
Retrieve cells from StoreGate.
Definition: CaloTowerBuilderToolBase.cxx:59
CaloCell_Base_ID::LARHEC
@ LARHEC
Definition: CaloCell_Base_ID.h:46
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
CaloEnergyCluster::addUniqueCellNoKine
void addUniqueCellNoKine(const CaloCellContainer *theContainer, index_type theIndex, double weight, size_t size_hint=0)
Add a cell (very fast)
Definition: CaloEnergyCluster.cxx:125
CaloTowerBuilderTool::m_cellStoreInit
std::atomic_bool m_cellStoreInit
Definition: CaloTowerBuilderTool.h:112
CaloDetDescrManager.h
Definition of CaloDetDescrManager.
CaloTowerStore::tower_iterator::firstCell
cell_iterator firstCell() const
Definition: CaloTowerStore.h:301
CaloTowerStore::cell_iterator
Definition: CaloTowerStore.h:227
CaloTowerSeg::SubSeg
A rectangular window within the segmentation.
Definition: CaloTowerSeg.h:220
CaloTowerBuilderTool::rebuildLookup
StatusCode rebuildLookup(const EventContext &ctx)
Rebuild the cell lookup table.
Definition: CaloTowerBuilderTool.cxx:307
CaloTowerBuilderTool::addTower
static void addTower(const CaloTowerStore::tower_iterator tower_it, const ElementLink< CaloCellContainer > &cellsEL, CaloTower *tower)
Definition: CaloTowerBuilderTool.cxx:64
CaloTowerBuilderTool::checkSetup
virtual StatusCode checkSetup(MsgStream &log)
Definition: CaloTowerBuilderTool.cxx:244
CaloTowerContainer
Storable container class for CaloTower.
Definition: Calorimeter/CaloEvent/CaloEvent/CaloTowerContainer.h:77
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
lumiFormat.i
int i
Definition: lumiFormat.py:92
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
CaloTowerBuilderToolBase::towerSeg
const CaloTowerSeg & towerSeg() const
Return the tower segmentation.
Definition: CaloTowerBuilderToolBase.cxx:50
test_pyathena.parent
parent
Definition: test_pyathena.py:15
CaloTowerSeg::SubSegIterator::itower
size_t itower() const
The tower index to which the iterator is referring.
Definition: CaloTowerSeg.h:710
CaloPhiRange.h
CaloPhiRange class declaration.
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
CaloCell_Base_ID::TILE
@ TILE
Definition: CaloCell_Base_ID.h:46
CaloTowerBuilderTool::execute
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.
Definition: CaloTowerBuilderTool.cxx:165
CaloTowerBuilderTool::m_cellStore
CaloTowerStore m_cellStore
Definition: CaloTowerBuilderTool.h:110
CaloTower
Data class for calorimeter cell towers.
Definition: Calorimeter/CaloEvent/CaloEvent/CaloTower.h:55
CaloTowerStore::tower_iterator::lastCell
cell_iterator lastCell() const
Definition: CaloTowerStore.h:304
CaloTowerBuilderTool::~CaloTowerBuilderTool
virtual ~CaloTowerBuilderTool()
CaloTowerContainer::towerseg
const CaloTowerSeg & towerseg() const
Return a copy of the attached CaloTowerSeg.
Definition: Calorimeter/CaloEvent/CaloEvent/CaloTowerContainer.h:591
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
CaloTowerBuilderToolBase::m_caloMgrKey
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloMgrKey
Definition: CaloTowerBuilderToolBase.h:95
CaloTowerStore::tower_iterator
Definition: CaloTowerStore.h:292
CaloCellContainer.h
CaloCellContainer
Container class for CaloCell.
Definition: CaloCellContainer.h:55
CaloTowerBuilderTool::iterateSubSeg
void iterateSubSeg(CaloTowerContainer *towers, const ElementLink< CaloCellContainer > &cellsEL, const CaloTowerSeg::SubSeg *subseg) const
Definition: CaloTowerBuilderTool.cxx:114
python.PyAthena.v
v
Definition: PyAthena.py:157
CaloTowerBuilderTool::m_cellStoreMutex
std::mutex m_cellStoreMutex
Definition: CaloTowerBuilderTool.h:111
CaloDetDescrManager
This class provides the client interface for accessing the detector description information common to...
Definition: CaloDetDescrManager.h:473
CaloCell
Data object for each calorimeter readout cell.
Definition: CaloCell.h:57
RunTileMonitoring.towers
towers
Definition: RunTileMonitoring.py:133
CaloTowerBuilderTool::m_includedCalos
std::vector< std::string > m_includedCalos
Definition: CaloTowerBuilderTool.h:98
CaloTowerBuilderToolBase
Definition: CaloTowerBuilderToolBase.h:31
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
AthCommonMsg< AlgTool >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
P4EEtaPhiM::setE
virtual void setE(double theE)
set energy data member
Definition: P4EEtaPhiM.h:114
CaloTowerStore::towers
tower_iterator towers() const
Definition: CaloTowerStore.h:329
CaloTowerSeg::SubSeg::size
size_t size() const
The number of towers in this window.
Definition: CaloTowerSeg.h:591
CaloTowerStore::size
size_t size() const
Definition: CaloTowerStore.h:354
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
CaloTowerBuilderTool::iterateFull
void iterateFull(CaloTowerContainer *towers, const ElementLink< CaloCellContainer > &cellsEL) const
Definition: CaloTowerBuilderTool.cxx:98
python.CaloScaleNoiseConfig.ts
ts
Definition: CaloScaleNoiseConfig.py:86
CaloCell_Base_ID::LAREM
@ LAREM
Definition: CaloCell_Base_ID.h:46
CaloTowerStore::buildLookUp
bool buildLookUp(const CaloDetDescrManager &theManager, const CaloTowerSeg &theTowerSeg, const std::vector< CaloCell_ID::SUBCALO > &theCalos)
setup trigger
Definition: CaloTowerStore.cxx:74
CaloTowerBuilderTool
Definition: CaloTowerBuilderTool.h:34
StoreGateSvc.h
CaloTowerContainer::setCalo
void setCalo(const CaloCell_ID::SUBCALO &nCalo)
Adds a calorimeter index to the tower.
Definition: CaloTowerContainer.cxx:169
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
CaloTowerStore::tower_iterator::size
size_t size() const
Definition: CaloTowerStore.h:306
CaloTowerBuilderTool.h
CaloTowerBuilderTool::m_caloIndices
std::vector< CaloCell_ID::SUBCALO > m_caloIndices
Definition: CaloTowerBuilderTool.h:104
CaloTowerBuilderToolBase::setTowerSeg
virtual void setTowerSeg(const CaloTowerSeg &theTowerSeg) override
Definition: CaloTowerBuilderToolBase.cxx:37
CaloTowerStore::cell_iterator::weight
double weight() const
Definition: CaloTowerStore.h:261
CaloTower::getBasicEnergy
virtual double getBasicEnergy() const override
Basic signal getter.
Definition: CaloTower.cxx:51