ATLAS Offline Software
Loading...
Searching...
No Matches
CaloTowerStore.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5/********************************************************************
6
7NAME: CaloTowerStore
8PACKAGE: offline/Calorimeter/CaloUtils
9
10AUTHORS: S. Laplace
11CREATED: May 2005
12
13PURPOSE: Intermediate store for cell/tower maps
14
15Updated: Ilija Vukotic August 2008.
16 basically rewrote it completely.
17 add reverse lookup in order to speed things up
18 When I see how many linebreaks some people use I think of two things:
19 1. they programm on their mobile phone
20 2. they are paid per line of programm :-)
21
22********************************************************************/
24
27#include "GaudiKernel/Bootstrap.h"
28#include "GaudiKernel/Service.h"
29#include "GaudiKernel/MsgStream.h"
30#include "GaudiKernel/IMessageSvc.h"
32
34#include "CaloDetDescr/CaloDetDescrElement.h"
36
37#include <cmath>
38#include <utility>
39#include <limits>
40#include <cassert>
42// Constructor and Destructor //
44
45// constructor
47
48// destructor
50
52// Build LookUp Table //
54
55
69{
71 return tower_subseg_iterator::make (towers(), subseg);
72}
73
74
76 const CaloTowerSeg& theTowerSeg,
77 const std::vector<CaloCell_ID::SUBCALO>& theCalos)
78{
79 m_seg = theTowerSeg;
80 m_entries.clear();
81 m_towers.clear();
82 m_weights.clear();
83 m_entry_index.store (std::vector<unsigned short>());
84 m_entry_index.reset();
85
87 // Store Preparation //
89
90 // messaging
91 MsgStream msg(Athena::getMessageSvc(),"CaloTowerStore");
92
93 // get cell description manager
94 if ( ! theManager.isInitialized() ){
95 msg << MSG::ERROR<< "CaloDetDescrManager is not initialized, module unusable!"<< endmsg;
96 return false;
97 }
98 const CaloCell_ID& cellIdHelper = *theManager.getCaloCell_ID();
99
100 // Get list of Calos to be considered
101 size_t sizeCalos = theCalos.size();
102
103 unsigned int ntowers = theTowerSeg.neta() * theTowerSeg.nphi();
104 msg << MSG::DEBUG << " number of towers " << ntowers << endmsg;
105 std::vector< std::vector<Entry> > ttcmatrix;
106 ttcmatrix.resize (ntowers);
107 m_weights.reserve (10);
108 m_weights.push_back (1);
109
110 for ( unsigned int iCalo=0; iCalo<sizeCalos; iCalo++ ){ // Loop over calos //
111
112 // find numerical ranges
113 IdentifierHash firstIndex, lastIndex;
114 cellIdHelper.calo_cell_hash_range((int)theCalos[iCalo], firstIndex, lastIndex);
115 msg << MSG::DEBUG << " firstInder,lastIndex " << firstIndex << " " << lastIndex << endmsg;
116
117
118 for( size_t cellIndex = firstIndex; cellIndex < lastIndex; cellIndex++){ // Cell Loop //
119
120
121 const CaloDetDescrElement* theDDE = theManager.get_element(cellIndex);
122
123 if(theDDE==nullptr) {
124 msg << MSG::ERROR<< " CellIndex = "<< cellIndex<< " has a DDE pointer NULL " << endmsg;
125 continue;
126 }
127
128 // pick up cell dimensions and raw position
129 double cellDeta = theDDE->deta();
130 double cellDphi = theDDE->dphi();
131 double etaRaw = theDDE->eta_raw();
132 double phiRaw = CaloPhiRange::fix(theDDE->phi_raw());
133
135 // Calculate Cell Fragments //
137
138 // calculate cell/tower size ratio (integer,[1..n])
139 // DR : round rather than truncate
140 size_t ke = (size_t) (cellDeta/theTowerSeg.deta()+0.5);
141 ke = (ke==0) ? 1 : ke;
142 size_t kp = (size_t) (cellDphi/theTowerSeg.dphi()+0.5);
143 kp = (kp==0) ? 1 : kp;
144 // signal weight
145 double theWeight = 1. / ( (double) ke * kp );
146 // fractional cell sizes
147 double cellDdeta = cellDeta / (double) ke;
148 double cellDdphi = cellDphi / (double) kp;
149 double etaMin = etaRaw - cellDeta / 2.;
150 double phiMin = phiRaw - cellDphi / 2.;
151
153 // Loop Cell Fragments //
155
156
157 for ( size_t ie=1; ie<=ke; ie++ ){ // outer (eta) fragment loop
158 double cellEta = etaMin + ((double)ie - 0.5) * cellDdeta; // eta of fragment
159 for ( size_t ip=1; ip<=kp; ip++ ){ // inner (phi) fragement loop
160 double cellPhi = phiMin + ((double)ip - 0.5) * cellDdphi; // phi of fragment
161
162 CaloTowerSeg::index_t etaIndex = theTowerSeg.etaIndex(cellEta);
163 CaloTowerSeg::index_t phiIndex = theTowerSeg.phiIndex(cellPhi);
164
165 if ( etaIndex != CaloTowerSeg::outOfRange &&
166 phiIndex != CaloTowerSeg::outOfRange )
167 {
168 CaloTowerSeg::index_t towerIndex = theTowerSeg.etaphi (etaIndex, phiIndex);
169 size_t iw = 0;
170 for (; iw < m_weights.size(); iw++) {
171 if (m_weights[iw] == theWeight) break;
172 }
173 if (iw == m_weights.size())
174 m_weights.push_back (theWeight);
175
176 if (towerIndex < ntowers) {
177 ttcmatrix[towerIndex].emplace_back(cellIndex,iw);
178 }
179 } // index retrieval check
180
181 } // cell y loop
182 } // cell x loop
183
184 } // cell index loop
185
186
187 }
188
189 //int nraw = 0;
190 m_towers.reserve (ttcmatrix.size()+1);
191 m_entries.reserve (17500); // Typical observed size.
192 for (size_t i = 0; i < ttcmatrix.size(); i++) {
193 size_t last_nentries = m_entries.size();
194 const std::vector<Entry>& v = ttcmatrix[i];
195 //nraw += v.size();
196
197 if (!v.empty()) {
198 Entry ent (v[0]);
199 unsigned int stride = 0;
200 for (size_t j = 1; j < v.size(); j++) {
201 if (stride == 0) {
202 if (v[j].hash - ent.hash == (int)Entry::large_stride) {
203 stride = Entry::large_stride;
204 ent.stride = 1;
205 }
206 else {
207 ent.stride = 0;
208 stride = Entry::small_stride;
209 }
210 }
211 if ((int)(v[j].hash - v[j-1].hash) == (int)stride &&
212 v[j].windex == ent.windex &&
214 ++ent.ncells;
215 else {
216 m_entries.push_back (ent);
217 ent = v[j];
218 stride = 0;
219 }
220 }
221 m_entries.push_back (ent);
222 }
223
224 pushTower (m_entries.size() - last_nentries, v.size());
225 //m_towers.push_back (Tower (m_entries.size() - last_nentries, v.size()));
226 }
227
228#if 0
229 {
230 printf ("zzztowers calos: ");
231 for (size_t z = 0; z < theCalos.size(); z++) printf ("%d ", theCalos[z]);
232 printf ("ntower: %d nent: %d nentraw: %d weights: ",
233 ntowers, m_entries.size(), nraw);
234 for (size_t z = 0; z < m_weights.size(); z++) printf ("%f ", m_weights[z]);
235 printf ("\n");
236
237 static FILE* flog = 0;
238 if (!flog) flog = fopen ("towstore.dump", "w");
239 fprintf (flog, "========================================\n");
240 size_t ic = 0;
241 bool backref = false;
242 for (size_t it = 0; it < m_towers.size(); it++) {
243 fprintf (flog, "tow %d %d %d %d %d %d\n", it, m_towers[it].ncells,
244 m_towers[it].nentries,
245 m_towers[it].n1, m_towers[it].offs1, m_towers[it].offs2);
246 if (!backref) {
247 for (size_t z = 0; z < m_towers[it].nentries; z++) {
248 fprintf (flog, "%6d %6d %2d %2d %3d\n", ic, m_entries[ic].hash,
249 m_entries[ic].windex, m_entries[ic].stride,
250 m_entries[ic].ncells);
251 ++ic;
252 }
253 }
254 backref = m_towers[it].backref_next;
255 }
256 }
257#endif
258
259
260 return 1;
261}
262
263
268{
269 if (!m_entry_index.isValid()) {
270 std::vector<unsigned short> entries;
271 size_t sz = m_towers.size();
272 entries.resize (sz);
273 size_t ndx = 0;
274 for (size_t i = 0; i < sz; i++) {
275 entries[i] = ndx;
276 if (!m_towers[i].backref_next)
277 ndx += m_towers[i].nentries;
278 }
279 assert (ndx < std::numeric_limits<unsigned short>::max());
280 m_entry_index.set (std::move (entries));
281 }
282}
283
284
285void CaloTowerStore::pushTower (unsigned int nentries,
286 unsigned int ncells)
287{
288 if (!m_towers.empty() && m_towers.back().nentries == nentries) {
289 unsigned int pos1 = m_entries.size() - 2*nentries;
290 unsigned int pos2 = m_entries.size() - nentries;
291 unsigned int phase = 0;
292 unsigned int n1 = 0;
293 unsigned int offs1 = 0;
294 unsigned int offs2 = 0;
295 for (size_t i = 0; i < nentries; i++) {
296 const Entry& ent1 = m_entries[pos1+i];
297 const Entry& ent2 = m_entries[pos2+i];
298 if (ent1.windex != ent2.windex ||
299 ent1.ncells != ent2.ncells ||
300 ent1.stride != ent2.stride)
301 {
302 phase = 3;
303 break;
304 }
305 unsigned int offs = ent2.hash - ent1.hash;
306 if (phase == 0) {
307 offs1 = offs;
308 n1 = 1;
309 phase = 1;
310 }
311 else if (phase == 1) {
312 if (offs == offs1)
313 ++n1;
314 else {
315 offs2 = offs;
316 phase = 2;
317 }
318 }
319 else if (phase == 2) {
320 if (offs != offs2) {
321 phase = 3;
322 break;
323 }
324 }
325 }
326
327 if (phase == 1)
328 n1 = 0;
329
330 if (phase < 3 &&
331 n1 <= Tower::n1_max &&
332 offs1 <= Tower::offs1_max &&
333 offs2 <= Tower::offs2_max)
334 {
335 //m_towers.back().nentries = 0;
336 assert (!m_towers.empty());
337 m_towers.back().backref_next = true;
338 m_towers.emplace_back(nentries, ncells, n1, offs1, offs2);
339 m_entries.resize (m_entries.size() - nentries);
340 return;
341 }
342 }
343 m_towers.emplace_back(nentries, ncells);
344}
345
346
347CaloTowerStore::Entry::Entry (unsigned int the_hash,
348 unsigned int the_windex,
349 unsigned int the_ncells /*= 1*/,
350 unsigned int the_stride /*= 0*/)
351 : hash (the_hash),
352 windex (the_windex),
353 ncells (the_ncells),
354 stride (the_stride)
355{
356 assert (the_hash <= hash_max);
357 assert (the_windex <= windex_max);
358 assert (the_ncells <= ncells_max);
359 assert (the_stride <= stride_max);
360}
361
362
363CaloTowerStore::Tower::Tower (unsigned int the_nentries,
364 unsigned int the_ncells)
365 : nentries (the_nentries),
366 backref_next (false),
367 n1 (0),
368 ncells (the_ncells),
369 offs1 (0),
370 offs2 (0)
371{
372 assert (the_nentries <= nentries_max);
373 assert (the_ncells <= ncells_max);
374}
375
376
377CaloTowerStore::Tower::Tower (unsigned int the_nentries,
378 unsigned int the_ncells,
379 unsigned int the_n1,
380 unsigned int the_offs1,
381 unsigned int the_offs2)
382 : nentries (the_nentries),
383 backref_next (false),
384 n1 (the_n1),
385 ncells (the_ncells),
386 offs1 (the_offs1),
387 offs2 (the_offs2)
388{
389 assert (the_nentries <= nentries_max);
390 assert (the_ncells <= ncells_max);
391 assert (the_n1 <= n1_max);
392 assert (the_offs1 <= offs1_max);
393 assert (the_offs2 <= offs2_max);
394}
395
396
#define endmsg
Definition of CaloDetDescrManager.
CaloPhiRange class declaration.
static Double_t sz
#define z
void calo_cell_hash_range(const Identifier id, IdentifierHash &caloCellMin, IdentifierHash &caloCellMax) const
to loop on 'global' cell hashes of one sub-calorimeter alone
Helper class for offline cell identifiers.
Definition CaloCell_ID.h:34
This class groups all DetDescr information related to a CaloCell.
const CaloDetDescrElement * get_element(const Identifier &cellId) const
get element by its identifier
bool isInitialized() const
for backwards compatibility only
This class provides the client interface for accessing the detector description information common to...
const CaloCell_ID * getCaloCell_ID() const
get calo cell ID helper
static double fix(double phi)
static SubSegIterator make(tower_iterator beg, const SubSeg &subseg)
A rectangular window within the segmentation.
Data object stores CaloTower segmentation.
index_t nphi() const
Retrieve number of bins.
size_t index_t
Type for eta, phi indices.
index_t etaphi(index_t etaInd, index_t phiInd) const
Returns combined continous index from , indices.
index_t neta() const
Retrieve number of bins.
double deta() const
Retrieve bin size .
double dphi() const
Retrieve bin size .
index_t phiIndex(double phiVal) const
Returns index for a given value.
static const index_t outOfRange
Used to flag out-of-range indices.
index_t etaIndex(double etaVal) const
Returns index for a given value.
~CaloTowerStore()
destructor
CaloTowerSeg m_seg
std::vector< Tower > m_towers
std::vector< double > m_weights
CxxUtils::CachedValue< std::vector< unsigned short > > m_entry_index
One of these for each entry in m_towers, giving the index of the corresponding entry in m_entries.
bool buildLookUp(const CaloDetDescrManager &theManager, const CaloTowerSeg &theTowerSeg, const std::vector< CaloCell_ID::SUBCALO > &theCalos)
setup trigger
void pushTower(unsigned int nentries, unsigned int ncells)
CaloTowerStore()
constructor
void checkEntryIndex() const
Check m_entry_index and fill it in if we haven't done so yet.
tower_iterator towers() const
CaloTowerSeg::SubSegIterator< tower_iterator > tower_subseg_iterator
std::vector< Entry > m_entries
This is a "hash" representation of an Identifier.
singleton-like access to IMessageSvc via open function and helper
double entries
Definition listroot.cxx:49
IMessageSvc * getMessageSvc(bool quiet=false)
static const unsigned int windex_max
static const unsigned int stride_max
static const unsigned int hash_max
static const unsigned int ncells_max
Entry(unsigned int the_hash=0, unsigned int the_windex=0, unsigned int the_ncells=1, unsigned int the_stride=0)
Tower(unsigned int the_nentries, unsigned int the_ncells)
static const unsigned int nentries_max
static const unsigned int ncells_max
static const unsigned int n1_max
static const unsigned int offs1_max
static const unsigned int offs2_max
MsgStream & msg
Definition testRead.cxx:32