ATLAS Offline Software
Loading...
Searching...
No Matches
CaloTopoTowerBuilderTool.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#include "CLHEP/Units/SystemOfUnits.h"
7
8#include "GaudiKernel/AlgTool.h"
9
10#include "Gaudi/Property.h"
11#include "GaudiKernel/Service.h"
12#include "GaudiKernel/IToolSvc.h"
13
15
17
18#include "CaloEvent/CaloCell.h"
21#include "CaloEvent/CaloTower.h"
22#include "CaloEvent/CaloTowerContainer.h"
24
26
28#include "CaloEvent/CaloCluster.h"
29
31
32#include <string>
33#include <cmath>
34
36 const std::string& type,
37 const IInterface* parent)
39 m_calo_id(nullptr)
40{
41 declareInterface<ICaloTopoTowerBuilderToolBase>(this);
42}
43
45= default;
46
48// Specific Initialization //
50
51// protected!
53{
54 ATH_MSG_INFO( "Initializing CaloTopoTowerAlg" );
55
56 ATH_CHECK(detStore()->retrieve(m_calo_id, "CaloCell_ID"));
57
58 return StatusCode::SUCCESS;
59}
60
62// Tower Builder //
64
65StatusCode CaloTopoTowerBuilderTool::execute(const EventContext& ctx,
66 CaloTopoTowerContainer* theTowers, const CaloCellContainer* /*theCells*/) const
67{
69 //Starting loading variables from CaloTopoTowerContainer
70
71 ATH_MSG_DEBUG("Loading variables from theTowers");
72 const CaloTowerContainer* towerContainer=theTowers->GetTowers();
73 const CaloClusterContainer* clusters=theTowers->GetClusters();
74 const CaloCellContainer* Cells=theTowers->GetCells();
75
76 if (!towerContainer || !clusters || !Cells) {
77 msg(MSG::WARNING) << " Missing input container : ";
78 if (!towerContainer) msg(MSG::WARNING) << " no tower ";
79 if (!clusters) msg(MSG::WARNING) << " no TopoClusters ";
80 if (!Cells) msg(MSG::WARNING) << " no Cells ";
81 msg(MSG::WARNING) << " .. no CaloTopoTowers are made " << endmsg;
82 return StatusCode::SUCCESS;
83 }
84
85 const ElementLink<CaloCellContainer> CellsEL (*Cells, 0, ctx);
86
87 const CaloCell2ClusterMap* cellToClusterMap=theTowers->GetCellToClusterMap();
88 bool delete_cellToClusterMap=false;
89 if(cellToClusterMap==nullptr ){
90 cellToClusterMap=CreateCaloCell2ClusterMap(clusters);
91 delete_cellToClusterMap=true;
92 }
93 ATH_MSG_DEBUG( "Tower size " << towerContainer->size() );
94 ATH_MSG_DEBUG( "Cluster size " << clusters->size() );
95 ATH_MSG_DEBUG( "Cell size " << Cells->size() );
96
97 double minimumCellEnergy = theTowers->GetMinimumCellEnergy();
98 double minimumClusterEnergy = theTowers->GetMinimumClusterEnergy();
99
100 bool useCellWeights = theTowers->GetUseCellWeights();
101
102 ATH_MSG_DEBUG("Energy cuts " << minimumCellEnergy << " " << minimumClusterEnergy << " " << useCellWeights);
103
104 float noiseSigma0 = theTowers->GetNoiseSigma();
105 float cellESignificanceThreshold = theTowers->GetCellESignificanceThreshold();
106
107
108 ATH_MSG_DEBUG("Noise cuts "<< noiseSigma0 << " " << cellESignificanceThreshold);
109
110 // List of calorimeters from which to use cells
111 std::vector<CaloCell_ID::SUBCALO> caloIndices = theTowers->GetCaloIndices();
112 bool caloSelection = theTowers->GetCaloSelection();
113
114 ATH_MSG_DEBUG("caloSelection " << caloSelection << " " << caloIndices.size());
115
116 //Finished loading variables from CaloTopoTowerContainer
119 const CaloClusterContainer* clusterContainer = nullptr;
120 CaloCell2ClusterMap::const_iterator fClusMap(cellToClusterMap->begin());
121 CaloCell2ClusterMap::const_iterator lClusMap(cellToClusterMap->end());
122 ATH_MSG_DEBUG("Starting loop over Navigable CaloCell2ClusterMap");
123 while ( clusterContainer == nullptr && fClusMap != lClusMap ){
124 ATH_MSG_VERBOSE("In loop over Navigable CaloCell2ClusterMap");
125 if (*fClusMap) {
126 // Pick first Navigable and then ask first entry in this
127 // Navigable for the pointer to the CaloClusterContainer.
128 // This should be sufficient because all entries should
129 // have the same pointer. (TBC)
130 ATH_MSG_DEBUG("CaloCell2ClusterMap has entry");
131 const nav_t* pNav = (*fClusMap);
132 clusterContainer = pNav->getContainer(pNav->begin());
133 ATH_MSG_DEBUG("Successfully picked up CaloClusterContainer ");
134 }
135 else ++fClusMap;
136 }
137
138 // Make sure the cluster container is not NULL
139 if ( clusterContainer == nullptr ) {
140 if (!Cells->empty() ) {
141 ATH_MSG_WARNING( "No cluster found from CaloCell2ClusterMap, tool unusable" );
142 }
143 else {
144 ATH_MSG_DEBUG(" empty calorimeter event .. return ");
145 }
146
147 if(delete_cellToClusterMap){
148 ATH_MSG_DEBUG( "Deleting cellToClusterMap Pointer");
149 delete cellToClusterMap;
150 ATH_MSG_DEBUG("Deleting cellToClusterMap Pointer Finished");
151 }
152
153 return StatusCode::SUCCESS;
154 }
155 else
156 ATH_MSG_DEBUG("Size of CaloClusterContainer = " << clusterContainer->size());
157
160 // (*towerIter) is the ITERATOR over TOWERS
161 // (*cellInTowerIter) is the ITERATOR over CELLS for this TOWER
162
163 ATH_MSG_DEBUG("Beginning loop over tower grid");
164
165 for (const CaloTower* tower : *towerContainer)
166 {
167 int towerIndex = towerContainer->getTowerIndex(tower);
168
169 CaloTower* newTower = theTowers->getTower(towerIndex);
170
172 ATH_MSG_VERBOSE("In loop over tower grid: tower eta-phi" << tower->eta() << " " << tower->phi());
173 CaloTower::cell_iterator cellInTowerIter(tower->cell_begin());
174 CaloTower::cell_iterator lastCellInTower(tower->cell_end());
175
177 double energyTower = 0.0;
178 double totalAttachedClusterEnergy = 0.0;
179 int numberOfCellsInTower = 0;
180 int numberOfAttachedCellsInTower = 0;
181 int numberOfClustersInTower = 0;
182 int totalNumberOfCellsInAttachedClusters = 0;
184 ATH_MSG_VERBOSE("Now looking at all cells in this tower");
185 for ( ; cellInTowerIter != lastCellInTower; cellInTowerIter++ ){
186 numberOfCellsInTower++;
187 // geometrical cell weight in towers
188 // **** Note that in the header it says that this gets the kinematic weight
189 // **** is this somehow different from the geometrical weight?
190 double signedE = 0.0; // zero-out the energy for this cell in case we can't get it from the map
191 double weight = tower->getCellWeight(cellInTowerIter); // get the weight of this cell in the tower
192
193 const CaloCell* cell = (*cellInTowerIter);
194 if (!cell) continue;
195
196 size_t globalIndex=0;
197 if (!(tower->getCellIndex(cell,globalIndex)) ) {
198 ATH_MSG_WARNING( " cannot find back cell index " );
199 continue;
200 }
201
202 if (caloSelection) {
203 CaloCell_ID::SUBCALO iCaloNum = (cell->caloDDE()->getSubCalo()); // keep only cells from desired calorimeter
204 std::vector<CaloCell_ID::SUBCALO>::const_iterator theFound =
205 find (caloIndices.begin(),caloIndices.end(),iCaloNum);
206 if (theFound==caloIndices.end()) continue ;
207 }
208
209 signedE = cell->e(); // get the cell energy if we got a good pointer
210 if (!useCellWeights) weight = 1.0; // if we chose not to use the cell weights, reset to 1.0
211 double cellEnergy = weight * signedE; // calculate the energy of this cell in this tower using the weight
212
213
214 float signedRatio=0;
215
216 float noiseSigma = 1.0;
217 if (cellESignificanceThreshold>=0.) {
218 noiseSigma = noiseSigma0;
219 if ( noiseSigma > 0. ) signedRatio = signedE/noiseSigma;
220 }
221
222 // WARNINGGING
223 ATH_MSG_VERBOSE( " Cell has E = " << signedE << " eta,phi " << cell->eta() << " " << cell->phi() );
224 ATH_MSG_VERBOSE( "Cell has E in tower = " << cellEnergy );
225 ATH_MSG_VERBOSE( " Cell noise sigma = " << noiseSigma );
226 ATH_MSG_VERBOSE( " Cell noise signif = " << signedRatio );
228 if ( (signedE > minimumCellEnergy) && ( fabs(signedRatio) > cellESignificanceThreshold) ){
229 // find clusters associated to this cell using the hash ID
230 size_t cellIndex(cell->caloDDE()->calo_hash());
231 ATH_MSG_VERBOSE("Cell index from CaloCell2ClusterMap = " << cellIndex);
232 const nav_t* nav = (cellToClusterMap->operator[])(cellIndex);
233
235 if (!nav) {
236 ATH_MSG_VERBOSE("No Cluster container from this cell!");
237 }
238 else{
240 ATH_MSG_VERBOSE("Cell associated to N clusters = " << nav->size());
241 nav_t::object_iter clusterIterator(nav->begin());
242 nav_t::object_iter lastCluster(nav->end());
243 for ( ; clusterIterator != lastCluster; clusterIterator++ ){
244 const CaloCluster* clusterFromCell = (*clusterIterator);
245 double eClusRaw = clusterFromCell->getBasicEnergy();
246 double eClus = clusterFromCell->energy();
247 ATH_MSG_VERBOSE( " Cluster Basic Energy = " << eClusRaw);
248 ATH_MSG_VERBOSE( " Cluster Normal Energy = " << eClus);
249
251 if ( eClusRaw > minimumClusterEnergy ){
252 ATH_MSG_VERBOSE("Cluster has at least E > " << minimumClusterEnergy);
253
254 numberOfAttachedCellsInTower++;
255 totalNumberOfCellsInAttachedClusters += clusterFromCell->getNumberOfCells();
256 totalAttachedClusterEnergy += eClusRaw;
257 energyTower += cellEnergy;
258 numberOfClustersInTower++;
259
260 newTower->addUniqueCellNoKine(CellsEL,globalIndex,weight, 10);
261
262 // now that we found the cell in at least one cluster above threshold, stop looking at associated clusters
263 ATH_MSG_VERBOSE(" -- Found at least one cluster passing cuts. 'break'");
264 break;
265
266 } // cluster filter
267 } // clusters from cell loop
268 ATH_MSG_VERBOSE("Finished cluster loop");
269 } // cluster associated to cell
270 } // cell filter
271 } // cell loop
272 ATH_MSG_VERBOSE("Finished cell loop");
273
275 newTower->setE(energyTower);
276
277 // Report some information about this Topo-Tower
278 if (msgLvl(MSG::VERBOSE)) {
279 msg() << endmsg;
280 ATH_MSG_VERBOSE( "Old/ new TopoTower energy from all cells = " << tower->e() << " " << newTower->e() );
281 ATH_MSG_VERBOSE( "TopoTower energy adding all cells in clusters = " << energyTower );
282 ATH_MSG_VERBOSE( "Total attached cluster energy = " << totalAttachedClusterEnergy );
283 ATH_MSG_VERBOSE( "Total number of attached clusters = " << numberOfClustersInTower );
284 ATH_MSG_VERBOSE( "Number of cells in attached clusters = " << totalNumberOfCellsInAttachedClusters );
285 ATH_MSG_VERBOSE( "Total number of cells originally in tower = " << numberOfCellsInTower );
286 ATH_MSG_VERBOSE( "Total number of cells from clusters = " << numberOfAttachedCellsInTower );
287
288 CaloTower::cell_iterator cellInTowerIter(newTower->cell_begin());
289 CaloTower::cell_iterator lastCellInTower(newTower->cell_end());
290 msg(MSG::VERBOSE) << " E*weight, eta, phi of cells in new tower ";
291 for ( ; cellInTowerIter != lastCellInTower; cellInTowerIter++ ) {
292 double weight = tower->getCellWeight(cellInTowerIter); // get the weight of this cell in the tower
293 const CaloCell* cell = (*cellInTowerIter);
294 if (!cell) continue;
295 msg(MSG::VERBOSE) << cell->e()*weight << " " << cell->eta() << " " << cell->phi() << " / ";
296 }
297 msg(MSG::VERBOSE) << endmsg;
298 }
299
300 } // tower loop
301 if(delete_cellToClusterMap){
302 ATH_MSG_DEBUG("Deleting cellToClusterMap Pointer");
303 delete cellToClusterMap;
304 ATH_MSG_DEBUG("Deleting cellToClusterMap Pointer Finished");
305 }
306 ATH_MSG_DEBUG("Finished creating TopoTowers");
307
308 return StatusCode::SUCCESS;
309}
310
311
314{
315 ATH_MSG_DEBUG("CreateCaloCell2ClusterMap() Starting");
316 CaloCell2ClusterMap *cell2ClusterMap;
317 cell2ClusterMap = new CaloCell2ClusterMap();
318 // resize it to total range of IdentifierHash for all calos
319 Identifier::size_type maxRange = m_calo_id->calo_cell_hash_max();
320 cell2ClusterMap->resize(maxRange);
321
322 ATH_MSG_DEBUG("CaloCluster container contains " << clusColl->size() << " clusters");
323 // loop over cluster collection and add each cluster to the map for
324 // each member cell
325 for (const CaloCluster* clust : *clusColl) {
326 // loop over its cell members
327 if ((clust->getNumberOfCells()) == 0 ) {
328 ATH_MSG_DEBUG(" no cells for this cluster... No reverse navigation possible...");
329 }
330 else {
331 CaloCluster::cell_iterator cellIter = clust->cell_begin();
332 CaloCluster::cell_iterator cellIterEnd = clust->cell_end();
333 for( ;cellIter!=cellIterEnd;cellIter++) {
334 // look up the IdentifierHash for the current cell
335 if (*cellIter) {
336 IdentifierHash myHashId = m_calo_id->calo_cell_hash((*cellIter)->ID());
337 // get the existing? Navigable for this cell
338 Navigable<CaloClusterContainer> *theNav = (*cell2ClusterMap)[myHashId];
339 if ( !theNav ) {
340 // create a new Navigable if it doesn't exist
341 theNav = new Navigable<CaloClusterContainer>();
342 // and store it in the vector
343 (*cell2ClusterMap)[myHashId] = theNav;
344 }
345 // add the current cluster to the list of clusters for this cell
346 theNav->putElement(clusColl,clust);
347 // add the energy*weight for this cell to the weightedESum
348 }
349 }
350 }
351 }
352 ATH_MSG_DEBUG("CreateCaloCell2ClusterMap() Finished");
353 return cell2ClusterMap;
354}
355
356
357
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
CaloPhiRange class declaration.
map of CaloCluster objects each CaloCell belongs to
Container class for CaloCell.
CaloCell_Base_ID::SUBCALO SUBCALO
Definition CaloCell_ID.h:50
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
Principal data class for CaloCell clusters.
virtual double getBasicEnergy() const
Access basic energy scale signal.
CaloCompositeCellBase< CaloClusterNavigable >::cell_iterator cell_iterator
Iterator on CaloCell s.
unsigned int getNumberOfCells() const
Return the number of cells in the store.
virtual double energy() const
Return energy.
void addUniqueCellNoKine(const CaloCellContainer *theContainer, index_type theIndex, double weight, size_t size_hint=0)
Add a cell (very fast)
cell_iterator cell_begin() const
Retrieve a STL-type begin() iterator for the cell store.
cell_iterator cell_end() const
Retrieve a STL-type end() iterator for the cell store.
CaloTopoTowerBuilderToolBase(const std::string &name, const std::string &type, const IInterface *parent)
AlgTool constructor.
CaloTopoTowerBuilderTool(const std::string &name, const std::string &type, const IInterface *parent)
AlgTool constructor.
virtual StatusCode initializeTool() override
const CaloCell2ClusterMap * CreateCaloCell2ClusterMap(const CaloClusterContainer *c) const
virtual ~CaloTopoTowerBuilderTool()
virtual StatusCode execute(const EventContext &ctx, CaloTopoTowerContainer *theContainer, const CaloCellContainer *theCell=0) const override
execute
Navigable< CaloClusterContainer > nav_t
Storable container class for CaloTower.
DataLink< CaloClusterContainer > GetClusters() const
float GetCellESignificanceThreshold() const
DataLink< CaloTowerContainer > GetTowers() const
DataLink< CaloCellContainer > GetCells() const
const std::vector< CaloCell_ID::SUBCALO > & GetCaloIndices() const
const CaloCell2ClusterMap * GetCellToClusterMap() const
Storable container class for CaloTower.
index_t getTowerIndex(const CaloTower *aTower) const
Returns the combined index of a tower on the grid.
CaloTower * getTower(index_t eta, index_t phi)
Returns a pointer to a tower with given indices.
Data class for calorimeter cell towers.
virtual double e() const override final
get energy data member
CaloEnergyCluster::cell_iterator cell_iterator
Iterator on CaloCell s.
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
void resize(size_type sz)
Resizes the collection to the specified number of elements.
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.
This is a "hash" representation of an Identifier.
Navigable template generalization to handle navigation.
Definition Navigable.h:93
virtual unsigned int size() const
virtual object_iter begin() const
void putElement(const CONT *objectContainer, const constituent_type *constituentObject, const RPAR &objectParameter=RPAR(), size_t sizeHint=0)
NavigableIterator< CaloClusterContainer, NavigationDefaults::DefaultWeight, typename NavigationDefaults::DefaultChildColl< CaloClusterContainer, NavigationDefaults::DefaultWeight >::type > object_iter
Definition Navigable.h:159
virtual object_iter end() const
const CONT * getContainer(const constituent_type *aConstituent) const
virtual void setE(double theE)
set energy data member
Definition P4EEtaPhiM.h:114
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:138
MsgStream & msg
Definition testRead.cxx:32