ATLAS Offline Software
Loading...
Searching...
No Matches
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
15CaloTowerxAODAlgoBase::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() );
32 ATH_CHECK( m_caloMgrKey.initialize() );
33 return StatusCode::SUCCESS;
34}
35
36
38CaloTowerxAODAlgoBase::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
47 caloTowerContainer->configureGrid(m_nEtaBins,m_minEta,m_maxEta,m_nPhiBins);
48
49 //Prefill the container:
50 const int nTowers=caloTowerContainer->nTowers();
51
52 for (int iTower=0;iTower<nTowers;++iTower) {
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
73StatusCode 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
90 dummy->configureGrid(m_nEtaBins,m_minEta,m_maxEta,m_nPhiBins);
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}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
Definition of CaloDetDescrManager.
CaloPhiRange class declaration.
#define y
#define x
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ServiceHandle< StoreGateSvc > & detStore() const
An algorithm that can be simultaneously executed in multiple threads.
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,...
Helper class for offline cell identifiers.
Definition CaloCell_ID.h:34
This class groups all DetDescr information related to a CaloCell.
virtual int getLayer() const
cell layer
Identifier identify() const override final
cell identifier
bool is_lar_fcal() const
cell belongs to FCAL
calo_element_const_iterator element_begin() const
first element
CaloConstIteratorAdaptor< calo_element_vec::const_iterator > calo_element_const_iterator
calo_element_const_iterator element_end() const
end of element vector
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...
static double fix(double phi)
SG::WriteHandleKey< xAOD::CaloTowerContainer > m_caloTowerContainerKey
Handle to xAOD::CaloTowerContainer.
~CaloTowerxAODAlgoBase()
destructor
float m_maxEta
Tower-grid: upper eta boundary.
int m_nEtaBins
Tower-grid: number of phi bins.
std::vector< std::vector< cellToTower_t > > CellToTowerVec
bool m_doxCheck
Turn on internal checks (debugging)
CxxUtils::CachedValue< CellToTowerVec > m_cellToTower
map of cell indices to tower indices and weights
int m_nPhiBins
Tower-grid: number of phi bins.
const CellToTowerVec & getIndexCache(const EventContext &ctx) const
SG::WriteHandle< xAOD::CaloTowerContainer > makeContainer(const EventContext &ctx) const
Intialize m_cellToTower cache.
CaloTowerxAODAlgoBase(const std::string &name, ISvcLocator *pSvcLocator)
Default algorithm constructor.
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloMgrKey
float m_minEta
Tower-grid: lower eta boundary.
StatusCode fillIndexCache(const EventContext &ctx, CellToTowerVec &cellToTower) const
value_type get_compact() const
Get the compact id.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
void setEnergy(double energy)
Sets the energy.
int r
Definition globals.cxx:22