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