ATLAS Offline Software
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 
32 CaloTopoTowerAlg::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 
86 
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  {
106  m_caloIndices.push_back(CaloCell_ID::TILE);
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 
128 StatusCode 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.
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 }
CaloEnergyCluster::cell_begin
cell_iterator cell_begin() const
Retrieve a STL-type begin() iterator for the cell store.
Definition: CaloEnergyCluster.cxx:270
CaloTowerContainer::getTower
CaloTower * getTower(index_t eta, index_t phi)
Returns a pointer to a tower with given indices.
Definition: CaloTowerContainer.cxx:266
CaloCell_Base_ID::LARFCAL
@ LARFCAL
Definition: CaloCell_Base_ID.h:46
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
CaloEnergyCluster::cell_end
cell_iterator cell_end() const
Retrieve a STL-type end() iterator for the cell store.
Definition: CaloEnergyCluster.cxx:275
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
CaloTopoTowerAlg::m_includedCalos
std::vector< std::string > m_includedCalos
Definition: CaloTopoTowerAlg.h:89
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
SG::VarHandleBase::name
const std::string & name() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleBase.cxx:75
CaloClusterContainer
Storable container for CaloCluster.
Definition: Calorimeter/CaloEvent/CaloEvent/CaloClusterContainer.h:37
Navigable::begin
virtual object_iter begin() const
CaloTopoTowerAlg::m_caloSelection
bool m_caloSelection
Definition: CaloTopoTowerAlg.h:91
AthCommonMsg< Gaudi::Algorithm >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
CaloCell_Base_ID::LARHEC
@ LARHEC
Definition: CaloCell_Base_ID.h:46
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
CaloTopoTowerAlg::m_caloIndices
std::vector< CaloCell_ID::SUBCALO > m_caloIndices
Definition: CaloTopoTowerAlg.h:90
CaloTowerContainer::init
void init()
Initializes the CaloTowerContainer.
Definition: CaloTowerContainer.cxx:107
CaloEnergyCluster::addUniqueCellNoKine
void addUniqueCellNoKine(const CaloCellContainer *theContainer, index_type theIndex, double weight, size_t size_hint=0)
Add a cell (very fast)
Definition: CaloEnergyCluster.cxx:125
CaloTopoTowerAlg::m_noiseCDOKey
SG::ReadCondHandleKey< CaloNoise > m_noiseCDOKey
Key of the CaloNoise Conditions data object.
Definition: CaloTopoTowerAlg.h:81
CaloCell_ID.h
CaloTopoTowerAlg::execute
virtual StatusCode execute(const EventContext &ctx) const override
Execute.
Definition: CaloTopoTowerAlg.cxx:128
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:83
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:200
CaloTopoTowerAlg::m_towerContainerKey
SG::ReadHandleKey< CaloTowerContainer > m_towerContainerKey
Definition: CaloTopoTowerAlg.h:71
CaloTower::cell_iterator
CaloEnergyCluster::cell_iterator cell_iterator
Iterator on CaloCell s.
Definition: Calorimeter/CaloEvent/CaloEvent/CaloTower.h:94
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
CaloCell_Base_ID::SUBCALO
SUBCALO
enumeration of sub calorimeters
Definition: CaloCell_Base_ID.h:46
CaloTopoTowerAlg::m_cellToClusterMapKey
SG::ReadHandleKey< CaloCell2ClusterMap > m_cellToClusterMapKey
Definition: CaloTopoTowerAlg.h:69
CaloCell2ClusterMap.h
CaloCluster
Principal data class for CaloCell clusters.
Definition: Calorimeter/CaloEvent/CaloEvent/CaloCluster.h:79
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
CaloTopoTowerAlg::m_newTowerContainerKey
SG::WriteHandleKey< CaloTowerContainer > m_newTowerContainerKey
Definition: CaloTopoTowerAlg.h:72
CaloCell_Base_ID::TILE
@ TILE
Definition: CaloCell_Base_ID.h:46
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
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
CaloTower
Data class for calorimeter cell towers.
Definition: Calorimeter/CaloEvent/CaloEvent/CaloTower.h:55
CaloNoise
Definition: CaloNoise.h:16
CaloTower::e
virtual double e() const override final
get energy data member
Definition: Calorimeter/CaloEvent/CaloEvent/CaloTower.h:135
CaloTowerContainer::towerseg
const CaloTowerSeg & towerseg() const
Return a copy of the attached CaloTowerSeg.
Definition: Calorimeter/CaloEvent/CaloEvent/CaloTowerContainer.h:591
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
CaloTopoTowerAlg.h
Navigable::getContainer
const CONT * getContainer(const constituent_type *aConstituent) const
CaloTopoTowerAlg::m_useCellWeights
bool m_useCellWeights
Definition: CaloTopoTowerAlg.h:77
CaloTopoTowerAlg::m_cellESignificanceThreshold
float m_cellESignificanceThreshold
Definition: CaloTopoTowerAlg.h:83
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
CaloCellContainer.h
Navigable
Navigable template generalization to handle navigation.
Definition: Navigable.h:93
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
Navigable::size
virtual unsigned int size() const
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
CaloCell
Data object for each calorimeter readout cell.
Definition: CaloCell.h:57
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
AthCommonMsg< Gaudi::Algorithm >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
P4EEtaPhiM::setE
virtual void setE(double theE)
set energy data member
Definition: P4EEtaPhiM.h:114
CaloTopoTowerAlg::CaloTopoTowerAlg
CaloTopoTowerAlg(const std::string &name, ISvcLocator *pSvcLocator)
AlgTool constructor.
Definition: CaloTopoTowerAlg.cxx:32
CaloTopoTowerAlg::m_minimumClusterEnergy
double m_minimumClusterEnergy
Definition: CaloTopoTowerAlg.h:76
CaloTopoTowerAlg::~CaloTopoTowerAlg
virtual ~CaloTopoTowerAlg()
Destructor
CaloCell_Base_ID::NSUBCALO
@ NSUBCALO
Definition: CaloCell_Base_ID.h:46
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:14
CaloTopoTowerAlg::m_minimumCellEnergy
double m_minimumCellEnergy
Definition: CaloTopoTowerAlg.h:75
CaloTopoTowerAlg::m_cellContainerKey
SG::ReadHandleKey< CaloCellContainer > m_cellContainerKey
Definition: CaloTopoTowerAlg.h:70
CaloCell_Base_ID::LAREM
@ LAREM
Definition: CaloCell_Base_ID.h:46
CaloTopoTowerAlg::initialize
virtual StatusCode initialize() override
initialize
Definition: CaloTopoTowerAlg.cxx:77
CaloTopoTowerAlg::finalize
virtual StatusCode finalize() override
finalize
Definition: CaloTopoTowerAlg.cxx:69
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
DataVector::empty
bool empty() const noexcept
Returns true if the collection is empty.
WriteCellNoiseToCool.noise
noise
Definition: WriteCellNoiseToCool.py:380
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.