ATLAS Offline Software
CaloTowerStore.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 
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 #include "CaloEvent/CaloTowerSeg.h"
25 #include "GaudiKernel/Bootstrap.h"
26 #include "GaudiKernel/Service.h"
27 #include "GaudiKernel/MsgStream.h"
28 #include "GaudiKernel/IMessageSvc.h"
29 // include header files
31 
33 #include "CaloDetDescr/CaloDetDescrElement.h"
35 
36 #include <cmath>
37 #include <utility>
38 #include <limits>
39 #include <cassert>
41 // Constructor and Destructor //
43 
44 // constructor
46 
47 // destructor
49 
51 // Build LookUp Table //
53 
54 
68 {
70  return tower_subseg_iterator::make (towers(), subseg);
71 }
72 
73 
75  const CaloTowerSeg& theTowerSeg,
76  const std::vector<CaloCell_ID::SUBCALO>& theCalos)
77 {
78  m_seg = theTowerSeg;
79  m_entries.clear();
80  m_towers.clear();
81  m_weights.clear();
82  m_entry_index.store (std::vector<unsigned short>());
84 
86  // Store Preparation //
88 
89  // messaging
90  IMessageSvc* theMsgSvc;
91  StatusCode sc = Gaudi::svcLocator()->service("MessageSvc",theMsgSvc);
92  if(sc.isFailure()){
93  std::cout << "Cannot locate MessageSvc" << std::endl;
94  }
95  MsgStream msg(theMsgSvc,"CaloTowerStore");
96 
97  // get cell description manager
98  if ( ! theManager.isInitialized() ){
99  msg << MSG::ERROR<< "CaloDetDescrManager is not initialized, module unusable!"<< endmsg;
100  return false;
101  }
102  const CaloCell_ID& cellIdHelper = *theManager.getCaloCell_ID();
103 
104  // Get list of Calos to be considered
105  size_t sizeCalos = theCalos.size();
106 
107  unsigned int ntowers = theTowerSeg.neta() * theTowerSeg.nphi();
108  msg << MSG::DEBUG << " number of towers " << ntowers << endmsg;
109  std::vector< std::vector<Entry> > ttcmatrix;
110  ttcmatrix.resize (ntowers);
111  m_weights.reserve (10);
112  m_weights.push_back (1);
113 
114  for ( unsigned int iCalo=0; iCalo<sizeCalos; iCalo++ ){ // Loop over calos //
115 
116  // find numerical ranges
117  IdentifierHash firstIndex, lastIndex;
118  cellIdHelper.calo_cell_hash_range((int)theCalos[iCalo], firstIndex, lastIndex);
119  msg << MSG::DEBUG << " firstInder,lastIndex " << firstIndex << " " << lastIndex << endmsg;
120 
121 
122  for( size_t cellIndex = firstIndex; cellIndex < lastIndex; cellIndex++){ // Cell Loop //
123 
124 
125  const CaloDetDescrElement* theDDE = theManager.get_element(cellIndex);
126 
127  if(theDDE==nullptr) {
128  msg << MSG::ERROR<< " CellIndex = "<< cellIndex<< " has a DDE pointer NULL " << endmsg;
129  continue;
130  }
131 
132  // pick up cell dimensions and raw position
133  double cellDeta = theDDE->deta();
134  double cellDphi = theDDE->dphi();
135  double etaRaw = theDDE->eta_raw();
136  double phiRaw = CaloPhiRange::fix(theDDE->phi_raw());
137 
139  // Calculate Cell Fragments //
141 
142  // calculate cell/tower size ratio (integer,[1..n])
143  // DR : round rather than truncate
144  size_t ke = (size_t) (cellDeta/theTowerSeg.deta()+0.5);
145  ke = (ke==0) ? 1 : ke;
146  size_t kp = (size_t) (cellDphi/theTowerSeg.dphi()+0.5);
147  kp = (kp==0) ? 1 : kp;
148  // signal weight
149  double theWeight = 1. / ( (double) ke * kp );
150  // fractional cell sizes
151  double cellDdeta = cellDeta / (double) ke;
152  double cellDdphi = cellDphi / (double) kp;
153  double etaMin = etaRaw - cellDeta / 2.;
154  double phiMin = phiRaw - cellDphi / 2.;
155 
157  // Loop Cell Fragments //
159 
160 
161  for ( size_t ie=1; ie<=ke; ie++ ){ // outer (eta) fragment loop
162  double cellEta = etaMin + ((double)ie - 0.5) * cellDdeta; // eta of fragment
163  for ( size_t ip=1; ip<=kp; ip++ ){ // inner (phi) fragement loop
164  double cellPhi = phiMin + ((double)ip - 0.5) * cellDdphi; // phi of fragment
165 
166  CaloTowerSeg::index_t etaIndex = theTowerSeg.etaIndex(cellEta);
167  CaloTowerSeg::index_t phiIndex = theTowerSeg.phiIndex(cellPhi);
168 
169  if ( etaIndex != CaloTowerSeg::outOfRange &&
171  {
172  CaloTowerSeg::index_t towerIndex = theTowerSeg.etaphi (etaIndex, phiIndex);
173  size_t iw = 0;
174  for (; iw < m_weights.size(); iw++) {
175  if (m_weights[iw] == theWeight) break;
176  }
177  if (iw == m_weights.size())
178  m_weights.push_back (theWeight);
179 
180  if (towerIndex < ntowers) {
181  ttcmatrix[towerIndex].emplace_back(cellIndex,iw);
182  }
183  } // index retrieval check
184 
185  } // cell y loop
186  } // cell x loop
187 
188  } // cell index loop
189 
190 
191  }
192 
193  //int nraw = 0;
194  m_towers.reserve (ttcmatrix.size()+1);
195  m_entries.reserve (17500); // Typical observed size.
196  for (size_t i = 0; i < ttcmatrix.size(); i++) {
197  size_t last_nentries = m_entries.size();
198  const std::vector<Entry>& v = ttcmatrix[i];
199  //nraw += v.size();
200 
201  if (!v.empty()) {
202  Entry ent (v[0]);
203  unsigned int stride = 0;
204  for (size_t j = 1; j < v.size(); j++) {
205  if (stride == 0) {
206  if (v[j].hash - ent.hash == (int)Entry::large_stride) {
207  stride = Entry::large_stride;
208  ent.stride = 1;
209  }
210  else {
211  ent.stride = 0;
212  stride = Entry::small_stride;
213  }
214  }
215  if ((int)(v[j].hash - v[j-1].hash) == (int)stride &&
216  v[j].windex == ent.windex &&
218  ++ent.ncells;
219  else {
220  m_entries.push_back (ent);
221  ent = v[j];
222  stride = 0;
223  }
224  }
225  m_entries.push_back (ent);
226  }
227 
228  pushTower (m_entries.size() - last_nentries, v.size());
229  //m_towers.push_back (Tower (m_entries.size() - last_nentries, v.size()));
230  }
231 
232 #if 0
233  {
234  printf ("zzztowers calos: ");
235  for (size_t z = 0; z < theCalos.size(); z++) printf ("%d ", theCalos[z]);
236  printf ("ntower: %d nent: %d nentraw: %d weights: ",
237  ntowers, m_entries.size(), nraw);
238  for (size_t z = 0; z < m_weights.size(); z++) printf ("%f ", m_weights[z]);
239  printf ("\n");
240 
241  static FILE* flog = 0;
242  if (!flog) flog = fopen ("towstore.dump", "w");
243  fprintf (flog, "========================================\n");
244  size_t ic = 0;
245  bool backref = false;
246  for (size_t it = 0; it < m_towers.size(); it++) {
247  fprintf (flog, "tow %d %d %d %d %d %d\n", it, m_towers[it].ncells,
249  m_towers[it].n1, m_towers[it].offs1, m_towers[it].offs2);
250  if (!backref) {
251  for (size_t z = 0; z < m_towers[it].nentries; z++) {
252  fprintf (flog, "%6d %6d %2d %2d %3d\n", ic, m_entries[ic].hash,
253  m_entries[ic].windex, m_entries[ic].stride,
254  m_entries[ic].ncells);
255  ++ic;
256  }
257  }
258  backref = m_towers[it].backref_next;
259  }
260  }
261 #endif
262 
263 
264  return 1;
265 }
266 
267 
272 {
273  if (!m_entry_index.isValid()) {
274  std::vector<unsigned short> entries;
275  size_t sz = m_towers.size();
276  entries.resize (sz);
277  size_t ndx = 0;
278  for (size_t i = 0; i < sz; i++) {
279  entries[i] = ndx;
280  if (!m_towers[i].backref_next)
281  ndx += m_towers[i].nentries;
282  }
284  m_entry_index.set (std::move (entries));
285  }
286 }
287 
288 
290  unsigned int ncells)
291 {
292  if (!m_towers.empty() && m_towers.back().nentries == nentries) {
293  unsigned int pos1 = m_entries.size() - 2*nentries;
294  unsigned int pos2 = m_entries.size() - nentries;
295  unsigned int phase = 0;
296  unsigned int n1 = 0;
297  unsigned int offs1 = 0;
298  unsigned int offs2 = 0;
299  for (size_t i = 0; i < nentries; i++) {
300  const Entry& ent1 = m_entries[pos1+i];
301  const Entry& ent2 = m_entries[pos2+i];
302  if (ent1.windex != ent2.windex ||
303  ent1.ncells != ent2.ncells ||
304  ent1.stride != ent2.stride)
305  {
306  phase = 3;
307  break;
308  }
309  unsigned int offs = ent2.hash - ent1.hash;
310  if (phase == 0) {
311  offs1 = offs;
312  n1 = 1;
313  phase = 1;
314  }
315  else if (phase == 1) {
316  if (offs == offs1)
317  ++n1;
318  else {
319  offs2 = offs;
320  phase = 2;
321  }
322  }
323  else if (phase == 2) {
324  if (offs != offs2) {
325  phase = 3;
326  break;
327  }
328  }
329  }
330 
331  if (phase == 1)
332  n1 = 0;
333 
334  if (phase < 3 &&
335  n1 <= Tower::n1_max &&
336  offs1 <= Tower::offs1_max &&
337  offs2 <= Tower::offs2_max)
338  {
339  //m_towers.back().nentries = 0;
340  assert (!m_towers.empty());
341  m_towers.back().backref_next = true;
342  m_towers.emplace_back(nentries, ncells, n1, offs1, offs2);
343  m_entries.resize (m_entries.size() - nentries);
344  return;
345  }
346  }
347  m_towers.emplace_back(nentries, ncells);
348 }
349 
350 
351 CaloTowerStore::Entry::Entry (unsigned int the_hash,
352  unsigned int the_windex,
353  unsigned int the_ncells /*= 1*/,
354  unsigned int the_stride /*= 0*/)
355  : hash (the_hash),
356  windex (the_windex),
357  ncells (the_ncells),
358  stride (the_stride)
359 {
360  assert (the_hash <= hash_max);
361  assert (the_windex <= windex_max);
362  assert (the_ncells <= ncells_max);
363  assert (the_stride <= stride_max);
364 }
365 
366 
367 CaloTowerStore::Tower::Tower (unsigned int the_nentries,
368  unsigned int the_ncells)
369  : nentries (the_nentries),
370  backref_next (false),
371  n1 (0),
372  ncells (the_ncells),
373  offs1 (0),
374  offs2 (0)
375 {
376  assert (the_nentries <= nentries_max);
377  assert (the_ncells <= ncells_max);
378 }
379 
380 
381 CaloTowerStore::Tower::Tower (unsigned int the_nentries,
382  unsigned int the_ncells,
383  unsigned int the_n1,
384  unsigned int the_offs1,
385  unsigned int the_offs2)
386  : nentries (the_nentries),
387  backref_next (false),
388  n1 (the_n1),
389  ncells (the_ncells),
390  offs1 (the_offs1),
391  offs2 (the_offs2)
392 {
393  assert (the_nentries <= nentries_max);
394  assert (the_ncells <= ncells_max);
395  assert (the_n1 <= n1_max);
396  assert (the_offs1 <= offs1_max);
397  assert (the_offs2 <= offs2_max);
398 }
399 
400 
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
max
#define max(a, b)
Definition: cfImp.cxx:41
CaloTowerStore.h
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
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:423
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:289
CaloDetDescrManager.h
Definition of CaloDetDescrManager.
CaloTowerSeg::nphi
index_t nphi() const
Retrieve number of bins.
Definition: CaloTowerSeg.h:428
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
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:367
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
CaloTowerSeg::dphi
double dphi() const
Retrieve bin size .
Definition: CaloTowerSeg.h:438
lumiFormat.i
int i
Definition: lumiFormat.py:92
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
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
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:157
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:351
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
Definition: IdentifierHash.h:38
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:74
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