ATLAS Offline Software
Loading...
Searching...
No Matches
CaloTopoTowerAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
21
23#include "CaloEvent/CaloTowerContainer.h"
26#include "CaloTopoTowerAlg.h"
27#include <string>
28
32CaloTopoTowerAlg::CaloTopoTowerAlg(const std::string& name,ISvcLocator* pSvcLocator):
33 AthReentrantAlgorithm(name, pSvcLocator),
34 m_cellToClusterMapKey("CaloCell2TopoCluster"),
35 m_cellContainerKey("AllCalo"),
36 m_towerContainerKey("CmbTower"),
37 m_newTowerContainerKey("TopoTower"),
38 m_caloSelection(false)
39{
40
41 // Containers needed for this algorithm
42 declareProperty("Cell2ClusterMapName", m_cellToClusterMapKey);
43 declareProperty("CellContainerName" , m_cellContainerKey);
44 declareProperty("InputTowerContainerName" , m_towerContainerKey);
45 declareProperty("OutputTowerContainerName", m_newTowerContainerKey );
46
47 // Declare configurable properties of the algorithm
48 declareProperty("MinimumCellEnergy", m_minimumCellEnergy = -1000000000.0);
49 declareProperty("MinimumClusterEnergy", m_minimumClusterEnergy = -1000000000.0);
50
51 declareProperty("CellEnergySignificance", m_cellESignificanceThreshold = -1);
52
53 // Calo from which to use cells
54 declareProperty("IncludedCalos", m_includedCalos);
55
56 declareProperty("useCellWeight", m_useCellWeights=true);
57
58}
59
64= default;
65
70{
71 return StatusCode::SUCCESS;
72}
73
78{
79 // services
80 ATH_MSG_INFO( "Initializing CaloTopoTowerAlg" );
81
82 ATH_CHECK(m_cellToClusterMapKey.initialize());
83 ATH_CHECK(m_cellContainerKey.initialize());
84 ATH_CHECK(m_towerContainerKey.initialize());
86
87 ATH_CHECK(m_noiseCDOKey.initialize());
88
89 m_caloIndices.clear();
90 for ( unsigned int iCalos=0; iCalos< m_includedCalos.size(); iCalos++ )
91 {
92 if ( m_includedCalos[iCalos] == "LAREM" )
93 {
95 }
96 else if ( m_includedCalos[iCalos] == "LARHEC")
97 {
99 }
100 else if ( m_includedCalos[iCalos] == "LARFCAL" )
101 {
103 }
104 else if ( m_includedCalos[iCalos] == "TILE" )
105 {
107 }
108 }
109
110 m_caloSelection=false;
111 unsigned int nSubCalo=static_cast<int>(CaloCell_ID::NSUBCALO) ;
112 if (!m_caloIndices.empty() && m_caloIndices.size()<nSubCalo) m_caloSelection=true;
113
114 ATH_MSG_INFO( " Calo selection applied ? " << m_caloSelection );
115 if (m_caloSelection) {
116 msg(MSG::INFO) << " subcalo selected ";
117 for (unsigned int iCalos=0;iCalos< m_includedCalos.size(); iCalos++ ) msg(MSG::INFO) << " " << m_includedCalos[iCalos];
118 msg(MSG::INFO) << " " << endmsg;
119 }
120
121 // check setup
122 return StatusCode::SUCCESS;
123}
124
128StatusCode CaloTopoTowerAlg::execute (const EventContext& ctx) const
129{
131 ATH_MSG_DEBUG( "In CaloTopoTowerAlg::execute()" );
132
134
136 if ( !towerContainer.isValid()) {
137 ATH_MSG_WARNING( " cannot retrieve tower container with key " << towerContainer.name() );
138 return StatusCode::SUCCESS;
139 }
140
141
144 if (newTowerContainer.record( std::make_unique<CaloTowerContainer> (towerContainer->towerseg()) ).isFailure()){
145 ATH_MSG_WARNING( " cannot record new tower container with key " << towerContainer.name() );
146 return StatusCode::SUCCESS;
147 }
148 newTowerContainer->init();
149
152 if ( !theCells.isValid()) {
153 ATH_MSG_WARNING( " cannot retrieve cell container with key " << theCells.name() );
154 return StatusCode::SUCCESS;
155 }
156
157 // EL to the container, to allow making other ELs quickly.
158 ElementLink<CaloCellContainer> theCellsEL (m_cellContainerKey.key(), 0, ctx);
159
161 const CaloClusterContainer* clusterContainer = nullptr;
162
164
165 if ( !cellToClusterMap.isValid() )
166 {
167 ATH_MSG_WARNING( "cannot retrieve CaloCell2ClusterMap with key <"
168 << cellToClusterMap.name() << ">" );
169 return StatusCode::SUCCESS;
170 }
171 ATH_MSG_DEBUG( "Successfully retrieved CaloCell2ClusterMap <"<< cellToClusterMap.name() << ">" );
172
175 const CaloNoise* noise=*noiseHdl;
176
177
179 CaloCell2ClusterMap::const_iterator fClusMap(cellToClusterMap->begin());
180 CaloCell2ClusterMap::const_iterator lClusMap(cellToClusterMap->end());
181 ATH_MSG_DEBUG( "Starting loop over Navigable CaloCell2ClusterMap" );
182 while ( clusterContainer == nullptr && fClusMap != lClusMap )
183 {
184 ATH_MSG_VERBOSE( "In loop over Navigable CaloCell2ClusterMap" );
185 if (*fClusMap)
186 {
187 // Pick first Navigable and then ask first entry in this
188 // Navigable for the pointer to the CaloClusterContainer.
189 // This should be sufficient because all entries should
190 // have the same pointer. (TBC)
191 ATH_MSG_DEBUG( "CaloCell2ClusterMap has entry" );
192 const nav_t* pNav = (*fClusMap);
193 clusterContainer = pNav->getContainer(pNav->begin());
194 ATH_MSG_DEBUG( "Successfully picked up CaloClusterContainer " );
195 }
196 else ++fClusMap;
197 }
198
199 // Make sure the cluster container is not NULL
200 if ( clusterContainer == nullptr )
201 {
202 if (!theCells->empty() ) {
203 ATH_MSG_WARNING( "No cluster found from CaloCell2ClusterMap, tool unusable" );
204 return StatusCode::SUCCESS;
205 }
206 else {
207 ATH_MSG_DEBUG( " empty calorimeter event .. return " );
208 return StatusCode::SUCCESS;
209 }
210 }
211 else ATH_MSG_DEBUG( "Size of CaloClusterContainer = " << clusterContainer->size() );
212
214 // (*towerIter) is the ITERATOR over TOWERS
215 // (*cellInTowerIter) is the ITERATOR over CELLS for this TOWER
216
217 ATH_MSG_DEBUG( "Beginning loop over tower grid" );
218
219 for (const CaloTower* theTower : *towerContainer) {
220 int towerIndex = towerContainer->getTowerIndex(theTower);
221
222 CaloTower* newTower = newTowerContainer->getTower(towerIndex);
223
225 ATH_MSG_VERBOSE( "In loop over tower grid: tower eta-phi" << theTower->eta() << " " << theTower->phi() );
226 CaloTower::cell_iterator cellInTowerIter(theTower->cell_begin());
227 CaloTower::cell_iterator lastCellInTower(theTower->cell_end());
228
230 double energyTower = 0.0;
231 double totalAttachedClusterEnergy = 0.0;
232 int numberOfCellsInTower = 0;
233 int numberOfAttachedCellsInTower = 0;
234 int numberOfClustersInTower = 0;
235 int totalNumberOfCellsInAttachedClusters = 0;
236
238 ATH_MSG_VERBOSE( "Now looking at all cells in this tower" );
239 for ( ; cellInTowerIter != lastCellInTower; cellInTowerIter++ )
240 {
241 numberOfCellsInTower++;
242 // geometrical cell weight in towers
243 // **** Note that in the header it says that this gets the kinematic weight
244 // **** is this somehow different from the geometrical weight?
245 double signedE = 0.0; // zero-out the energy for this cell in case we can't get it from the map
246 double weight = theTower->getCellWeight(cellInTowerIter); // get the weight of this cell in the tower
247
248 const CaloCell* cell = (*cellInTowerIter);
249 if (!cell) continue;
250
251 size_t globalIndex=0;
252 if (!(theTower->getCellIndex(cell,globalIndex)) ) {
253 ATH_MSG_WARNING( " cannot find back cell index " );
254 continue;
255 }
256
257 if (m_caloSelection) {
258 CaloCell_ID::SUBCALO iCaloNum = (cell->caloDDE()->getSubCalo()); // keep only cells from desired calorimeter
259 std::vector<CaloCell_ID::SUBCALO>::const_iterator theFound =
260 find (m_caloIndices.begin(),m_caloIndices.end(),iCaloNum);
261 if (theFound==m_caloIndices.end()) continue ;
262 }
263
264 signedE = cell->e(); // get the cell energy if we got a good pointer
265 if (!m_useCellWeights) weight = 1.0; // if we chose not to use the cell weights, reset to 1.0
266 double cellEnergy = weight * signedE; // calculate the energy of this cell in this tower using the weight
267
268
269 float signedRatio=0;
270
271 float noiseSigma = 1.0;
273 // Noise tool to calculate cell energy significance
274 noiseSigma=noise->getNoise(cell->ID(),cell->gain());
275 if ( noiseSigma > 0. ) signedRatio = signedE/noiseSigma;
276 }
277
278 // DEBUGGING
279 ATH_MSG_VERBOSE( " Cell has E = " << signedE << " eta,phi " << cell->eta() << " " << cell->phi() );
280 ATH_MSG_VERBOSE( "Cell has E in tower = " << cellEnergy );
281 ATH_MSG_VERBOSE( " Cell noise sigma = " << noiseSigma );
282 ATH_MSG_VERBOSE( " Cell noise signif = " << signedRatio );
283
285 if ( (signedE > m_minimumCellEnergy) && ( fabs(signedRatio) > m_cellESignificanceThreshold) )
286 {
287 // find clusters associated to this cell using the hash ID
288 size_t cellIndex(cell->caloDDE()->calo_hash());
289 ATH_MSG_VERBOSE( "Cell index from CaloCell2ClusterMap = " << cellIndex );
290 const nav_t* nav = (cellToClusterMap->operator[])(cellIndex);
291
293 if (!nav) {
294 ATH_MSG_VERBOSE( "No Cluster container from this cell!" );
295 }
296 else
297 {
299 ATH_MSG_VERBOSE( "Cell associated to N clusters = " << nav->size() );
300 for (const CaloCluster* clusterFromCell : *nav) {
301 double eClusRaw = clusterFromCell->getBasicEnergy();
302 double eClus = clusterFromCell->energy();
303 ATH_MSG_VERBOSE( " Cluster Basic Energy = " << eClusRaw );
304 ATH_MSG_VERBOSE( " Cluster Normal Energy = " << eClus );
305
307 if ( eClusRaw > m_minimumClusterEnergy )
308 {
309 ATH_MSG_VERBOSE( "Cluster has at least E > " << m_minimumClusterEnergy );
310
311 numberOfAttachedCellsInTower++;
312 totalNumberOfCellsInAttachedClusters += clusterFromCell->getNumberOfCells();
313 totalAttachedClusterEnergy += eClusRaw;
314 energyTower += cellEnergy;
315 numberOfClustersInTower++;
316
317 newTower->addUniqueCellNoKine(theCellsEL,globalIndex,weight, 10);
318
319 // now that we found the cell in at least one cluster above threshold, stop looking at associated clusters
320 ATH_MSG_VERBOSE( " -- Found at least one cluster passing cuts. 'break'" );
321 break;
322
323 } // cluster filter
324 } // clusters from cell loop
325 ATH_MSG_VERBOSE( "Finished cluster loop" );
326 } // cluster associated to cell
327 } // cell filter
328 } // cell loop
329 ATH_MSG_VERBOSE( "Finished cell loop" );
330
332 newTower->setE(energyTower);
333
334 // Report some information about this Topo-Tower
335 if (msgLvl(MSG::VERBOSE)) {
336 ATH_MSG_VERBOSE( "" );
337 ATH_MSG_VERBOSE( "Old/ new TopoTower energy from all cells = " << theTower->e() << " " << newTower->e() );
338 ATH_MSG_VERBOSE( "TopoTower energy adding all cells in clusters = " << energyTower );
339 ATH_MSG_VERBOSE( "Total attached cluster energy = " << totalAttachedClusterEnergy );
340 ATH_MSG_VERBOSE( "Total number of attached clusters = " << numberOfClustersInTower );
341 ATH_MSG_VERBOSE( "Number of cells in attached clusters = " << totalNumberOfCellsInAttachedClusters );
342 ATH_MSG_VERBOSE( "Total number of cells originally in tower = " << numberOfCellsInTower );
343 ATH_MSG_VERBOSE( "Total number of cells from clusters = " << numberOfAttachedCellsInTower );
344 CaloTower::cell_iterator cellInTowerIter(newTower->cell_begin());
345 CaloTower::cell_iterator lastCellInTower(newTower->cell_end());
346 msg(MSG::VERBOSE) << " E*weight, eta, phi of cells in new tower ";
347 for ( ; cellInTowerIter != lastCellInTower; cellInTowerIter++ ) {
348 double weight = theTower->getCellWeight(cellInTowerIter); // get the weight of this cell in the tower
349 const CaloCell* cell = (*cellInTowerIter);
350 if (!cell) continue;
351 msg(MSG::VERBOSE) << cell->e()*weight << " " << cell->eta() << " " << cell->phi() << " / ";
352 }
353 msg(MSG::VERBOSE) << endmsg;
354 }
355
356 } // tower loop
357
358 ATH_MSG_DEBUG( "Finished creating TopoTowers" );
359
360 return StatusCode::SUCCESS;
361
362}
#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)
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
bool msgLvl(const MSG::Level lvl) const
An algorithm that can be simultaneously executed in multiple threads.
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.
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.
CaloTopoTowerAlg(const std::string &name, ISvcLocator *pSvcLocator)
AlgTool constructor.
virtual StatusCode execute(const EventContext &ctx) const override
Execute.
virtual StatusCode initialize() override
initialize
Navigable< CaloClusterContainer > nav_t
std::vector< CaloCell_ID::SUBCALO > m_caloIndices
SG::ReadCondHandleKey< CaloNoise > m_noiseCDOKey
Key of the CaloNoise Conditions data object.
std::vector< std::string > m_includedCalos
SG::ReadHandleKey< CaloCellContainer > m_cellContainerKey
SG::WriteHandleKey< CaloTowerContainer > m_newTowerContainerKey
virtual ~CaloTopoTowerAlg()
Destructor.
SG::ReadHandleKey< CaloTowerContainer > m_towerContainerKey
virtual StatusCode finalize() override
finalize
SG::ReadHandleKey< CaloCell2ClusterMap > m_cellToClusterMapKey
float m_cellESignificanceThreshold
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
size_type size() const noexcept
Returns the number of elements in the collection.
virtual unsigned int size() const
virtual object_iter begin() const
const CONT * getContainer(const constituent_type *aConstituent) const
virtual void setE(double theE)
set energy data member
Definition P4EEtaPhiM.h:114
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const std::string & name() const
Return the StoreGate ID for the referenced object.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:138