ATLAS Offline Software
CaloTowerStore.h
Go to the documentation of this file.
1 // This file's extension implies that it's C, but it's really -*- C++ -*-.
2 
3 /*
4  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
5 */
6 
7 #ifndef CALOTOWERSTORE_H
8 #define CALOTOWERSTORE_H
9 /********************************************************************
10 
11 NAME: CaloTowerStore
12 PACKAGE: offline/Calorimeter/CaloRec
13 
14 AUTHORS: S. Laplace
15 CREATED: May 2005
16 
17 PURPOSE: Intermediate store for cell/tower maps. This is NOT to be
18  confused with CaloTowerContainer, even though
19  it is a container class for CaloTower objects. In particular,
20  this class is NOT inherited from CaloTowerContainer classes.
21 
22 Updated: Jul 2009, sss
23 
24  Rewritten to greatly compress the mapping tables,
25  to save virtual memory.
26 
27  To understand what's happening, it helps to go through
28  the optimizations step-by-step.
29 
30  Originally, the table was stored like this:
31 
32  vector<vector<pair<unsigned int, double> > >
33 
34  The outer vector was indexed by the tower number;
35  for each tower, we had a list of (cell hash, weight) pairs.
36 
37  The first thing to notice is that there are only a very
38  few distinct weights used. The weight is the ratio
39  of tower/cell size, capped at 1. The tower segmentations
40  used during reconstruction give a maximum of five
41  distinct weight values (1/n, where n is a small integer).
42  So we can start by moving the weights to a separate list,
43  and storing just the indices into that list. I.e., something
44  like
45 
46  struct Entry {
47  unsigned int hash : ...;
48  unsigned int weight_index : ...;
49  };
50  vector<vector<Entry> >
51 
52  The bitfield sizes can be set to pack Entry into a 32-bit word.
53 
54  The next step is to flatten the nested vector: there may
55  be many towers, each with not so many cells. So, instead of
56  a nested vector, we can store two vectors, one for the
57  cell entries:
58 
59  vector<Entry> m_entries;
60 
61  and one for the towers:
62 
63  vector<unsigned int> m_towers;
64 
65  where the entries here give the indices into m_entries.
66 
67  The next thing to notice is that the entries list contains
68  many runs of cells with consecutive hash codes, plus even longer
69  runs where the hash codes are regularly spaced at intervals
70  of 64. So we can compress things further: for each entry,
71  we now store:
72 
73  - The starting hash code
74  - The number of cells that this entry represents.
75  - A flag for the stride (1 or 64).
76  - The weight index.
77 
78  This can still be packed into 32 bits.
79 
80  When we do this, we also need to add to each tower the
81  total count of cells. We need this when building towers
82  in order to reserve space for the cell list, and don't want
83  to have to run through the entries a separate time to count.
84  The cell count plus the entry index can be packed into 32 bits.
85 
86  Finally, we notice that seqeunces of entries used
87  by adjacent towers tend to be quite similar, except that
88  the hashes are offset by a small integer. This offset may
89  not be constant over the entire sequence, though. For example,
90  consider these two adjacent towers:
91 
92  hash windex stride ncells
93  15008 1 64 4
94  25600 0 1 1
95  31232 3 1 1
96 
97  15008 1 64 4
98  25601 0 1 1
99  31233 3 1 1
100 
101  The first entry has an offset of 0, the other two have
102  an offset of 1.
103 
104  What we do is this. For each tower, we encode two offsets,
105  and also a count of the number of entries using the first
106  offset (call this n1). We choose n1 to be in the range 0--3;
107  this catches most of the observed patterns. If n1 is 0,
108  then the first offset is applied to all entries.
109 
110  It's not possible to usefully pack both offsets and n1 along with
111  an entry index and a count of the cells into 32 bits. But
112  instead of storing the entry index, we can store the number
113  of entries used by this tower. (That suffices since we only
114  ever iterate forwards over the entire container.) We also need
115  to store a flag to tell if we're reusing the list of entries
116  from the previous tower (with offsets). So the information
117  required for each tower is:
118 
119  - The number of entries this tower uses.
120  - A flag to say if the next tower will reuse the entries
121  for this tower.
122  - The number of cells for this tower.
123  - The first and second offset, and the count of entries
124  using the first offset.
125 
126  With judicious choices, this fits in 32 bits.
127 
128  Further optimizations are possible.
129  Many adjacent towers use have an OFFS1,OFFS2,OFFS1 pattern
130  rather and OFFS1,OFFS2. Examination of the compressed
131  entry lists shows that the hash codes are often regularly
132  spaced; adding a second outer stride could compress these
133  further.
134 
135  I think we're reaching diminishing returns, though, so those
136  compressions haven't been implemented. With the current
137  version, the entry lists made by the standard reconstruction
138  have a length of about ~17000 words.
139 
140  The upshot is that memory usage is reduced by ~20x.
141  Execution time is not observed to change significantly.
142 
143 ********************************************************************/
144 
145 // include header files
147 #include "CaloEvent/CaloTowerSeg.h"
148 #include "CxxUtils/CachedValue.h"
149 #include <vector>
150 #include <utility>
151 
152 
153 class CaloDetDescrManager;
154 
155 
157 {
158 private:
159  struct Entry
160  {
161  static const unsigned int hash_width = 18;
162  static const unsigned int hash_max = (1<<hash_width)-1;
163  static const unsigned int windex_width = 6;
164  static const unsigned int windex_max = (1<<windex_width)-1;
165  static const unsigned int ncells_width = 7;
166  static const unsigned int ncells_max = (1<<ncells_width)-1;
167  static const unsigned int stride_width = 1;
168  static const unsigned int stride_max = (1<<stride_width)-1;
169 
170  // Work around link problems with some gcc versions.
171  //static const unsigned int large_stride = 64;
172  //static const unsigned int small_stride = 1;
173  enum {
175  small_stride = 1
176  };
177 
178  unsigned int hash : hash_width;
179  unsigned int windex : windex_width;
180  unsigned int ncells : ncells_width;
181  unsigned int stride : stride_width;
182 
183  Entry (unsigned int the_hash = 0,
184  unsigned int the_windex = 0,
185  unsigned int the_ncells = 1,
186  unsigned int the_stride = 0);
187  };
188 
189  struct Tower
190  {
191  static const unsigned int nentries_width = 5;
192  static const unsigned int nentries_max = (1<<nentries_width)-1;
193  static const unsigned int backref_next_width = 1;
194  static const unsigned int backref_next_max = (1<<backref_next_width)-1;
195  static const unsigned int n1_width = 2;
196  static const unsigned int n1_max = (1<<n1_width)-1;
197  static const unsigned int ncells_width = 8;
198  static const unsigned int ncells_max = (1<<ncells_width)-1;
199  static const unsigned int offs1_width = 8;
200  static const unsigned int offs1_max = (1<<offs1_width)-1;
201  static const unsigned int offs2_width = 8;
202  static const unsigned int offs2_max = (1<<offs2_width)-1;
203 
204  unsigned int nentries : nentries_width;
206  unsigned int n1 : n1_width;
207  unsigned int ncells : ncells_width;
208  unsigned int offs1 : offs1_width;
209  unsigned int offs2 : offs2_width;
210 
211  Tower (unsigned int the_nentries, unsigned int the_ncells);
212  Tower (unsigned int the_nentries, unsigned int the_ncells,
213  unsigned int the_n1,
214  unsigned int the_offs1, unsigned int the_offs2);
215  };
216 
217 
218  public:
219 
222 
225 
227  {
228  public:
229  cell_iterator (std::vector<Entry>::const_iterator it,
230  unsigned int n1,
231  unsigned int offs1,
232  unsigned int offs2,
233  std::vector<double>::const_iterator weights)
234  : m_weights (weights),
235  m_it (it),
236  m_hash (0),
237  m_nleft (0),
238  m_n1 (n1),
239  m_offs (offs1),
240  m_offs2 (offs2),
241  m_stride (0)
242  { }
243  cell_iterator (std::vector<Entry>::const_iterator it)
244  : m_it (it),
245  m_hash(0),
246  m_nleft(0),
247  m_n1(0),
248  m_offs(0),
249  m_offs2(0),
250  m_stride(0)
251  { }
252  unsigned int hash()
253  {
254  if (m_nleft == 0) {
255  m_hash = m_it->hash + m_offs;
256  m_nleft = m_it->ncells;
258  }
259  return m_hash;
260  }
261  double weight() const { return m_weights[m_it->windex]; }
263  if (m_nleft == 0) hash();
264  --m_nleft;
265  if (m_nleft > 0) {
266  m_hash += m_stride;
267  }
268  else {
269  ++m_it;
270  if (m_n1 && --m_n1 == 0) {
271  m_offs = m_offs2;
272  }
273  }
274  return *this;
275  }
277  { return this->m_it != other.m_it;}
278 
279 
280  private:
281  std::vector<double>::const_iterator m_weights;
282  std::vector<Entry>::const_iterator m_it;
283  unsigned int m_hash;
284  unsigned int m_nleft;
285  unsigned int m_n1;
286  unsigned int m_offs;
287  unsigned int m_offs2;
288  unsigned int m_stride;
289  };
290 
292  {
293  public:
294  tower_iterator (std::vector<Tower>::const_iterator it,
295  const std::vector<Entry>::const_iterator entry,
296  const CaloTowerStore& store)
297  : m_entry (entry),
298  m_it (it),
299  m_store (store)
300  {}
302  { return cell_iterator (m_entry, m_it->n1, m_it->offs1, m_it->offs2,
303  m_store.m_weights.begin()); }
305  { return cell_iterator (m_entry + m_it->nentries); }
306  size_t size() const { return m_it->ncells; }
308  if (!m_it->backref_next)
309  m_entry += m_it->nentries;
310  ++m_it;
311  return *this;
312  }
313 
315  {
316  m_it += offs;
317  m_entry = m_store.m_entries.begin() +
318  (*m_store.m_entry_index.ptr())[m_it - m_store.m_towers.begin()];
319  return *this;
320  }
321 
322  protected:
323  std::vector<Entry>::const_iterator m_entry;
324  std::vector<Tower>::const_iterator m_it;
326  };
327 
328 
330  {
331  return tower_iterator (m_towers.begin(),
332  m_entries.begin(),
333  *this);
334  }
335 
336 
338 
339 
351  tower_subseg_iterator towers (const CaloTowerSeg::SubSeg& subseg) const;
352 
353 
354  size_t size() const { return m_towers.size(); }
355 
357  bool buildLookUp(const CaloDetDescrManager& theManager,
358  const CaloTowerSeg& theTowerSeg,
359  const std::vector<CaloCell_ID::SUBCALO>& theCalos);
360 
361  private:
362  friend class tower_iterator;
363 
364  void pushTower (unsigned int nentries, unsigned int ncells);
365 
366 
370  void checkEntryIndex() const;
371 
373  std::vector<Entry> m_entries;
374  std::vector<Tower> m_towers;
375  std::vector<double> m_weights;
376 
383 };
384 
385 
386 //************************************************************************
387 
388 
389 
390 #endif
CaloTowerStore::Tower::nentries
unsigned int nentries
Definition: CaloTowerStore.h:204
store
StoreGateSvc * store
Definition: fbtTestBasics.cxx:69
CaloTowerSeg::SubSegIterator
Iterator over a rectangular window of towers.
Definition: CaloTowerSeg.h:337
CaloTowerStore::tower_iterator::m_it
std::vector< Tower >::const_iterator m_it
Definition: CaloTowerStore.h:324
CaloTowerStore::tower_iterator::tower_iterator
tower_iterator(std::vector< Tower >::const_iterator it, const std::vector< Entry >::const_iterator entry, const CaloTowerStore &store)
Definition: CaloTowerStore.h:294
CaloTowerStore::cell_iterator::cell_iterator
cell_iterator(std::vector< Entry >::const_iterator it, unsigned int n1, unsigned int offs1, unsigned int offs2, std::vector< double >::const_iterator weights)
Definition: CaloTowerStore.h:229
CaloTowerStore::Tower::offs2
unsigned int offs2
Definition: CaloTowerStore.h:209
CaloTowerStore::Entry::ncells_max
static const unsigned int ncells_max
Definition: CaloTowerStore.h:166
CxxUtils::CachedValue::ptr
const T * ptr() const
Return a pointer to the cached value.
CaloTowerStore::m_seg
CaloTowerSeg m_seg
Definition: CaloTowerStore.h:372
CaloTowerStore::Tower::backref_next_width
static const unsigned int backref_next_width
Definition: CaloTowerStore.h:193
CaloTowerStore::Tower::offs1_max
static const unsigned int offs1_max
Definition: CaloTowerStore.h:200
CaloTowerStore::Entry::hash_width
static const unsigned int hash_width
Definition: CaloTowerStore.h:161
CaloTowerStore::Tower::offs2_max
static const unsigned int offs2_max
Definition: CaloTowerStore.h:202
CaloTowerStore::m_entry_index
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.
Definition: CaloTowerStore.h:382
CaloTowerStore::Tower::nentries_max
static const unsigned int nentries_max
Definition: CaloTowerStore.h:192
CaloTowerStore::Tower::offs1_width
static const unsigned int offs1_width
Definition: CaloTowerStore.h:199
CaloTowerStore::~CaloTowerStore
~CaloTowerStore()
destructor
CaloTowerStore::tower_iterator::m_store
const CaloTowerStore & m_store
Definition: CaloTowerStore.h:325
CaloTowerStore::tower_iterator
friend class tower_iterator
Definition: CaloTowerStore.h:362
skel.it
it
Definition: skel.GENtoEVGEN.py:423
CaloTowerStore::cell_iterator::hash
unsigned int hash()
Definition: CaloTowerStore.h:252
CaloTowerStore::Tower::offs2_width
static const unsigned int offs2_width
Definition: CaloTowerStore.h:201
CaloTowerStore::tower_subseg_iterator
CaloTowerSeg::SubSegIterator< tower_iterator > tower_subseg_iterator
Definition: CaloTowerStore.h:337
CaloTowerStore::Tower::ncells_max
static const unsigned int ncells_max
Definition: CaloTowerStore.h:198
CaloTowerStore::m_towers
std::vector< Tower > m_towers
Definition: CaloTowerStore.h:374
CaloTowerSeg.h
CaloTowerStore::Tower
Definition: CaloTowerStore.h:190
CaloTowerStore::Entry::hash_max
static const unsigned int hash_max
Definition: CaloTowerStore.h:162
CaloTowerStore::Entry::ncells
unsigned int ncells
Definition: CaloTowerStore.h:180
CaloTowerStore::pushTower
void pushTower(unsigned int nentries, unsigned int ncells)
Definition: CaloTowerStore.cxx:289
CaloTowerStore::Tower::ncells
unsigned int ncells
Definition: CaloTowerStore.h:207
CaloTowerStore::cell_iterator::m_weights
std::vector< double >::const_iterator m_weights
Definition: CaloTowerStore.h:281
CaloCell_ID.h
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
CaloTowerStore::m_entries
std::vector< Entry > m_entries
Definition: CaloTowerStore.h:373
CaloTowerStore::cell_iterator::m_stride
unsigned int m_stride
Definition: CaloTowerStore.h:288
CaloTowerStore::Tower::Tower
Tower(unsigned int the_nentries, unsigned int the_ncells)
Definition: CaloTowerStore.cxx:367
CaloTowerStore::cell_iterator::m_nleft
unsigned int m_nleft
Definition: CaloTowerStore.h:284
CaloTowerStore::cell_iterator::m_hash
unsigned int m_hash
Definition: CaloTowerStore.h:283
PlotCalibFromCool.nentries
nentries
Definition: PlotCalibFromCool.py:798
CaloTowerStore::checkEntryIndex
void checkEntryIndex() const
Check m_entry_index and fill it in if we haven't done so yet.
Definition: CaloTowerStore.cxx:271
CaloTowerStore::cell_iterator::m_offs
unsigned int m_offs
Definition: CaloTowerStore.h:286
CaloTowerStore::Entry::windex_max
static const unsigned int windex_max
Definition: CaloTowerStore.h:164
CaloTowerStore::cell_iterator::m_n1
unsigned int m_n1
Definition: CaloTowerStore.h:285
CaloTowerStore::Tower::ncells_width
static const unsigned int ncells_width
Definition: CaloTowerStore.h:197
CaloTowerStore::CaloTowerStore
CaloTowerStore()
constructor
CaloTowerStore::Entry::stride_width
static const unsigned int stride_width
Definition: CaloTowerStore.h:167
CxxUtils::CachedValue
Cached value with atomic update.
Definition: CachedValue.h:55
CaloTowerStore::Entry::hash
unsigned int hash
Definition: CaloTowerStore.h:178
CaloTowerStore::Tower::nentries_width
static const unsigned int nentries_width
Definition: CaloTowerStore.h:191
CaloTowerStore::m_weights
std::vector< double > m_weights
Definition: CaloTowerStore.h:375
CaloTowerStore::Entry::windex
unsigned int windex
Definition: CaloTowerStore.h:179
CaloTowerStore::cell_iterator::operator!=
bool operator!=(const cell_iterator &other)
Definition: CaloTowerStore.h:276
CaloTowerStore::cell_iterator::operator++
cell_iterator & operator++()
Definition: CaloTowerStore.h:262
CaloTowerStore
Definition: CaloTowerStore.h:157
CaloTowerStore::Tower::n1_width
static const unsigned int n1_width
Definition: CaloTowerStore.h:195
GetAllXsec.entry
list entry
Definition: GetAllXsec.py:132
CaloTowerStore::tower_iterator::lastCell
cell_iterator lastCell() const
Definition: CaloTowerStore.h:304
CachedValue.h
Cached value with atomic update.
CaloTowerStore::Entry::stride_max
static const unsigned int stride_max
Definition: CaloTowerStore.h:168
CaloTowerStore::tower_iterator
Definition: CaloTowerStore.h:292
CaloTowerStore::Tower::n1_max
static const unsigned int n1_max
Definition: CaloTowerStore.h:196
Rtt_histogram.n1
n1
Definition: Rtt_histogram.py:21
CaloTowerStore::cell_iterator::cell_iterator
cell_iterator(std::vector< Entry >::const_iterator it)
Definition: CaloTowerStore.h:243
CaloTowerStore::cell_iterator::m_it
std::vector< Entry >::const_iterator m_it
Definition: CaloTowerStore.h:282
CaloTowerStore::Tower::backref_next
bool backref_next
Definition: CaloTowerStore.h:205
CaloTowerStore::Entry::Entry
Entry(unsigned int the_hash=0, unsigned int the_windex=0, unsigned int the_ncells=1, unsigned int the_stride=0)
Definition: CaloTowerStore.cxx:351
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
CaloTowerStore::Tower::backref_next_max
static const unsigned int backref_next_max
Definition: CaloTowerStore.h:194
CaloDetDescrManager
This class provides the client interface for accessing the detector description information common to...
Definition: CaloDetDescrManager.h:473
CaloTowerStore::tower_iterator::operator+=
tower_iterator & operator+=(size_t offs)
Definition: CaloTowerStore.h:314
CaloTowerStore::Tower::n1
unsigned int n1
Definition: CaloTowerStore.h:206
CaloTowerStore::Entry::windex_width
static const unsigned int windex_width
Definition: CaloTowerStore.h:163
CaloTowerStore::towers
tower_iterator towers() const
Definition: CaloTowerStore.h:329
CaloTowerStore::Tower::offs1
unsigned int offs1
Definition: CaloTowerStore.h:208
CaloTowerSeg
Data object stores CaloTower segmentation.
Definition: CaloTowerSeg.h:37
CaloTowerStore::size
size_t size() const
Definition: CaloTowerStore.h:354
CaloTowerStore::Entry::large_stride
@ large_stride
Definition: CaloTowerStore.h:174
CaloTowerStore::tower_iterator::m_entry
std::vector< Entry >::const_iterator m_entry
Definition: CaloTowerStore.h:323
CaloTowerStore::tower_iterator::operator++
tower_iterator & operator++()
Definition: CaloTowerStore.h:307
CaloTowerStore::cell_iterator::m_offs2
unsigned int m_offs2
Definition: CaloTowerStore.h:287
CaloTowerStore::Entry::small_stride
@ small_stride
Definition: CaloTowerStore.h:175
CaloTowerStore::Entry::ncells_width
static const unsigned int ncells_width
Definition: CaloTowerStore.h:165
CaloTowerStore::buildLookUp
bool buildLookUp(const CaloDetDescrManager &theManager, const CaloTowerSeg &theTowerSeg, const std::vector< CaloCell_ID::SUBCALO > &theCalos)
setup trigger
Definition: CaloTowerStore.cxx:74
CaloTowerStore::Entry::stride
unsigned int stride
Definition: CaloTowerStore.h:181
CaloTowerStore::tower_iterator::size
size_t size() const
Definition: CaloTowerStore.h:306
CaloTowerStore::cell_iterator::weight
double weight() const
Definition: CaloTowerStore.h:261
CaloTowerStore::Entry
Definition: CaloTowerStore.h:160