ATLAS Offline Software
CaloTowerxAODAlgoBase.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
9 
11 #include "CaloDetDescr/CaloDetDescrElement.h"
14 
15 CaloTowerxAODAlgoBase::CaloTowerxAODAlgoBase(const std::string& name,ISvcLocator* pSvcLocator)
16  : AthReentrantAlgorithm(name,pSvcLocator),
17  m_caloTowerContainerKey("CmbTowers") {
18  declareProperty("CaloTowerContainer", m_caloTowerContainerKey,"Output xAOD::CaloTowerContainer");
19  declareProperty("minEta",m_minEta=-5,"Tower-grid: lower eta boundary");
20  declareProperty("maxEta",m_maxEta=5,"Tower-grid: upper eta boundary");
21  declareProperty("nEta",m_nEtaBins=100,"Tower-grid: number of phi bins");
22  declareProperty("nPhi",m_nPhiBins=64,"Tower-grid: number of phi bins");
23  declareProperty("doCrossChecks",m_doxCheck=false,"Turn on internal checks (debugging)");
24 }
25 
27 = default;
28 
29 
31  ATH_CHECK( m_caloTowerContainerKey.initialize() );
33  return StatusCode::SUCCESS;
34 }
35 
36 
38 CaloTowerxAODAlgoBase::makeContainer (const EventContext& ctx) const
39 {
42 
43  if( caloTowerContainer.record (std::make_unique<xAOD::CaloTowerContainer>(),
44  std::make_unique<xAOD::CaloTowerAuxContainer>()).isSuccess())
45  {
46  // configure the container
48 
49  //Prefill the container:
50  const int nTowers=caloTowerContainer->nTowers();
51 
52  for (int iTower=0;iTower<nTowers;++iTower) {
53  xAOD::CaloTower* tower=new xAOD::CaloTower();
54  caloTowerContainer->push_back(tower);
55  tower->setEnergy(0.0);
56  }
57  }
58 
59  return caloTowerContainer;
60 }
61 
62 
64 {
65  if(!m_cellToTower.isValid()) {
66  CellToTowerVec cellToTower;
67  if(fillIndexCache(ctx,cellToTower).isFailure()) cellToTower.clear();
68  m_cellToTower.set(std::move(cellToTower));
69  }
70  return *m_cellToTower.ptr();
71 }
72 
73 StatusCode CaloTowerxAODAlgoBase::fillIndexCache(const EventContext& ctx, CellToTowerVec& cellToTower) const
74 {
75  ATH_MSG_INFO("Filling cell -> tower index map");
76 
77  //Some basic sanity checks:
78  if (m_minEta>=m_maxEta) {
79  ATH_MSG_ERROR( "Configuration problem: minEta>=maxEta " << m_minEta << "," << m_maxEta );
80  return StatusCode::FAILURE;
81  }
82 
84  ATH_CHECK(caloMgrHandle.isValid());
85  const CaloDetDescrManager* theManager = *caloMgrHandle;
86 
87  //Build a dummy CaloTowerContainer
88  std::unique_ptr<xAOD::CaloTowerContainer> dummy(new xAOD::CaloTowerContainer());
89 
91 
92  const int nTowers=dummy->nTowers();
93 
94  if (nTowers<1) {
95  ATH_MSG_ERROR( "Something went wrong with tower grid config: Got container with " << nTowers << " Towers." );
96  return StatusCode::FAILURE;
97  }
98 
99  ATH_MSG_INFO("Working on tower container with dEta=" << dummy->deltaEta() << ", dPhi="
100  << dummy->deltaPhi() << ", nTowers=" << nTowers);
101 
102  cellToTower.clear();
103  cellToTower.resize(theManager->element_size()); //fixme, get calo-hash-max
104 
105  //FCAL cells are not pointing. We slice them in smaller chunks to see in which tower they go
106  const std::array<double,3> ndxFCal={{4.,4.,6.}};
107  const std::array<double,3> ndyFCal={{4.,6.,6.}};
108 
110  ddeIt!=theManager->element_end();++ddeIt) {
111 
112  const CaloDetDescrElement* dde=*ddeIt;
113 
114  if (dde->is_lar_fcal()) {
115  //special handling of FCAL cells. Inspired by LArRecUtils/src/LArFCalTowerStore.cxx
116  double xCell = dde->x();
117  double yCell = dde->y();
118  double zCell = dde->z();
119  double dxCell = dde->dx();
120  double dyCell = dde->dy();
121 
122  // get cell logical location
123  int thisModule = dde->getLayer()-1; //modules are counted 1..n, convert to 0..n-1
124  double theXBin = dxCell / ndxFCal[thisModule];
125  double theYBin = dyCell / ndyFCal[thisModule];
126  double theWeight = 1. / (ndxFCal[thisModule] * ndyFCal[thisModule]);
127 
128  // loop the cell fragments
129  for (int iX=0;iX<ndxFCal[thisModule];++iX) {
130  double x=xCell-dxCell/2.0 + iX*theXBin;
131  for (int iY=0;iY<ndyFCal[thisModule];++iY) {
132  double y=yCell-dyCell/2.0 + iY*theYBin;
133 
134  // eta,phi of fragment
135  double r = sqrt( x * x + y * y + zCell * zCell );
136  double eta = -0.5 * log((r-zCell)/(r+zCell));
137  double phi = CaloPhiRange::fix(atan2(y,x));
138  //int towerIdx=xAOD::CaloTowerGrid::index(dummy.get(),eta,phi);
139  int towerIdx=dummy->index(eta,phi);
140  if (towerIdx>=nTowers || towerIdx<0) {
141  ATH_MSG_ERROR("Found invalid tower index for FCAL cell eta/phi " << eta << "/" << phi << ", x/y=" << x << "/" << y);
142  return StatusCode::FAILURE;
143  }
144  //m_cellToTower[dde->calo_hash()].push_back(cellToTower_t(towerIdx,theWeight));
145  cellToTower[dde->calo_hash()].emplace_back(towerIdx,theWeight);
146  ATH_MSG_VERBOSE("cell hash " << dde->calo_hash() << ", goes into tower " << towerIdx << " with weight " << theWeight);
147  } //end y loop
148  } //end x loop
149  }//end FCAL
150 
151  else { //Non-FCAL subcalos:
152 
153  const double cellDeta = dde->deta();
154  const double cellDphi = dde->dphi();
155  const double etaRaw = dde->eta_raw();
156  const double phiRaw = CaloPhiRange::fix(dde->phi_raw());
157  //The following lines ar copied from the old CaloTowerStore.cxx
158  // calculate cell/tower size ratio (integer,[1..n])
159  size_t ke = (size_t) (cellDeta/dummy->deltaEta()+0.5);
160  ke = (ke==0) ? 1 : ke;
161  size_t kp = (size_t) (cellDphi/dummy->deltaPhi()+0.5);
162  kp = (kp==0) ? 1 : kp;
163  // signal weight
164  if ( ke>1 || kp>1 ) {
165  ATH_MSG_VERBOSE( "Found cell [0x" << std::hex << dde->identify().get_compact() << std::dec
166  << "] spanning several towers. nEta=" << ke << "nPhi="<<kp );
167  }
168 
169 
170  double theWeight = 1. / ( (double) ke * kp );
171  // fractional cell sizes
172  double cellDdeta = cellDeta / (double) ke;
173  double cellDdphi = cellDphi / (double) kp;
174  double etaMin = etaRaw - cellDeta / 2.;
175  double phiMin = phiRaw - cellDphi / 2.;
176 
177  //Loop over cell fragments:
178 
179  for ( size_t ie=1; ie<=ke; ie++ ){ // outer (eta) fragment loop
180  double cellEta = etaMin + ((double)ie - 0.5) * cellDdeta; // eta of fragment
181  for ( size_t ip=1; ip<=kp; ip++ ){ // inner (phi) fragement loop
182  double cellPhi = phiMin + ((double)ip - 0.5) * cellDdphi; // phi of fragment
183  int towerIdx=dummy->index(cellEta,cellPhi);
184  if (towerIdx>=nTowers || towerIdx<0) {
185  ATH_MSG_ERROR("Found invalid tower index " << towerIdx << " for cell eta/phi " << cellEta << "/" << cellPhi << " coming from " << dde->calo_hash() << "/" << ie << "/" << ip);
186  return StatusCode::FAILURE;
187  }
188  cellToTower[dde->calo_hash()].push_back(cellToTower_t(towerIdx,theWeight));
189  ATH_MSG_VERBOSE("cell hash " << dde->calo_hash() << ", goes into tower " << towerIdx << "with weight" << theWeight);
190  }//end loop over fragments (phi)
191  }// end loop over fragments (eta)
192  }//end else FCAL
193  }//end loop over detDescrElements
194 
195 
196  if (m_doxCheck) {
197  const CaloCell_ID* caloCellId;
198  ATH_CHECK(detStore()->retrieve(caloCellId));
199  for (size_t i=0;i<cellToTower.size(); ++i) {
200  const auto& towerinfo=cellToTower[i];
201  if (!towerinfo.empty()) {
202  ATH_MSG_DEBUG("Cell with index " << i << " contributes to " << towerinfo.size() << " Towers.");
203  }
204  else {
205  const Identifier id=caloCellId->cell_id(i);
206  ATH_MSG_ERROR("Cell with index " << i << ", id=0x"
207  << std::hex << id.get_identifier32().get_compact() << std::dec
208  << "does not contribute to any tower!");
209  }
210  double sumWeight=0;
211  for (const cellToTower_t& ct : towerinfo) sumWeight+=ct.m_weight;
212  if (fabs(sumWeight-1)>0.001) {
213  const Identifier id=caloCellId->cell_id(i);
214  ATH_MSG_ERROR( "Cell with index " << i << ", id=0x"
215  << std::hex << id.get_identifier32().get_compact() << std::dec
216  << ": Weights don't add up to 1.0, got " << sumWeight );
217  }
218  }//end loop over cells
219  }//end if doxCheck
220 
221  ATH_MSG_DEBUG("Built CelltoTower index table. nCells=" << cellToTower.size() << ", nTowers=" << nTowers);
222 
223  return StatusCode::SUCCESS;
224 }
CaloDetDescrElement::deta
float deta() const
cell deta
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:356
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
beamspotman.r
def r
Definition: beamspotman.py:676
CxxUtils::CachedValue::ptr
const T * ptr() const
Return a pointer to the cached value.
xAOD::CaloTowerContainer_v1
Basic container storing all information need for xAOD::CaloTower_v1 objects.
Definition: CaloTowerContainer_v1.h:21
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:64
CaloDetDescrManager_Base::element_end
calo_element_const_iterator element_end() const
end of element vector
Definition: CaloDetDescrManager.cxx:117
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
CaloTowerxAODAlgoBase::~CaloTowerxAODAlgoBase
~CaloTowerxAODAlgoBase()
destructor
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
CaloDetDescrElement::y
float y() const
cell y
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:365
CaloTowerxAODAlgoBase::cellToTower_t
Definition: CaloTowerxAODAlgoBase.h:57
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
CaloTowerxAODAlgoBase::initBase
StatusCode initBase()
<
Definition: CaloTowerxAODAlgoBase.cxx:30
AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
CxxUtils::CachedValue::isValid
bool isValid() const
Test to see if the value is valid.
CaloTowerxAODAlgoBase::getIndexCache
const CellToTowerVec & getIndexCache(const EventContext &ctx) const
Definition: CaloTowerxAODAlgoBase.cxx:63
CaloDetDescrElement
This class groups all DetDescr information related to a CaloCell. Provides a generic interface for al...
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:66
CaloTowerxAODAlgoBase::m_doxCheck
bool m_doxCheck
Turn on internal checks (debugging)
Definition: CaloTowerxAODAlgoBase.h:46
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
x
#define x
CaloTowerAuxContainer.h
CaloDetDescrManager.h
Definition of CaloDetDescrManager.
CaloDetDescrElement::eta_raw
float eta_raw() const
cell eta_raw
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:350
CaloCell_ID.h
AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:83
PlotCalibFromCool.ie
ie
Definition: PlotCalibFromCool.py:420
CaloDetDescrElement::identify
Identifier identify() const override final
cell identifier
Definition: CaloDetDescrElement.cxx:64
CaloTowerxAODAlgoBase::fillIndexCache
StatusCode fillIndexCache(const EventContext &ctx, CellToTowerVec &cellToTower) const
Definition: CaloTowerxAODAlgoBase.cxx:73
CaloDetDescrElement::calo_hash
IdentifierHash calo_hash() const
cell calo hash
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:412
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
CaloTowerContainer.h
CaloTowerxAODAlgoBase::CellToTowerVec
std::vector< std::vector< cellToTower_t > > CellToTowerVec
Definition: CaloTowerxAODAlgoBase.h:63
lumiFormat.i
int i
Definition: lumiFormat.py:92
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
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
CaloTowerxAODAlgoBase::m_maxEta
float m_maxEta
Tower-grid: upper eta boundary.
Definition: CaloTowerxAODAlgoBase.h:43
xAOD::CaloTower
CaloTower_v1 CaloTower
Definition: Event/xAOD/xAODCaloEvent/xAODCaloEvent/CaloTower.h:13
CaloTowerxAODAlgoBase::m_minEta
float m_minEta
Tower-grid: lower eta boundary.
Definition: CaloTowerxAODAlgoBase.h:42
CaloTowerxAODAlgoBase::makeContainer
SG::WriteHandle< xAOD::CaloTowerContainer > makeContainer(const EventContext &ctx) const
Intialize m_cellToTower cache.
Definition: CaloTowerxAODAlgoBase.cxx:38
CaloTowerxAODAlgoBase.h
find_tgc_unfilled_channelids.ip
ip
Definition: find_tgc_unfilled_channelids.py:3
CaloPhiRange.h
CaloPhiRange class declaration.
python.xAODType.dummy
dummy
Definition: xAODType.py:4
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
CaloTowerxAODAlgoBase::m_caloMgrKey
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloMgrKey
Definition: CaloTowerxAODAlgoBase.h:49
CaloCell_ID
Helper class for offline cell identifiers.
Definition: CaloCell_ID.h:34
CaloTowerxAODAlgoBase::m_nEtaBins
int m_nEtaBins
Tower-grid: number of phi bins.
Definition: CaloTowerxAODAlgoBase.h:44
xAOD::double
double
Definition: CompositeParticle_v1.cxx:159
CaloDetDescrElement::is_lar_fcal
bool is_lar_fcal() const
cell belongs to FCAL
Definition: CaloDetDescrElement.cxx:138
CaloPhiRange::fix
static double fix(double phi)
Definition: CaloPhiRange.cxx:14
calibdata.ct
ct
Definition: calibdata.py:418
xAOD::CaloTowerContainer_v1::nTowers
int nTowers() const
Definition: CaloTowerContainer_v1.h:147
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
CaloTowerxAODAlgoBase::CaloTowerxAODAlgoBase
CaloTowerxAODAlgoBase(const std::string &name, ISvcLocator *pSvcLocator)
Default algorithm constructor.
Definition: CaloTowerxAODAlgoBase.cxx:15
xAOD::CaloTower_v1::setEnergy
void setEnergy(double energy)
Sets the energy.
Definition: CaloTower_v1.cxx:26
CaloTowerxAODAlgoBase::m_cellToTower
CxxUtils::CachedValue< CellToTowerVec > m_cellToTower
map of cell indices to tower indices and weights
Definition: CaloTowerxAODAlgoBase.h:77
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)
CaloTowerxAODAlgoBase::m_caloTowerContainerKey
SG::WriteHandleKey< xAOD::CaloTowerContainer > m_caloTowerContainerKey
Handle to xAOD::CaloTowerContainer.
Definition: CaloTowerxAODAlgoBase.h:41
CxxUtils::CachedValue::set
void set(const T &val) const
Set the value, assuming it is currently invalid.
CaloDetDescrManager_Base::element_begin
calo_element_const_iterator element_begin() const
first element
Definition: CaloDetDescrManager.cxx:111
CaloCell_Base_ID::cell_id
Identifier cell_id(const int subCalo, const int barec_or_posneg, const int sampling_or_fcalmodule, const int region_or_dummy, const int eta, const int phi) const
Make a cell (== channel) ID from constituting fields and subCalo index; for (Mini)FCAL,...
CaloDetDescrElement::x
float x() const
cell x
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:363
checkCorrelInHIST.iX
int iX
Definition: checkCorrelInHIST.py:491
CaloDetDescrElement::dphi
float dphi() const
cell dphi
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:358
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
CaloDetDescrElement::getLayer
virtual int getLayer() const
cell layer
Definition: CaloDetDescrElement.cxx:85
LArCellBinning.etaMin
etaMin
Definition: LArCellBinning.py:84
y
#define y
Identifier::get_compact
value_type get_compact(void) const
Get the compact id.
CaloDetDescrManager
This class provides the client interface for accessing the detector description information common to...
Definition: CaloDetDescrManager.h:473
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
CaloDetDescrElement::dx
float dx() const
cell dx
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:375
CaloDetDescrManager_Base::element_size
calo_element_vec_size element_size() const
total number of elements
Definition: CaloDetDescrManager.cxx:105
CaloDetDescrElement::z
float z() const
cell z
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:367
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
checkCorrelInHIST.iY
int iY
Definition: checkCorrelInHIST.py:518
xAOD::CaloTower_v1
!
Definition: CaloTower_v1.h:18
CaloDetDescrElement::dy
float dy() const
cell dy
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:377
CaloTowerxAODAlgoBase::m_nPhiBins
int m_nPhiBins
Tower-grid: number of phi bins.
Definition: CaloTowerxAODAlgoBase.h:45
CaloConstIteratorAdaptor
Tranform iterator over pointers to iterator over const pointers.
Definition: CaloConstIteratorAdaptor.h:47
xAOD::CaloTowerContainer_v1::configureGrid
bool configureGrid(int nEtaBins, double etaMin, double etaMax, int nPhiBins)
Definition: CaloTowerContainer_v1.cxx:39
CaloDetDescrElement::phi_raw
float phi_raw() const
cell phi_raw
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:352