ATLAS Offline Software
CaloTopoTowerFromClusterMaker.cxx
Go to the documentation of this file.
1 /* Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration */
2 #include "GaudiKernel/MsgStream.h"
3 #include "GaudiKernel/SystemOfUnits.h"
4 
5 #include "AthenaKernel/Units.h"
6 
9 
11 
14 
15 #include "CaloGeoHelpers/CaloSampling.h"
17 #include "CaloGeoHelpers/proxim.h"
18 
19 #include "CaloProtoCluster.h"
20 
21 #include "CaloDetDescr/CaloDetDescrElement.h"
23 
24 #include <algorithm>
25 
26 #include <cstdio>
27 #include <cstdarg>
28 #include <string>
29 #include <cmath>
30 #include <memory>
31 #include <vector>
32 #include <atomic>
33 #include <tuple>
34 
35 namespace {
36  MsgStream& operator<<(MsgStream& mstr,const SG::ReadHandleKey<CaloCellContainer>& ckey) { mstr << ckey.key(); return mstr; }
37  MsgStream& operator<<(MsgStream& mstr,const SG::ReadHandleKey<xAOD::CaloClusterContainer>& ckey) { mstr << ckey.key(); return mstr; }
38 }
39 
41 
43 // CaloTopoTowerFromClusterMaker //
45 
46 const double CaloTopoTowerFromClusterMaker::m_energyThresholdDef = -100000000.; // in MeV
49 
51  const std::string& name,
52  const IInterface* pParent)
53  : AthAlgTool(type,name,pParent)
54  , m_clusterContainerKey("CaloTopoClusters")
55  , m_cellContainerKey("AllCalo")
56  , m_energyThreshold(m_energyThresholdDef-1.)
57  , m_clusterRange(m_clusterRangeDef)
58  // , m_numberOfCells(0)
59  // , m_maxCellHash(0)
60  , m_numberOfSamplings(static_cast<uint_t>(CaloSampling::Unknown))
61  // , m_numberOfTowers(0)
62 {
63  declareInterface<CaloTowerCollectionProcessor>(this);
64  declareProperty("CaloCellContainerKey", m_cellContainerKey, "SG Key for CaloCellContainer (input)");
65  declareProperty("BuildTopoTowers", m_useCellsFromClusters, "Turn on/off topo-tower formation");
66  declareProperty("CaloTopoClusterContainerKey", m_clusterContainerKey, "SG Key for CaloClusterContainer (input)");
67  declareProperty("OrderClusterByPt", m_orderByPt, "Turn on/off pT-ordering of CaloClusterContainer (output)");
68  declareProperty("ApplyCellEnergyThreshold", m_applyCellEnergyThreshold, "Turn on/off cell energy thresholds");
69  declareProperty("CellEnergyThreshold", m_energyThreshold, "Energy threshold for cells filled in clusters");
70  declareProperty("PrepareLCW", m_prepareLCW, "Prepare data structure to apply LCW");
71  declareProperty("ExcludedSamplings", m_excludedSamplingsName, "Excluded samplings by name");
72  declareProperty("DoCellIndexCheck", m_doCellIndexCheck, "Check cell hash indices for consistency");
73  declareProperty("BuildCombinedTopoSignal", m_buildCombinedSignal, "Build topo-clusters and topo-towers");
74  declareProperty("TopoClusterRange", m_clusterRange, "Rapidity range for using topo-clusters in combined signal mode");
75  declareProperty("RemoveSamplingData", m_removeSamplingData, "Remove the associated sampling data");
76 }
77 
79 {
80  //--------------------//
81  // Set up handle keys //
82  //--------------------//
83 
85 
86  //---------------------//
87  // Check configuration //
88  //---------------------//
89 
92 
93  // tower builder configurations
94  if ( m_useCellsFromClusters ) {
95  // topo-tower
96  ATH_MSG_INFO("Configure for building topo-towers (filtered mode):");
97  // energy threshold not (yet) implemented for topo-towers
99  ATH_MSG_WARNING("[ignore] cannot apply energy thresholds to topo-towers!");
101  }
103  // // check on request for LCW
104  // if ( m_prepareLCW ) {
105  // ATH_CHECK(m_cellClusterWeightKey.initialize());
106  // ATH_MSG_INFO("[accept] prepare for LCW calibration - initialize CaloCellClusterWeights key object <" << m_cellClusterWeightKey << ">");
107  // } else {
108  // ATH_MSG_INFO("[accept] use EM scale");
109  // }
110  } else {
111  // inclusive/exclusive towers
112  ATH_MSG_INFO("Configure for building cell towers:");
114  ATH_MSG_INFO("[accept] configure exclusive towers: use cell energy threshold");
116  ATH_MSG_ERROR("######## [reject] invalid cell energy threshold " << m_energyThreshold/Athena::Units::GeV
117  << " GeV is smaller than default (no-op) " << m_energyThresholdDef/Athena::Units::GeV << " GeV - fatal");
118  return StatusCode::FAILURE;
119  }
120  ATH_MSG_INFO("######## [accept] energy threshold for cells to contribute to towers is " << m_energyThreshold/Athena::Units::GeV << " GeV");
121  } else {
122  ATH_MSG_INFO("[accept] configure inclusive towers");
123  } // end inclusive/exclusive tower configuration
124  } // end tower builder configuration
125 
126  // local data (constant parameters)
127  //m_numberOfCells = m_towerGeometrySvc->totalNumberCells();
128  //m_maxCellHash = m_towerGeometrySvc->maxCellHash();
129  //m_numberOfTowers = m_towerGeometrySvc->towerBins();
130  // ATH_MSG_INFO("Additional tool parameters:");
131  // if ( m_numberOfCells > 0 ) {
132  // ATH_MSG_INFO("[accept] maximum cell hash index is " << m_maxCellHash);
133  // ATH_MSG_INFO("[accept] maximum number of cells is " << m_numberOfCells);
134  // } else {
135  // ATH_MSG_ERROR("[reject] invalid maximum cell hash index/total number of cells " << m_maxCellHash << "/" << m_numberOfCells << " - fatal");
136  // return StatusCode::FAILURE;
137  // }
138  // if ( m_numberOfTowers > 0 ) {
139  // ATH_MSG_INFO("[accept] maximum number of towers is " << m_numberOfTowers);
140  // } else {
141  // ATH_MSG_ERROR("[reject] invalid maximum number of towers " << m_numberOfTowers << " - fatal");
142  // return StatusCode::FAILURE;
143  // }
144 
145  if ( m_excludedSamplingsName.empty() ) {
146  m_excludedSamplings.clear();
148  ATH_MSG_INFO("Cells from all samplings used for topo-cluster included");
149  } else {
150  size_t nex(std::min(m_excludedSamplingsName.size(), m_excludedSamplingsPattern.size()));
151  if ( m_excludedSamplingsName.size() > m_excludedSamplingsPattern.size() ) {
152  ATH_MSG_WARNING( CaloRec::Helpers::fmtMsg("Configuration problem: number of excluded sampling names %zu exceeds expected maximum %zu - ignore last %zu name(s)",
154  }
155  m_excludedSamplings.resize(nex);
157  for ( size_t i(0); i<nex; ++i ) {
158  m_excludedSamplings[i] = CaloRec::Lookup::getSamplingId(m_excludedSamplingsName.at(i));
160  ATH_MSG_INFO( CaloRec::Helpers::fmtMsg("CaloSampling \042%10.10s\042 has id %2zu (name in lookup table \042%10.10s\042)",
161  m_excludedSamplingsName.at(i).c_str(),(size_t)m_excludedSamplings.at(i),CaloRec::Lookup::getSamplingName(m_excludedSamplings.at(i)).c_str()) );
162  }
163  }
164 
165  ATH_MSG_INFO("Other properties:");
166  std::map<bool,std::string> blu { { true, "true" }, { false, "false" } };
167  ATH_MSG_INFO( CaloRec::Helpers::fmtMsg("PrepareLCW ................. %s", blu[m_prepareLCW].c_str()) );
168  ATH_MSG_INFO( CaloRec::Helpers::fmtMsg("BuildTopoTowers ............ %s", blu[m_useCellsFromClusters].c_str()) );
169  ATH_MSG_INFO( CaloRec::Helpers::fmtMsg("ApplyCellEnergyThreshold ... %s", blu[m_applyCellEnergyThreshold].c_str()) );
170  ATH_MSG_INFO( CaloRec::Helpers::fmtMsg("OrderClusterByPt ........... %s", blu[m_orderByPt].c_str()) );
171  ATH_MSG_INFO( CaloRec::Helpers::fmtMsg("DoCellIndexCheck ........... %s", blu[m_doCellIndexCheck].c_str()) );
172  ATH_MSG_INFO( CaloRec::Helpers::fmtMsg("BuildCombinedTopoSignal .... %s", blu[m_buildCombinedSignal].c_str()) );
173  ATH_MSG_INFO( CaloRec::Helpers::fmtMsg("TopoClusterRange ........... %.2f", m_clusterRange) );
174  ATH_MSG_INFO( CaloRec::Helpers::fmtMsg("ExcludedSamplings .......... %zu (number of)",m_excludedSamplingsName.size()) );
175  ATH_MSG_INFO( CaloRec::Helpers::fmtMsg("RemoveSamplingData ......... %s", blu[m_removeSamplingData].c_str()) );
176 
177  return StatusCode::SUCCESS;
178 }
179 
181 { return StatusCode::SUCCESS; }
182 
184  xAOD::CaloClusterContainer* pClusCont,
185  CaloCellClusterWeights* cellWeights) const
186 {
188  // Check input //
190 
191  // CaloCellContainer is needed to construct CaloProtoCluster
193  if ( !pCellCont.isValid() ) {
194  ATH_MSG_ERROR("Cannot allocate CaloCellContainer with key <" << m_cellContainerKey << ">");
195  return StatusCode::FAILURE;
196  }
197 
199  const CaloTowerGeometry* towerGeo=*towerGeoHandle;
200 
202  const CaloDetDescrManager* caloDDMgr = *caloMgrHandle;
203 
204 
205  if ( msgLvl(MSG::DEBUG) && towerGeo->totalNumberCells() != pCellCont->size() ) {
206  ATH_MSG_DEBUG( CaloRec::Helpers::fmtMsg("[mismatch] number of cells in CaloCellContainer %6zu, total number of cell descriptors %6zu",
207  pCellCont->size(),towerGeo->totalNumberCells()) );
208  }
209 
210  if ( m_doCellIndexCheck ) { this->checkCellIndices(towerGeo,caloDDMgr, pCellCont.cptr()); }
211 
213  // Set up ProtoCluster //
215 
216  // index of CaloProtoCluster in container relates to tower position! DO NOT sort, shuffle, or remove elements!
217  size_t numberOfTowers=towerGeo->towerBins();
218  protocont_t pProtoCont; pProtoCont.reserve(numberOfTowers);
219  for ( uint_t i(0); i<numberOfTowers; ++i ) { pProtoCont.push_back(CaloProtoCluster(pCellCont.cptr())); }
220 
222  // Apply overall cell filter and fill protoclusters //
224 
225  // The weights extracted for cells from clusters are LCW weights (typically). The total
226  // contribution of a LCW-weighted cell to towers is Ecell*Weight_LCW*Weight_tower.
227 
228  // If EM clusters are used, the weights of a clustered cell are completely defined
229  // by the tower grid. As cells can shared between clusters, each cell can only be
230  // projected onto the towergrid once, with Ecell*Weight_tower
231 
232  // The CaloCellClusterWeights object is used to store the combined LCW weight.
233  // for each clustered cell. In case of EM, the LCW weights are ignored and this
234  // object is not used - a simple vector<bool> tags cells already put into towers.
235 
236  uint_t cCtr(0);
237  if ( m_useCellsFromClusters ) {
238  // retrieve topo-cluster container for topo-towers
240  if ( !pTopoClusCont.isValid() ) {
241  ATH_MSG_ERROR("Cannot allocate xAOD::CaloClusterContainer with key <" << m_clusterContainerKey << ">");
242  return StatusCode::FAILURE;
243  } // check on ReadHandle validity
244  cCtr = m_prepareLCW && cellWeights != nullptr ? this->buildLCWTopoTowers(towerGeo,*pTopoClusCont,pProtoCont,cellWeights) : this->buildEMTopoTowers(towerGeo,*pTopoClusCont,pProtoCont);
245  if ( !isValidIndex(cCtr) ) { ATH_MSG_WARNING("problems building EM or LCW topo-towers"); return StatusCode::SUCCESS; }
246  } else {
247  // fill inclusive/exclusive towers
248  cCtr = m_applyCellEnergyThreshold ? this->buildExclTowers(towerGeo,*pCellCont,pProtoCont) : this->buildInclTowers(towerGeo,*pCellCont,pProtoCont);
249  if ( !isValidIndex(cCtr) ) { ATH_MSG_WARNING("problems building EM inclusive or exclusive towers"); return StatusCode::SUCCESS; }
250  } // end topo-towers/inclusive-exclusive towers
251 
252 
253 
254  // allocate sufficient space in vector
255  pClusCont->reserve(cCtr);
256  // pick up cluster size tag and set up counter
258  // loop proto-clusters
259  for ( uint_t ipc(0); ipc<pProtoCont.size(); ++ipc ) {
260  CaloProtoCluster& pProto = pProtoCont.at(ipc); // pick up proto-cluster
261  std::unique_ptr<CaloClusterCellLink> lptr(pProto.releaseCellLinks()); // take over CaloClusterCellLink object
262  this->cleanupCells(towerGeo,lptr.get(),ipc); // clean up cell links
263  if ( CaloTopoTowerFromClusterMaker::filterProtoCluster(*lptr.get()) ) { // ignore empty proto-clusters (no cells assigned)
264  xAOD::CaloCluster* clptr = pClusCont->push_back(new xAOD::CaloCluster()); // new empty cluster
265  clptr->addCellLink(std::move(lptr)); // transfer cell links to CaloCluster
266  clptr->setClusterSize(csize); // set the cluster size spec
267  CaloRec::Helpers::calculateKine(clptr,false); // calculate kinematics and other signals from cells
268  if ( m_removeSamplingData ) { // remove sampling data and invalidate tower center
269  clptr->clearSamplingData(); clptr->setEta0(0.); clptr->setPhi0(0.);
270  } else { // keep sampling data and valid tower center
271  clptr->setEta0(towerGeo->towerEta(ipc)); clptr->setPhi0(towerGeo->towerPhi(ipc));
272  }
273  }
274  } // proto-cluster loop
275 
276  // clean up proto-cluster container
277  pProtoCont.clear();
278 
280  // Sorting //
282 
283  // All towers/clusters at this point are on EM scale. Sorting LCW towers by pT should be done in the
284  // CaloTopoClusterFromTowerCalibrator tool to assure desired ordering on the final scale.
285  // The link between tower location and index of tower representation (CaloCluster) in its
286  // container is definitively broken after sorting (was never ok in mixed cluster/tower mode).
287  if ( m_orderByPt ) {
288  std::sort(pClusCont->begin(),pClusCont->end(),[](xAOD::CaloCluster* pc1,xAOD::CaloCluster* pc2) {
289  volatile double pt1(pc1->pt()); // FIXME needed? (this was just copied)
290  volatile double pt2(pc2->pt()); // FIXME needed? (this was just copied)
291  return ( pt1 > pt2 );
292  }
293  );
294  } // end ordered by pT
295 
296  return StatusCode::SUCCESS;
297 } // end execute
298 
300 // Fill topo-towers //
302 
303 // EM
305 {
306  // presets
307  uint_t cCtr(0);
308  std::vector<bool> cellTags(towerGeo->totalNumberCells(),false);
309 
310  // -- EM scale clusters
311  if ( !m_buildCombinedSignal ) {
312  // topo-towers
313  for ( const auto *pClus : pClusCont ) {
314  for ( auto fCell(pClus->cell_begin()); fCell != pClus->cell_end(); ++fCell ) {
315  uint_t cidx(static_cast<uint_t>((*fCell)->caloDDE()->calo_hash()));
316  if ( cidx < cellTags.size() ) {
317  if ( !cellTags.at(cidx) ) { cellTags[cidx] = this->addCellToProtoCluster(towerGeo,*fCell,pProtoCont); }
318  } else {
319  ATH_MSG_ERROR( CaloRec::Helpers::fmtMsg("Invalid cell hash index %6zu >= maximum index %6zu for cell in %s at (eta,phi) = (%6.3,%f6.3)",
320  cidx,cellTags.size(),CaloSampling::getSamplingName((*fCell)->caloDDE()->getSampling()).c_str(),(*fCell)->eta(),(*fCell)->phi()) );
321  return m_errorValueUINT;
322  }
323  } // end cells-in-cluster loop
324  } // end cluster loop
325  } else {
326  // selected topo-towers for combined signal
327  std::vector<std::tuple<const CaloCell*,double> > cellList(towerGeo->totalNumberCells(),std::tuple<const CaloCell*,double>(nullptr,0.));
328  for ( const auto *pClus : pClusCont ) {
329  if ( std::abs(pClus->eta()) > m_clusterRange ) {
330  for ( auto fCell(pClus->cell_begin()); fCell != pClus->cell_end(); ++fCell ) {
331  uint_t cidx(static_cast<uint_t>((*fCell)->caloDDE()->calo_hash()));
332  if ( cellTags.at(cidx) ) {
333  std::get<1>(cellList[cidx]) += fCell.weight();
334  } else {
335  cellList[cidx] = std::tuple<const CaloCell*,double>(*fCell,fCell.weight());
336  cellTags[cidx] = true;
337  }
338  } // cell in cluster loop
339  } else {
340  ++cCtr;
341  } // cluster range check
342  } // cluster loop
343  // fill proto-cluster
344  for ( auto tpl : cellList ) { this->addCellToProtoCluster(towerGeo,std::get<0>(tpl),pProtoCont,std::get<1>(tpl)); }
345  } // end of fill mode
346 
347  //
348  return cCtr+pProtoCont.size();
349 }
350 
351 // LCW
353 {
354  // Need to keep track of LCW weights (up to two per cell) available from the topo-cluster(s) the cell is assigned to.
355  // Each cell in a topo-cluster is, at first occurance, added to the CaloProtoCluster(s) representing the tower(s) and its
356  // LCW calibration weight is stored in a lookup table indexed by the calorimeter hash id of the cell. The second
357  // time the same cell is found in another topo-cluster, only its LCW weight is added to the lookup table (stored in
358  // CaloCellClusterWeights for use in the downstream tower calibration tool) - the assignment to tower(s) has already
359  // happened.
360 
361  uint_t cCtr(0);
362  // project cells on tower grid
363  if ( !m_buildCombinedSignal ) {
364  // loop original topo-cluster container
365  for ( const auto *pClus : pClusCont ) {
366  // loop over cells in the original topo-cluster
367  for ( auto fCell(pClus->cell_begin()); fCell != pClus->cell_end(); ++fCell ) {
368  // map to towers only once
369  if ( !cellWeights->check(*fCell) ) { this->addCellToProtoCluster(towerGeo,*fCell,pProtoCont); }
370  // store all associated LCW weights
371  cellWeights->set(*fCell,fCell.weight());
372  } // end cells-in-cluster loop
373  } // end cluster loop
374  } else {
375  // loop topo-cluster
376  for ( const auto *pClus : pClusCont ) {
377  // keep top-clusters in configured eta range
378  if ( std::abs(pClus->eta()) > m_clusterRange ) {
379  // loop over cells of topo-clusters for the forward towards
380  for ( auto fCell(pClus->cell_begin()); fCell != pClus->cell_end(); ++fCell ) {
381  // map to towers only once
382  if ( !cellWeights->check(*fCell) ) { this->addCellToProtoCluster(towerGeo,*fCell,pProtoCont); }
383  // store all associated LCW weights
384  cellWeights->set(*fCell,fCell.weight());
385  } // end cells-in-cluster loop
386  } else {
387  ++cCtr;
388  } // end range check
389  } // end cluster loop
390  } // end combined signal check
391 
392  //
393  return cCtr+pProtoCont.size();
394 }
395 
397 // Fill towers //
399 
400 // inclusive
402 {
403  // loop cell container - counter icl replaces cell hash index for NULL pointers in cell container
404  uint_t icl(0);
405  for ( const auto *cptr : pCellCont ) {
406  if ( cptr == nullptr ) {
407  ATH_MSG_ERROR( CaloRec::Helpers::fmtMsg("CaloCellContainer[%6zu] contains invalid cell object pointer %p",icl,(void*)cptr) );
408  return m_errorValueUINT;
409  } else {
410  // existing cell with non-zero energy (negative or positive)
411  if ( std::fabs(cptr->e()) > 0. ) { this->addCellToProtoCluster(towerGeo,cptr,pProtoCont); }
412  } // end pointer check
413  ++icl;
414  } // end cell loop
415  return pProtoCont.size();
416 }
417 
418 // exclusive
420 {
421  // loop cell container
422  uint_t icl(0);
423  for ( const auto *cptr : pCellCont ) {
424  if ( cptr == nullptr ) {
425  ATH_MSG_ERROR( CaloRec::Helpers::fmtMsg("CaloCellContainer[%6zu] contains invalid cell object pointer %p",icl,(void*)cptr) );
426  return m_errorValueUINT;
427  } else {
428  // existing cell with energy above threshold
429  if ( cptr->e() > m_energyThreshold ) { this->addCellToProtoCluster(towerGeo,cptr,pProtoCont); }
430  } // end pointer check
431  ++icl;
432  } // end cell loop
433  //return StatusCode::SUCCESS;
434  return pProtoCont.size();
435 }
436 
438  protocont_t& pProtoCont,double weight) const
439 
440 {
441  // invalid input
442  if ( cptr == nullptr ) { return false; }
443 
444  // get towers for cell from geometry service
445  uint_t nctr(0);
446  for ( auto elm : towerGeo->getTowers(cptr->caloDDE()->calo_hash()) ) {
447  auto towerIdx(towerGeo->towerIndex(elm));
448  if ( !towerGeo->isInvalidIndex(towerIdx) ) {
449  if ( !m_excludedSamplingsPattern[(size_t)cptr->caloDDE()->getSampling()] ) {
450  uint_t cellIdx(pProtoCont.at(towerIdx).getCellLinks()->getCellContainer()->findIndex(cptr->caloDDE()->calo_hash()));
451  pProtoCont[towerIdx].addCell(cellIdx,towerGeo->cellWeight(elm)*weight); ++nctr;
452  }
453  }
454  }
455  return nctr > 0;
456 }
457 
459 // Helpers //
461 
464 
466 {
467  // check for tower sizes
468  return nTowers == 6400 // known "standard" towers 0,1 x 0.1
470  : nTowers == 25600 // known "fine" towers 0.05 x 0.05
472  : xAOD::CaloCluster::Tower_fixed_area; // unspecified towers
473 }
474 
476 {
477  // Any pathology here probably indicates a configuration problem with the conditions (geometry)
478  // database (wrong tag for data?)
479 
480  // check on null pointers in cell links
481  int nrc(0); int hid(0);
482  auto fcell(clk->begin());
483  while ( fcell != clk->end() ) {
484  const CaloCell* pCell = *fcell;
485  auto nc(clk->getCellContainer()->size());
486  const CaloCell* aCell = fcell.index() < nc ? clk->getCellContainer()->at(fcell.index()) : (const CaloCell*)nullptr;
487  if ( pCell == nullptr ) {
488  ATH_MSG_WARNING( CaloRec::Helpers::fmtMsg("CaloCellContainer[%6zu/%6zu] - tower %5zu at (%6.3f,%6.3f) - cell pointer invalid (%p/%p) [removed %3i of %3zu cells]",
489  fcell.index(),nc-1,nclus,towerGeo->towerEta(nclus),towerGeo->towerPhi(nclus),
490  (void*)pCell,(void*)aCell,++nrc,clk->size()) );
491  fcell = clk->removeCell(fcell);
492  } else {
493  uint_t chash(static_cast<uint_t>(pCell->caloDDE()->calo_hash()));
494  uint_t csamp(static_cast<uint_t>(pCell->caloDDE()->getSampling()));
495  if (chash > towerGeo->maxCellHash() ) {
496  // check cell hash
497  ATH_MSG_WARNING( CaloRec::Helpers::fmtMsg("Tower %5zu at (%6.3f,%6.3f) linked cell %3i - cell hash index (%6zu/%6zu) invalid",
498  nclus,towerGeo->towerEta(nclus),towerGeo->towerPhi(nclus),hid,chash,towerGeo->maxCellHash()) );
499  fcell = clk->removeCell(fcell); ++nrc;
500  } else if ( csamp >= m_numberOfSamplings ) {
501  // check sampling id
502  ATH_MSG_WARNING( CaloRec::Helpers::fmtMsg("Tower %5zu at (%6.3f,%6.3f) linked cell %3i -cell sampling id (%3zu/%3zu) invalid",
503  nclus,towerGeo->towerEta(nclus),towerGeo->towerPhi(nclus),hid,csamp,m_numberOfSamplings) );
504  fcell = clk->removeCell(fcell); ++nrc;
505  } else if ( fcell.weight() <= 0.0000001 ) {
506  // remove cells with 0 weight
507  fcell = clk->removeCell(fcell); ++nrc;
508  } else {
509  // next cell
510  ++fcell;
511  }
512  } // end remove cell due to pointer invalid
513  ++hid;
514  } // end loop on cells in cell link object
515  return nrc;
516 }
517 
519 { return clnk.size() > 0; }
520 
522  const CaloCellContainer* pCellCont) const
523 {
525  // input and setup checks //
527 
528  // check argument
529  if ( pCellCont == nullptr ) {
530  ATH_MSG_WARNING( CaloRec::Helpers::fmtMsg("Invalid pointer to CaloCellContainer (%p)",(void*)pCellCont) ); return false;
531  } else if ( pCellCont->empty() ) {
532  ATH_MSG_WARNING( CaloRec::Helpers::fmtMsg("CaloCellContainer at %p is empty (size %zu)",(void*)pCellCont,pCellCont->size()) ); return false;
533  }
534  // check the atomic state
535  if ( CaloTopoTowerFromClusterMaker_checkCellIndices ) { return true; }
536  // set the atomic flag
537  ATH_MSG_INFO( "Cell hash index check requested" );
539  // assign output file
540  std::string algname(this->name());
541  if ( algname.find_last_of('.') != std::string::npos ) { algname = algname.substr(algname.find_last_of('.')+1); }
542  std::string logname(CaloRec::Helpers::fmtMsg("%s.cellhash_index_check.dat",this->name().c_str()));
543  std::ofstream logstream; logstream.open(logname);
544  if ( !logstream.is_open() ) {
545  ATH_MSG_WARNING( CaloRec::Helpers::fmtMsg("Cannot open log file \042%s\042 - no hash index checking",logname.c_str()) );
546  return false;
547  }
548  logstream << "##########################################################################" << std::endl;
549  logstream << "### This file contains a list of CaloCell indices in CaloCellContainer ###" << std::endl;
550  logstream << "### for which this index is not the same as the calorimeter cell hash ###" << std::endl;
551  logstream << "### identifier. An empty list indicates full consistency between this ###" << std::endl;
552  logstream << "### index and the hash identifier for all cells. ###" << std::endl;
553  logstream << "##########################################################################" << std::endl;
554  logstream << "<begin list>--------------------------------------------------------------" << std::endl;
555 
557  // loop cell container //
559 
560  // prepare tag store
561  size_t ifc(0); std::bitset<200000> chkflg; chkflg.reset();
562  for ( size_t i(0); i<pCellCont->size(); ++i ) {
563  if ( pCellCont->at(i) != nullptr ) {
564  size_t chash((size_t)pCellCont->at(i)->caloDDE()->calo_hash());
565  if ( chash != i ) {
566  std::string cni("UKNOWN");
567  double etai(0.); double phii(0.);
568  const CaloDetDescrElement* iel = i < caloDDMgr->element_size() ? caloDDMgr->get_element(i) : nullptr;
569  if ( iel != nullptr ) {
570  cni = CaloRec::Lookup::getSamplingName(iel->getSampling());
571  etai = iel->eta_raw();
572  phii = iel->phi_raw();
573  }
574  std::string cnc("UNKNOWN");
575  double etac(0.); double phic(0.);
576  const CaloDetDescrElement* cel = chash < caloDDMgr->element_size() ? caloDDMgr->get_element(chash) : nullptr;
577  if ( cel != nullptr ) {
578  cnc = CaloRec::Lookup::getSamplingName(cel->getSampling());
579  etac = cel->eta_raw();
580  phic = cel->phi_raw();
581  }
582  size_t cidx(pCellCont->findIndex(chash));
583  logstream << CaloRec::Helpers::fmtMsg("[%06zu] Cell %6zu [%12.12s %5.3f %5.3f] non-matching id %6zu [%12.12s %5.3f %5.3f] findCell() index %6zu",
584  ++ifc,i,cni.c_str(),etai,phii,chash,cnc.c_str(),etac,phic,cidx) << std::endl;
585  }
586  chkflg.set(chash);
587  }
588  }
589  logstream << "<end list>----------------------------------------------------------------" << std::endl;
590  logstream.close();
591 
593  // check missed hashes //
595 
596  // number of non-matched hashes
597  if ( ifc > 0 ) {
598  ATH_MSG_DEBUG( CaloRec::Helpers::fmtMsg("Found %zu non-matching cell hashes",ifc) );
599  }
600  // list of non-matched hashes
601  std::vector<size_t> chl; chl.reserve(towerGeo->totalNumberCells());
602  for ( size_t i(0); i<chl.size(); ++i ) { if ( !chkflg.test(i) ) { chl.push_back(i); } }
603  if ( !chl.empty() ) {
604  for ( auto h : chl ) { ATH_MSG_DEBUG( CaloRec::Helpers::fmtMsg("Cell hash %6zu not in CaloCellContainer",h) ); }
605  }
606 
607  return true;
608 }
609 
DataVector::reserve
void reserve(size_type n)
Attempt to preallocate enough memory for a specified number of elements.
CaloClusterKineHelper.h
GetLCDefs::Unknown
@ Unknown
Definition: GetLCDefs.h:21
CaloTopoTowerFromClusterMaker::buildLCWTopoTowers
uint_t buildLCWTopoTowers(const CaloTowerGeometry *towerGeo, const xAOD::CaloClusterContainer &clusCont, protocont_t &protoCont, CaloCellClusterWeights *cellWeights) const
LCW topo-towers.
Definition: CaloTopoTowerFromClusterMaker.cxx:352
CaloTopoTowerFromClusterMaker::m_orderByPt
bool m_orderByPt
Orders cluster container by , default true.
Definition: CaloTopoTowerFromClusterMaker.h:70
getMenu.algname
algname
Definition: getMenu.py:54
GeV
#define GeV
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/Root/HelperFunctions.cxx:17
CaloTopoTowerFromClusterMaker::filterProtoCluster
static bool filterProtoCluster(const CaloClusterCellLink &clnk)
Checks for and removes invalid cell links
Definition: CaloTopoTowerFromClusterMaker.cxx:518
xAOD::CaloCluster_v1::ClusterSize
ClusterSize
Enumeration to identify different cluster sizes.
Definition: CaloCluster_v1.h:86
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
SG::ReadHandle::cptr
const_pointer_type cptr()
Dereference the pointer.
xAOD::CaloCluster_v1::Tower_01_01
@ Tower_01_01
Definition: CaloCluster_v1.h:109
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
xAOD::CaloCluster_v1::clearSamplingData
void clearSamplingData()
Clear the sampling data.
Definition: CaloCluster_v1.cxx:717
CaloDetDescrElement
This class groups all DetDescr information related to a CaloCell. Provides a generic interface for al...
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:66
ConvertOldUJHistosToNewHistos.etaBins
list etaBins
Definition: ConvertOldUJHistosToNewHistos.py:145
CaloDetDescrManager_Base::get_element
const CaloDetDescrElement * get_element(const Identifier &cellId) const
get element by its identifier
Definition: CaloDetDescrManager.cxx:159
CaloSampling
provides Calorimeter Sampling enum
Definition: Calorimeter/CaloGeoHelpers/CaloGeoHelpers/CaloSampling.h:17
CaloProtoCluster
Definition: CaloProtoCluster.h:14
CaloTopoTowerFromClusterMaker::m_clusterContainerKey
SG::ReadHandleKey< xAOD::CaloClusterContainer > m_clusterContainerKey
Topo-cluster container key.
Definition: CaloTopoTowerFromClusterMaker.h:68
AthCommonMsg< AlgTool >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
CaloCellClusterWeights::check
bool check(size_t hash) const
Safe checking if cell is used by any cluster.
Definition: CaloCellClusterWeights.cxx:38
CaloRec::Helpers::fmtMsg
std::string fmtMsg(const char *fmt,...)
Definition: CaloTopoClusterFromTowerHelpers.cxx:13
CaloTowerGeometry::towerPhi
double towerPhi(index_t towerIndex) const
Return azimuth from global tower index (bin center)
Definition: CaloTowerGeometry.h:327
CaloTopoTowerFromClusterMaker::m_applyCellEnergyThreshold
bool m_applyCellEnergyThreshold
Apply cell energy threshold, default is false.
Definition: CaloTopoTowerFromClusterMaker.h:73
SG::ReadHandleKey< CaloCellContainer >
CaloCellClusterWeights::set
void set(size_t hash, double value)
Definition: CaloCellClusterWeights.cxx:41
CaloTopoTowerFromClusterMaker::buildExclTowers
uint_t buildExclTowers(const CaloTowerGeometry *towerGeo, const CaloCellContainer &pCellCont, protocont_t &pProtoCont) const
Exclusive towers.
Definition: CaloTopoTowerFromClusterMaker.cxx:419
xAOD::CaloCluster_v1::setEta0
void setEta0(flt_t)
CaloDetDescrManager.h
Definition of CaloDetDescrManager.
CaloTopoTowerFromClusterMaker::m_cellContainerKey
SG::ReadHandleKey< CaloCellContainer > m_cellContainerKey
Calorimeter cell container.
Definition: CaloTopoTowerFromClusterMaker.h:69
CaloDetDescrElement::eta_raw
float eta_raw() const
cell eta_raw
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:350
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:189
xAOD::CaloCluster_v1::Tower_005_005
@ Tower_005_005
Definition: CaloCluster_v1.h:110
CaloTopoTowerFromClusterMaker::checkCellIndices
bool checkCellIndices(const CaloTowerGeometry *towerGeo, const CaloDetDescrManager *caloDDM, const CaloCellContainer *pCellCont) const
Checks consistency between cell indices and hash identifiers.
Definition: CaloTopoTowerFromClusterMaker.cxx:521
CaloTopoTowerFromClusterMaker::m_energyThresholdDef
static const double m_energyThresholdDef
Default energy threshold.
Definition: CaloTopoTowerFromClusterMaker.h:87
proxim.h
CaloTowerGeometry::maxCellHash
uint_t maxCellHash() const
Maximum cell hash value.
Definition: CaloTowerGeometry.h:280
CaloTopoTowerFromClusterMaker::protocont_t
std::vector< CaloProtoCluster > protocont_t
Container for CaloProtoCluster objects.
Definition: CaloTopoTowerFromClusterMaker.h:57
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:59
CaloDetDescrElement::calo_hash
IdentifierHash calo_hash() const
cell calo hash
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:412
CaloTopoTowerFromClusterMaker::m_clusterRange
double m_clusterRange
Range where topo-clusters are used when m_buildCombinedSignal = true
Definition: CaloTopoTowerFromClusterMaker.h:77
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
CaloTopoTowerFromClusterMaker::m_doCellIndexCheck
bool m_doCellIndexCheck
Check cell hash index consistency if true (default false)
Definition: CaloTopoTowerFromClusterMaker.h:74
xAOD::CaloCluster_v1::setPhi0
void setPhi0(flt_t)
Set raw of cluster seed.
CaloTopoTowerFromClusterMaker::m_buildCombinedSignal
bool m_buildCombinedSignal
Build topo-clusters within given range, else topo-towers.
Definition: CaloTopoTowerFromClusterMaker.h:75
lumiFormat.i
int i
Definition: lumiFormat.py:85
CaloTopoTowerFromClusterMaker::isValidIndex
bool isValidIndex(uint_t idx) const
Checks if argument is a valid index value.
Definition: CaloTopoTowerFromClusterMaker.h:146
CaloTopoTowerFromClusterMaker.h
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
CaloProtoCluster.h
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
CaloCell::caloDDE
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
Definition: CaloCell.h:305
CaloTopoTowerFromClusterMaker::m_towerGeoKey
SG::ReadCondHandleKey< CaloTowerGeometry > m_towerGeoKey
the name of the key of the CaloTowerGeometry object in the ConditonsStore
Definition: CaloTopoTowerFromClusterMaker.h:65
CaloTopoTowerFromClusterMaker::m_excludedSamplings
std::vector< CaloSampling::CaloSample > m_excludedSamplings
List of excluded samplings (CaloSampling::CaloSample enumerators)
Definition: CaloTopoTowerFromClusterMaker.h:135
CaloTopoTowerFromClusterMaker::m_caloMgrKey
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloMgrKey
Definition: CaloTopoTowerFromClusterMaker.h:66
CaloTowerGeometry::towerEta
double towerEta(index_t towerIndex) const
Return pseudorapidity from global tower index (bin center)
Definition: CaloTowerGeometry.h:326
xAOD::CaloCluster_v1::Tower_fixed_area
@ Tower_fixed_area
Definition: CaloCluster_v1.h:111
CaloTopoTowerFromClusterMaker::getClusterSize
static xAOD::CaloCluster::ClusterSize getClusterSize(uint_t etaBins, uint_t phiBins)
Returns a cluster size tag from number of eta and phi bins in tower grid.
Definition: CaloTopoTowerFromClusterMaker.cxx:462
CaloTopoTowerFromClusterMaker::CaloTopoTowerFromClusterMaker
CaloTopoTowerFromClusterMaker(const std::string &type, const std::string &name, const IInterface *pParent)
Tool constructor.
Definition: CaloTopoTowerFromClusterMaker.cxx:50
CaloPhiRange.h
CaloPhiRange class declaration.
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
CaloTopoTowerFromClusterMaker::buildInclTowers
uint_t buildInclTowers(const CaloTowerGeometry *towerGeo, const CaloCellContainer &pCellCont, protocont_t &pProtoCont) const
Inclusive towers.
Definition: CaloTopoTowerFromClusterMaker.cxx:401
CaloTopoTowerFromClusterMaker::addCellToProtoCluster
bool addCellToProtoCluster(const CaloTowerGeometry *towerGeo, const CaloCell *cptr, protocont_t &pProtoCont, double weight=1.) const
Adding cells to proto-clusters.
Definition: CaloTopoTowerFromClusterMaker.cxx:437
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
CaloTopoTowerFromClusterMaker_checkCellIndices
std::atomic< bool > CaloTopoTowerFromClusterMaker_checkCellIndices(false)
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
CaloTowerGeometry::towerBins
uint_t towerBins() const
Total number of towers.
Definition: CaloTowerGeometry.h:293
CaloTopoTowerFromClusterMaker::m_prepareLCW
bool m_prepareLCW
Prepare LCW calibration, default is false.
Definition: CaloTopoTowerFromClusterMaker.h:71
CaloTopoTowerFromClusterMaker::initialize
virtual StatusCode initialize() override
Setting up the operational mode and corresponding parameters.
Definition: CaloTopoTowerFromClusterMaker.cxx:78
CaloRec::Helpers::calculateKine
bool calculateKine(xAOD::CaloCluster *pClus, bool onlyKine=false)
Kinematic updates.
Definition: CaloTopoClusterFromTowerHelpers.cxx:118
CaloTopoTowerFromClusterMaker::m_errorValueUINT
static const uint_t m_errorValueUINT
Error value for uint_t type values.
Definition: CaloTopoTowerFromClusterMaker.h:89
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
CaloTopoTowerFromClusterMaker::uint_t
std::size_t uint_t
Unsigned integral type.
Definition: CaloTopoTowerFromClusterMaker.h:58
CaloTowerGeometry
Tower geometry store and description provider.
Definition: CaloTowerGeometry.h:23
LArConditions2Ntuple.ckey
string ckey
Definition: LArConditions2Ntuple.py:162
CaloTopoTowerFromClusterMaker::m_excludedSamplingsName
std::vector< std::string > m_excludedSamplingsName
List of excluded samplings (human-readable names)
Definition: CaloTopoTowerFromClusterMaker.h:136
CaloTopoTowerFromClusterMaker::m_numberOfSamplings
uint_t m_numberOfSamplings
Number of samplings.
Definition: CaloTopoTowerFromClusterMaker.h:85
operator<<
std::ostream & operator<<(std::ostream &lhs, const TestGaudiProperty &rhs)
Definition: TestGaudiProperty.cxx:69
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
Units.h
Wrapper to avoid constant divisions when using units.
CaloCellContainer
Container class for CaloCell.
Definition: CaloCellContainer.h:55
CaloTopoTowerFromClusterMaker::m_removeSamplingData
bool m_removeSamplingData
Remove sampling data for towers.
Definition: CaloTopoTowerFromClusterMaker.h:78
CaloCellClusterWeights
Hash lookup of calibration weights for calorimeter cells.
Definition: CaloCellClusterWeights.h:23
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
CaloTowerGeometry::towerIndex
index_t towerIndex(IdentifierHash cellHash) const
Get global tower index for a calorimeter cell referenced by its hash identifier.
Definition: CaloTowerGeometry.h:309
CaloTowerGeometry::totalNumberCells
uint_t totalNumberCells() const
Total number of cells.
Definition: CaloTowerGeometry.h:281
CaloProtoCluster::releaseCellLinks
CaloClusterCellLink * releaseCellLinks()
Hand over ownership of CaloClusterCellLink to client.
Definition: CaloProtoCluster.h:53
xAOD::CaloCluster_v1::addCellLink
void addCellLink(CaloClusterCellLink *CCCL)
Definition: CaloCluster_v1.h:721
h
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
xAOD::CaloCluster_v1::setClusterSize
void setClusterSize(const ClusterSize)
Get cluster size.
Definition: CaloCluster_v1.cxx:369
CaloDetDescrElement::getSampling
CaloCell_ID::CaloSample getSampling() const
cell sampling
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:395
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
CaloTopoTowerFromClusterMaker::m_clusterRangeDef
static const double m_clusterRangeDef
Default cluster range.
Definition: CaloTopoTowerFromClusterMaker.h:88
CaloDetDescrManager_Base::element_size
calo_element_vec_size element_size() const
total number of elements
Definition: CaloDetDescrManager.cxx:105
CaloTopoClusterFromTowerHelpers.h
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
DEBUG
#define DEBUG
Definition: page_access.h:11
CaloCellContainer::findIndex
int findIndex(const IdentifierHash theHash) const
Return index of the cell with a given hash.
Definition: CaloCellContainer.cxx:363
CaloTopoTowerFromClusterMaker::buildEMTopoTowers
uint_t buildEMTopoTowers(const CaloTowerGeometry *towerGeo, const xAOD::CaloClusterContainer &clusCont, protocont_t &protoCont) const
EM topo-towers.
Definition: CaloTopoTowerFromClusterMaker.cxx:304
CaloTopoTowerFromClusterMaker::execute
virtual StatusCode execute(const EventContext &ctx, xAOD::CaloClusterContainer *pClusCont, CaloCellClusterWeights *cellWeights) const override
Execute the tool and fill the xAOD::CaloClusterContainer pointed to by pClusCont.
Definition: CaloTopoTowerFromClusterMaker.cxx:183
CaloTopoTowerFromClusterMaker::m_excludedSamplingsPattern
std::bitset< _CALOTOPOTOWERFROMCLUSTERMAKER_BITSET_SIZE > m_excludedSamplingsPattern
Bit pattern indicates if sampling is excluded.
Definition: CaloTopoTowerFromClusterMaker.h:137
CaloTopoTowerFromClusterMaker::finalize
virtual StatusCode finalize() override
Finalize the tool (no action)
Definition: CaloTopoTowerFromClusterMaker.cxx:180
CaloSampling::getSamplingName
static std::string getSamplingName(CaloSample theSample)
Returns a string (name) for each CaloSampling.
Definition: Calorimeter/CaloGeoHelpers/Root/CaloSampling.cxx:18
DataVector::at
const T * at(size_type n) const
Access an element, as an rvalue.
AthAlgTool
Definition: AthAlgTool.h:26
CaloTopoTowerFromClusterMaker::m_useCellsFromClusters
bool m_useCellsFromClusters
Use cells from topo-clusters if true, else use all cells, default is true.
Definition: CaloTopoTowerFromClusterMaker.h:72
CaloTowerGeometry::cellWeight
double cellWeight(const element_t &elm) const
Retrieve cell signal weight from lookup table entry.
Definition: CaloTowerGeometry.h:337
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
CaloTowerGeometry::getTowers
elementvector_t getTowers(IdentifierHash cellHash) const
Retrieve the list of towers associated with a calorimeter cell referenced by its hash identifier.
Definition: CaloTowerGeometry.cxx:254
MakeSliceSet.logname
logname
Definition: MakeSliceSet.py:34
DataVector::empty
bool empty() const noexcept
Returns true if the collection is empty.
plotBeamSpotMon.nc
int nc
Definition: plotBeamSpotMon.py:83
CaloTopoTowerFromClusterMaker::cleanupCells
int cleanupCells(const CaloTowerGeometry *towerGeo, CaloClusterCellLink *clk, uint_t nclus) const
Checks CaloClusterCellLink for consistency.
Definition: CaloTopoTowerFromClusterMaker.cxx:475
CaloTopoTowerFromClusterMaker::m_energyThreshold
double m_energyThreshold
Cell energy threshold, default is set in m_energyThresholdDef.
Definition: CaloTopoTowerFromClusterMaker.h:76
CaloTowerGeometry::isInvalidIndex
bool isInvalidIndex(index_t idx) const
Returns true if argument is equal to the value provided by invalidIndex()
Definition: CaloTowerGeometry.h:299
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
CaloDetDescrElement::phi_raw
float phi_raw() const
cell phi_raw
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:352
CaloCellClusterWeights.h