ATLAS Offline Software
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 
7 NAME: CaloTowerStore
8 PACKAGE: offline/Calorimeter/CaloUtils
9 
10 AUTHORS: S. Laplace
11 CREATED: May 2005
12 
13 PURPOSE: Intermediate store for cell/tower maps
14 
15 Updated: 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 
26 #include "CaloEvent/CaloTowerSeg.h"
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>());
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 &&
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,
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  }
280  m_entry_index.set (std::move (entries));
281  }
282 }
283 
284 
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 
347 CaloTowerStore::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 
363 CaloTowerStore::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 
377 CaloTowerStore::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 
CaloDetDescrElement::deta
float deta() const
cell deta
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:356
CaloTowerSeg::SubSegIterator
Iterator over a rectangular window of towers.
Definition: CaloTowerSeg.h:337
CxxUtils::CachedValue::reset
void reset()
Reset the value to invalid.
ReadOfcFromCool.phase
phase
Definition: ReadOfcFromCool.py:127
CaloTowerStore::Entry::ncells_max
static const unsigned int ncells_max
Definition: CaloTowerStore.h:166
fitman.sz
sz
Definition: fitman.py:527
CaloTowerStore.h
getMessageSvc.h
singleton-like access to IMessageSvc via open function and helper
CaloTowerStore::m_seg
CaloTowerSeg m_seg
Definition: CaloTowerStore.h:372
CaloTowerSeg::SubSegIterator::make
static SubSegIterator make(TOWER_ITERATOR beg, const SubSeg &subseg)
Construct a new iterator for iterating over a window.
Definition: CaloTowerSeg.h:609
CaloTowerStore::Tower::offs1_max
static const unsigned int offs1_max
Definition: CaloTowerStore.h:200
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
CxxUtils::CachedValue::isValid
bool isValid() const
Test to see if the value is valid.
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
CaloDetDescrElement
This class groups all DetDescr information related to a CaloCell. Provides a generic interface for al...
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:66
CaloTowerStore::Tower::nentries_max
static const unsigned int nentries_max
Definition: CaloTowerStore.h:192
CaloDetDescrManager_Base::get_element
const CaloDetDescrElement * get_element(const Identifier &cellId) const
get element by its identifier
Definition: CaloDetDescrManager.cxx:159
CaloTowerStore::~CaloTowerStore
~CaloTowerStore()
destructor
skel.it
it
Definition: skel.GENtoEVGEN.py:396
CaloTowerSeg::neta
index_t neta() const
Retrieve number of bins.
Definition: CaloTowerSeg.h:423
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
CaloTowerSeg::deta
double deta() const
Retrieve bin size .
Definition: CaloTowerSeg.h:433
CaloTowerStore::Entry::hash_max
static const unsigned int hash_max
Definition: CaloTowerStore.h:162
CxxUtils::CachedValue::store
void store(const T &val)
Store a new value.
CaloTowerStore::Entry::ncells
unsigned int ncells
Definition: CaloTowerStore.h:180
CaloTowerStore::pushTower
void pushTower(unsigned int nentries, unsigned int ncells)
Definition: CaloTowerStore.cxx:285
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
CaloDetDescrManager.h
Definition of CaloDetDescrManager.
CaloTowerSeg::nphi
index_t nphi() const
Retrieve number of bins.
Definition: CaloTowerSeg.h:428
CaloDetDescrElement::eta_raw
float eta_raw() const
cell eta_raw
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:350
PlotCalibFromCool.ie
ie
Definition: PlotCalibFromCool.py:420
CaloDetDescrManager_Base::isInitialized
bool isInitialized() const
for backwards compatibility only
Definition: CaloDetDescrManager.h:165
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::Tower::Tower
Tower(unsigned int the_nentries, unsigned int the_ncells)
Definition: CaloTowerStore.cxx:363
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:267
CaloTowerSeg::dphi
double dphi() const
Retrieve bin size .
Definition: CaloTowerSeg.h:438
lumiFormat.i
int i
Definition: lumiFormat.py:85
z
#define z
CaloTowerStore::Entry::windex_max
static const unsigned int windex_max
Definition: CaloTowerStore.h:164
CaloCell_Base_ID::calo_cell_hash_range
void calo_cell_hash_range(const Identifier id, IdentifierHash &caloCellMin, IdentifierHash &caloCellMax) const
to loop on 'global' cell hashes of one sub-calorimeter alone
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
CaloTowerStore::CaloTowerStore
CaloTowerStore()
constructor
CaloTowerStore::Entry::hash
unsigned int hash
Definition: CaloTowerStore.h:178
CaloTowerStore::m_weights
std::vector< double > m_weights
Definition: CaloTowerStore.h:375
CaloTowerSeg::index_t
size_t index_t
Type for eta, phi indices.
Definition: CaloTowerSeg.h:59
find_tgc_unfilled_channelids.ip
ip
Definition: find_tgc_unfilled_channelids.py:3
CaloPhiRange.h
CaloPhiRange class declaration.
CaloTowerStore::Entry::windex
unsigned int windex
Definition: CaloTowerStore.h:179
CaloCell_ID
Helper class for offline cell identifiers.
Definition: CaloCell_ID.h:34
xAOD::double
double
Definition: CompositeParticle_v1.cxx:159
CaloPhiRange::fix
static double fix(double phi)
Definition: CaloPhiRange.cxx:14
grepfile.ic
int ic
Definition: grepfile.py:33
IdentifierHash.h
CaloTowerSeg::phiIndex
index_t phiIndex(double phiVal) const
Returns index for a given value.
Definition: CaloTowerSeg.h:499
CaloTowerSeg::etaphi
index_t etaphi(index_t etaInd, index_t phiInd) const
Returns combined continous index from , indices.
Definition: CaloTowerSeg.h:481
CxxUtils::CachedValue::set
void set(const T &val) const
Set the value, assuming it is currently invalid.
CaloTowerStore::Entry::stride_max
static const unsigned int stride_max
Definition: CaloTowerStore.h:168
CaloTowerStore::Tower::n1_max
static const unsigned int n1_max
Definition: CaloTowerStore.h:196
eflowRec::phiIndex
unsigned int phiIndex(float phi, float binsize)
calculate phi index for a given phi
Definition: EtaPhiLUT.cxx:23
Rtt_histogram.n1
n1
Definition: Rtt_histogram.py:21
python.PyAthena.v
v
Definition: PyAthena.py:154
CaloDetDescrElement::dphi
float dphi() const
cell dphi
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:358
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:347
LArCellBinning.etaMin
etaMin
Definition: LArCellBinning.py:84
CaloDetDescrManager
This class provides the client interface for accessing the detector description information common to...
Definition: CaloDetDescrManager.h:473
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:109
DEBUG
#define DEBUG
Definition: page_access.h:11
entries
double entries
Definition: listroot.cxx:49
CaloTowerSeg::outOfRange
static const index_t outOfRange
Used to flag out-of-range indices.
Definition: CaloTowerSeg.h:62
CaloDetDescrManager::getCaloCell_ID
const CaloCell_ID * getCaloCell_ID() const
get calo cell ID helper
Definition: CaloDetDescrManager.cxx:1590
CaloTowerStore::towers
tower_iterator towers() const
Definition: CaloTowerStore.h:329
CaloTowerSeg
Data object stores CaloTower segmentation.
Definition: CaloTowerSeg.h:37
CaloTowerStore::Entry::large_stride
@ large_stride
Definition: CaloTowerStore.h:174
IdentifierHash
This is a "hash" representation of an Identifier. This encodes a 32 bit index which can be used to lo...
Definition: IdentifierHash.h:25
CaloTowerStore::Entry::small_stride
@ small_stride
Definition: CaloTowerStore.h:175
CaloTowerSeg::etaIndex
index_t etaIndex(double etaVal) const
Returns index for a given value.
Definition: CaloTowerSeg.h:489
CaloTowerStore::buildLookUp
bool buildLookUp(const CaloDetDescrManager &theManager, const CaloTowerSeg &theTowerSeg, const std::vector< CaloCell_ID::SUBCALO > &theCalos)
setup trigger
Definition: CaloTowerStore.cxx:75
CaloTowerStore::Entry::stride
unsigned int stride
Definition: CaloTowerStore.h:181
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
CaloDetDescrElement::phi_raw
float phi_raw() const
cell phi_raw
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:352
CaloTowerStore::Entry
Definition: CaloTowerStore.h:160