ATLAS Offline Software
Loading...
Searching...
No Matches
TBClusterMaker.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "TBClusterMaker.h"
6
7#include "CLHEP/Units/SystemOfUnits.h"
9
10#include "CaloEvent/CaloCell.h"
17
18//#############################################################################
19
21 const std::string& name,
22 const IInterface* parent)
23
24 : AthAlgTool(type, name, parent),
25 m_cellCut(-99999.),
26 m_seedCut(5.),
27 m_deltaR(0.02),
28 m_maxIter(4),
29 m_CellEnergyInADC(false),
30 m_calo_id(0)
31{
32 // CaloCell Container Name
33 declareProperty("caloCellContainerName",m_caloCellContainerName="AllCalo");
34 // Names of used calorimeter samplings
35 declareProperty("samplingNames",m_samplingNames);
36 // Cone cuts for each (!!) sampling used
37 declareProperty("coneCuts",m_coneCuts);
38 // Cut on a cell energy in sigma noise units
39 declareProperty("cellCut",m_cellCut);
40 // Cut on a seed cell energy in sigma noise units
41 declareProperty("seedCut",m_seedCut);
42 // Maximal claster position shift at the current step to stop iterations
43 declareProperty("deltaR",m_deltaR);
44 // Maximal number of iterations to find cluster
45 declareProperty("maxIterations",m_maxIter);
46 // True if cell enrgy is in ADC counts, default = FALSE
47 declareProperty("CellEnergyInADC",m_CellEnergyInADC);
48 // Flag to fix cluster position ( \f$ \eta,\phi \f$) from JO file
49 declareProperty("fixClusterPosition",m_fixClusterPosition=false);
50 // Cluster \f$ \eta \f$) from JO file
51 declareProperty("etaCluster",m_eta0=99.);
52 // Cluster \f$ \phi \f$) from JO file
53 declareProperty("phiCluster",m_phi0=99.);
54
55}
56
57// Initialization //
59
61
62 MsgStream log(msgSvc(), name());
63 log << MSG::INFO << "in initialize()" << endmsg;
64
65 // Get pointer to CaloCell_ID:
66 ATH_CHECK(detStore()->retrieve(m_calo_id, "CaloCell_ID"));
67 ATH_CHECK( m_elecNoiseKey.initialize() );
68
69 // setup calorimeter module and sampling lookup tables
70 if ((this->setupLookupTables()).isFailure()) {
71 log << MSG::FATAL
72 << "problems performing setup of module and sampling lookup tables"
73 << endmsg;
74 return StatusCode::FAILURE;
75 }
76
77 // fill map with cone cuts
78 if (m_samplingNames.size() <= 0) {
79 log << MSG::FATAL << "List of samplings is not supplied" << endmsg;
80 return StatusCode::FAILURE;
81 }
82 if (m_samplingNames.size() != m_coneCuts.size()) {
83 log << MSG::FATAL << "Number of cone cuts = " << m_coneCuts.size() <<
84 " does not correspond to the number of samplings = " <<
85 m_samplings.size() << endmsg;
86 return StatusCode::FAILURE;
87 }
88
89 log << MSG::INFO << "Included calorimeter samplings(coneCuts): ";
90 std::vector<std::string>::const_iterator sampling = m_samplingNames.begin();
91 std::vector<float>::const_iterator cut = m_coneCuts.begin();
93 for (; sampling != m_samplingNames.end(); ++sampling, ++cut) {
95 if (idSamp == CaloSampling::Unknown) {
96 log << MSG::FATAL << " Unknown sampling: \042" << *sampling << "\042 "
97 << endmsg;
98 return StatusCode::FAILURE;
99 }
100 log << MSG::INFO << "\042" << *sampling << "\042"
101 << "(" << *cut << ") ";
102 m_samplings.push_back(idSamp);
103 m_samplingConeCuts[idSamp] = *cut;
104 CaloCell_ID::SUBCALO idCalo = m_caloLookup[idSamp];
105 std::vector<CaloCell_ID::SUBCALO>::iterator it=m_calos.begin();
106 for (;it!=m_calos.end();++it) if (*it == idCalo) break;
107 if (it == m_calos.end()) m_calos.push_back(idCalo);
108 }
109 log << MSG::INFO << endmsg;
110 log << MSG::INFO << "Included calorimeters: " << m_calos << endmsg;
111 if (m_fixClusterPosition && (m_eta0 == 99. || m_phi0 == 99.)) {
112 log << MSG::FATAL << " Cluster position is fixed but (eta, phi) are not "
113 << "supplied in the JO file" << endmsg;
114 return StatusCode::FAILURE;
115 }
116 // Clear counters
117 //m_numSeedCellNotFound=0;
118 //m_numCluIterationsConverged=0;
119 //m_numCluIterationsNonConverged=0;
120
121 return StatusCode::SUCCESS;
122}
123
124
125StatusCode TBClusterMaker::execute(const EventContext& ctx,
126 xAOD::CaloClusterContainer* clusCont) const
127{
128 MsgStream log(msgSvc(), name());
129 log << MSG::DEBUG << "in execute()" << endmsg;
130
132
134 // Data Access //
136
137 // CaloCells
138 const CaloCellContainer* cellContainer;
139 StatusCode sc
140 = evtStore()->retrieve(cellContainer, m_caloCellContainerName);
141 if (sc.isFailure()) {
142 log << MSG::ERROR
143 << "cannot allocate CaloCellContainer with key <"
144 << m_caloCellContainerName << ">" << endmsg;
145 return sc;
146 }
147 log << MSG::DEBUG << "CaloCellContainer container size = " <<
148 cellContainer->size() << endmsg;
149
150 std::unique_ptr<xAOD::CaloCluster> Cluster;
151 double cluEta=0,cluPhi=0,cluNorm = 0;
152 double cluEta0=0,cluPhi0=0,cluNorm0 = 0;
153 bool clusterPositionFound = false;
155 clusterPositionFound = true;
156 cluEta0 = m_eta0;
157 cluPhi0 = m_phi0;
158 //m_numCluIterationsConverged++;
159 }
160 int nIter = 0;
161 for (; nIter<m_maxIter+1; nIter++) {
162 // loop over calorimeters
163 for (CaloCell_ID::SUBCALO calo : m_calos) {
164 // loop over cells of the current calorimeter
165 CaloCellContainer::const_iterator itc= cellContainer->beginConstCalo(calo);
166 int cindex=cellContainer->indexFirstCellCalo(calo);
167 for (; itc!=cellContainer->endConstCalo(calo); ++itc,++cindex) {
168 const CaloCell* cell = (*itc);
169 double e = cell->energy();
170 double noiseRMS = elecNoise->getNoise(cell->ID(), cell->gain());
171 if(noiseRMS <= 0.) noiseRMS = 0.0001;
172 double eSigma = e/noiseRMS;
173 CaloSampling::CaloSample idSample=(CaloSampling::CaloSample) m_calo_id->calo_sample(cell->ID());
174 if (m_CellEnergyInADC) eSigma *= m_adcToMeV[idSample];
175 if (!clusterPositionFound) {
176 // find cluster position
177 if (nIter == 0) { // use seed cells
178 if (eSigma < m_seedCut) continue;
179 log << MSG::DEBUG <<"smp,eta,phi,e,eSigma= "
180 <<idSample<<" "<<cell->eta()<<" "<<cell->phi()<<" "<<
181 e<<" "<<eSigma<<" "<<endmsg;
182 double phiRef=0.;
183 if (cluNorm0 == 0) {
184 cluPhi0 = e*cell->phi();
185 phiRef=cell->phi();
186 }
187 else cluPhi0 += e*proxim(cell->phi(),phiRef);
188 cluEta0 += e*cell->eta();
189 cluNorm0 += e;
190 } // nIter == 0
191 else {
192 double dist = sqrt(pow(cluPhi0-proxim(cell->phi(),cluPhi0),2)
193 +pow(cluEta0-cell->eta(),2));
194 if (dist > m_samplingConeCuts[idSample]) continue;
195 if (eSigma < m_cellCut) continue;
196 //if (e>0.) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
197 if (eSigma > 2.) {
198 cluPhi += e*proxim(cell->phi(),cluPhi0);
199 cluEta += e*cell->eta();
200 cluNorm += e;
201 }
202 }
203 }
204 else {
205 // fill the cluster
206 double dist = sqrt(pow(cluPhi0-proxim(cell->phi(),cluPhi0),2)
207 +pow(cluEta0-cell->eta(),2));
208 if (dist > m_samplingConeCuts[idSample]) continue;
209 if (eSigma < m_cellCut) continue;
210 // if (!Cluster) Cluster = new CaloCluster(cluEta0,cluPhi0);
211 if (!Cluster) Cluster = CaloClusterStoreHelper:: makeCluster(cellContainer,cluEta0,cluPhi0,xAOD::CaloCluster::SW_7_11);
212 //makeCluster();
213 //Cluster->addCell(cellContainer,cell,1.);
214 Cluster->addCell(cindex,1.);
215 log << MSG::DEBUG <<"smp,e,eSigma= "
216 <<idSample<<" "<<e<<" "<<eSigma<<" "<<endmsg;
217 }
218 } // end of loop over cells of the current calorimeter
219 } // end of loop over calorimeters
220 if (clusterPositionFound) break;
221 if (nIter==0) {
222 if (cluNorm0 == 0.) {
223 //m_numSeedCellNotFound++;
224 log << MSG::INFO << "No seed cell found" << endmsg;
225 return StatusCode::SUCCESS;
226 }
227 cluPhi0 /= cluNorm0;
228 cluEta0 /= cluNorm0;
229 log << MSG::DEBUG << "nIter=0: cluEta0,cluPhi0,cluNorm0= " << cluEta0
230 << " " << cluPhi0 << " " << cluNorm0 << endmsg;
231 continue;
232 }
233 if (cluNorm == 0.) {
234 log << MSG::ERROR << "cluNorm = 0.: should never be" << endmsg;
235 return StatusCode::SUCCESS;
236 }
237 cluPhi /= cluNorm;
238 cluEta /= cluNorm;
239 double dist = sqrt(pow(cluPhi0-proxim(cluPhi,cluPhi0),2)
240 +pow(cluEta0-cluEta,2));
241 if (dist < m_deltaR) {
242 clusterPositionFound = true;
243 //m_numCluIterationsConverged++;
244 }
245 else if (nIter == m_maxIter-1) {
246 clusterPositionFound = true;
247 //m_numCluIterationsNonConverged++;
248 log << MSG::DEBUG << "Maximal number of iterations reached" << endmsg;
249 log << MSG::DEBUG << "cluEta0,cluPhi0,cluNorm0= " << cluEta0 << " " <<
250 cluPhi0 << " " << cluNorm0 << endmsg;
251 log << MSG::DEBUG << "cluEta,cluPhi,cluNorm= " << cluEta << " " <<
252 cluPhi << " " << cluNorm << endmsg;
253 }
254 cluEta0 = cluEta;
255 cluPhi0 = cluPhi;
256 cluNorm0 = cluNorm;
257 cluEta=0.; cluPhi=0.; cluNorm = 0.;
258 } // end of loop over iterations
259
260 if (Cluster) {
261 // ** Calclulate Kine **
262 CaloClusterKineHelper::calculateKine(Cluster.get(),false,true); //No weight at this point!
263 log<<MSG::DEBUG<<"Cluster eta0, phi0= "<<Cluster->eta0()<<" "<<
264 Cluster->phi0();
265 log<<MSG::DEBUG<<" Cluster #cells, E, eta, phi= "<<
266 Cluster->clusterSize()<<" "<<Cluster->e()<<" "<<
267 Cluster->eta()<<" "<<Cluster->phi()<<endmsg;
268 log<<MSG::DEBUG<<"In samplings: #samp E eta(etasize) phi(phisize):"
269 <<endmsg;
270 //std::vector<CaloSampling::CaloSample>::const_iterator
271 //it=m_samplings.begin();
272 //for(;it!=m_samplings.end();it++) {
273 // CaloSampling::CaloSample smp=*it;
274 // if (!Cluster->is_valid_sampling(smp)) continue;
275 //log<<MSG::DEBUG<<"Valid= "<<Cluster->is_valid_sampling(smp)<<endmsg;
276 //log<<MSG::DEBUG<<"#"<<smp<<" "<<Cluster->eSample(smp)<<" ";
277 //log<<MSG::DEBUG<<"#"<<smp<<" "<<Cluster->eSample(smp)<<" "<<
278 // Cluster->etaSample(smp)<<"("<<Cluster->etasize(smp)<<") "<<
279 // Cluster->phiSample(smp)<<"("<<Cluster->phisize(smp)<<") ";
280 //}
281 //log<<MSG::DEBUG<<endmsg;
282 clusCont->push_back(std::move(Cluster));
283 return StatusCode::SUCCESS;
284 } else {
285 log << MSG::ERROR << "Cluster not found: should never be here!" << endmsg;
286 return StatusCode::SUCCESS;
287 }
288
289}
290
292
293 MsgStream log(msgSvc(), name());
294 log << MSG::DEBUG << "in finalize()" << endmsg;
295
296 //log << MSG::INFO << "Total number of found clusters = " <<
297 // m_numCluIterationsConverged + m_numCluIterationsNonConverged << endmsg;
298 //log << MSG::INFO << "Numbers of clusters with converged/non-converged " <<
299 // "iteration procedure = " << m_numCluIterationsConverged << "/" <<
300 // m_numCluIterationsNonConverged<<endmsg;
301 //log << MSG::INFO << " Seed cells were not found in " << m_numSeedCellNotFound
302 // << " events" << endmsg;
303
304 return StatusCode::SUCCESS;
305}
306
308
309 m_samplingFromNameLookup["PreSamplerB"] = CaloSampling::PreSamplerB; // electromagnetic barrel
310 m_samplingFromNameLookup["EMB1"] = CaloSampling::EMB1;
311 m_samplingFromNameLookup["EMB2"] = CaloSampling::EMB2;
312 m_samplingFromNameLookup["EMB3"] = CaloSampling::EMB3;
313 m_samplingFromNameLookup["PreSamplerE"] = CaloSampling::PreSamplerE; // electromagnetic endcap
314 m_samplingFromNameLookup["EME1"] = CaloSampling::EME1;
315 m_samplingFromNameLookup["EME2"] = CaloSampling::EME2;
316 m_samplingFromNameLookup["EME3"] = CaloSampling::EME3;
317 m_samplingFromNameLookup["HEC0"] = CaloSampling::HEC0; // hadronic endcap
318 m_samplingFromNameLookup["HEC1"] = CaloSampling::HEC1;
319 m_samplingFromNameLookup["HEC2"] = CaloSampling::HEC2;
320 m_samplingFromNameLookup["HEC3"] = CaloSampling::HEC3;
321 m_samplingFromNameLookup["TileBar0"] = CaloSampling::TileBar0; // tile barrel
322 m_samplingFromNameLookup["TileBar1"] = CaloSampling::TileBar1;
323 m_samplingFromNameLookup["TileBar2"] = CaloSampling::TileBar2;
324 m_samplingFromNameLookup["TileGap1"] = CaloSampling::TileGap1; // tile gap scintillators
325 m_samplingFromNameLookup["TileGap2"] = CaloSampling::TileGap2;
326 m_samplingFromNameLookup["TileGap3"] = CaloSampling::TileGap3;
327 m_samplingFromNameLookup["TileExt0"] = CaloSampling::TileExt0; // tile extended barrel
328 m_samplingFromNameLookup["TileExt1"] = CaloSampling::TileExt1;
329 m_samplingFromNameLookup["TileExt2"] = CaloSampling::TileExt2;
330 m_samplingFromNameLookup["FCal1"] = CaloSampling::FCAL0; // fcal
331 m_samplingFromNameLookup["FCal2"] = CaloSampling::FCAL1;
332 m_samplingFromNameLookup["FCal3"] = CaloSampling::FCAL2;
333 m_samplingFromNameLookup["unknown"] = CaloSampling::Unknown;
334
335 // fill calo lookup table
336 m_caloLookup[CaloSampling::PreSamplerB] = CaloCell_ID::LAREM;
337 m_caloLookup[CaloSampling::EMB1] = CaloCell_ID::LAREM;
338 m_caloLookup[CaloSampling::EMB2] = CaloCell_ID::LAREM;
339 m_caloLookup[CaloSampling::EMB3] = CaloCell_ID::LAREM;
340 m_caloLookup[CaloSampling::PreSamplerE] = CaloCell_ID::LAREM;
341 m_caloLookup[CaloSampling::EME1] = CaloCell_ID::LAREM;
342 m_caloLookup[CaloSampling::EME2] = CaloCell_ID::LAREM;
343 m_caloLookup[CaloSampling::EME3] = CaloCell_ID::LAREM;
344 m_caloLookup[CaloSampling::HEC0] = CaloCell_ID::LARHEC;
345 m_caloLookup[CaloSampling::HEC1] = CaloCell_ID::LARHEC;
346 m_caloLookup[CaloSampling::HEC2] = CaloCell_ID::LARHEC;
347 m_caloLookup[CaloSampling::HEC3] = CaloCell_ID::LARHEC;
348 m_caloLookup[CaloSampling::TileBar0] = CaloCell_ID::TILE;
349 m_caloLookup[CaloSampling::TileBar1] = CaloCell_ID::TILE;
350 m_caloLookup[CaloSampling::TileBar2] = CaloCell_ID::TILE;
351 m_caloLookup[CaloSampling::TileGap1] = CaloCell_ID::TILE;
352 m_caloLookup[CaloSampling::TileGap2] = CaloCell_ID::TILE;
353 m_caloLookup[CaloSampling::TileGap3] = CaloCell_ID::TILE;
354 m_caloLookup[CaloSampling::TileExt0] = CaloCell_ID::TILE;
355 m_caloLookup[CaloSampling::TileExt1] = CaloCell_ID::TILE;
356 m_caloLookup[CaloSampling::TileExt2] = CaloCell_ID::TILE;
357 m_caloLookup[CaloSampling::FCAL0] = CaloCell_ID::LARFCAL;
358 m_caloLookup[CaloSampling::FCAL1] = CaloCell_ID::LARFCAL;
359 m_caloLookup[CaloSampling::FCAL2] = CaloCell_ID::LARFCAL;
360
361 // fill ADC to MeV conversion map (for HIGH gain !!)
363 m_adcToMeV[CaloSampling::EME2] = 29.0;
364 m_adcToMeV[CaloSampling::EME3] = 13.7;
365 m_adcToMeV[CaloSampling::HEC0] = 11.2;
366 m_adcToMeV[CaloSampling::HEC1] = 11.2;
367 m_adcToMeV[CaloSampling::HEC2] = 11.2;
368 m_adcToMeV[CaloSampling::FCAL0] = 83.4;
369 m_adcToMeV[CaloSampling::FCAL1] = 163.9;
370 m_adcToMeV[CaloSampling::FCAL2] = 181.8;
371
372 return StatusCode::SUCCESS;
373}
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
CaloPhiRange class declaration.
static Double_t sc
constexpr int pow(int base, int exp) noexcept
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
ServiceHandle< StoreGateSvc > & evtStore()
const ServiceHandle< StoreGateSvc > & detStore() const
Container class for CaloCell.
CaloCellContainer::const_iterator beginConstCalo(CaloCell_ID::SUBCALO caloNum) const
get const iterators on cell of just one calo
CaloCellContainer::const_iterator endConstCalo(CaloCell_ID::SUBCALO caloNum) const
int indexFirstCellCalo(const CaloCell_ID::SUBCALO caloNum) const
index of first cell of given calorimeter (-1 if none).
CaloCell_Base_ID::SUBCALO SUBCALO
Definition CaloCell_ID.h:50
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
static void calculateKine(xAOD::CaloCluster *clu, const bool useweight=true, const bool updateLayers=true, const bool useGPUCriteria=false)
Helper class to calculate cluster kinematics based on cells.
static std::unique_ptr< xAOD::CaloCluster > makeCluster(const CaloCellContainer *cellCont)
Creates a valid CaloCluster with a private Aux-Store and CellLink container.
static constexpr unsigned int getNumberOfSamplings()
Get number of available samplings.
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
value_type push_back(value_type pElem)
Add an element to the end of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
float m_cellCut
Threshold cut on cell energy in sigma noise units.
virtual StatusCode initialize() override
StatusCode setupLookupTables()
Setup lookup tables.
std::vector< std::string > m_samplingNames
std::vector< float > m_samplingConeCuts
Map of cone cuts for calorimeter samplings.
bool m_fixClusterPosition
Flag to fix cluster position ( ) from JO file.
const CaloCell_ID * m_calo_id
Services.
bool m_CellEnergyInADC
True if cell enrgy is in ADC counts, default = FALSE.
float m_eta0
Cluster ) set in JO file.
std::vector< CaloSampling::CaloSample > m_samplings
Vectors containing the list of used samplings and corresponding cone cuts; list of used calorimeters.
std::map< CaloSampling::CaloSample, CaloCell_ID::SUBCALO > m_caloLookup
std::vector< float > m_coneCuts
std::vector< CaloCell_ID::SUBCALO > m_calos
virtual StatusCode execute(const EventContext &ctx, xAOD::CaloClusterContainer *theClusters) const override
Execute on an entire collection of clusters.
float m_seedCut
Threshold cut on seed cell energy in sigma noise units to find the 1st approximation of cluster .
std::map< std::string, CaloSampling::CaloSample > m_samplingFromNameLookup
TBClusterMaker(const std::string &type, const std::string &name, const IInterface *parent)
SG::ReadCondHandleKey< CaloNoise > m_elecNoiseKey
int m_maxIter
Maximal number of iterations to find cluster position.
float m_deltaR
Maximal claster position shift at the current step to stop iterations.
std::string m_caloCellContainerName
Names.
virtual StatusCode finalize() override
std::vector< float > m_adcToMeV
CaloClusterContainer_v1 CaloClusterContainer
Define the latest version of the calorimeter cluster container.
double proxim(double b, double a)
Definition proxim.h:17