ATLAS Offline Software
Loading...
Searching...
No Matches
TileLookForMuAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5//***************************************************************************
6// Filename : TileLookForMuAlg.cxx
7// Author : G Usai
8// Created : June 2003
9//***************************************************************************
10
11// Tile includes
13#include "TileEvent/TileCell.h"
14
15// Calo includes
18
19// Athena includes
23
24//Library Includes
25#include <algorithm>
26#include <cmath>
27
28TileLookForMuAlg::TileLookForMuAlg(const std::string& name,
29 ISvcLocator* pSvcLocator)
30 : AthReentrantAlgorithm(name, pSvcLocator)
31 , m_tileID(0)
32 , m_etaD()
33 , m_etaBC()
34 , m_etaA()
35 , m_nMuMax(30)
36{
37 declareProperty("LowerTresh0MeV", m_loThrA=80.0);
38 declareProperty("LowerTresh1MeV", m_loThrBC=80.0);
39 declareProperty("LowerTresh2MeV", m_loThrD=80.0);
40 declareProperty("LowerTreshScinMeV", m_loThrITC=160.0);
41 declareProperty("UpperTresh2MeV", m_hiThrD);
42 declareProperty("UpperTresh1MeV", m_hiThrBC);
43 declareProperty("UpperTresh0MeV", m_hiThrA);
44 declareProperty("From3to2", m_fromDtoBC);
45 declareProperty("From2to1", m_fromBCtoA);
46
47}
48
51
53//Initialization /
56
57 // retrieve TileID helper and TileIfno from det store
58
59 CHECK( detStore()->retrieve(m_tileID) );
60
61
62 // define a numbering scheme for the cells
63 double eta_D = -1.2;
64 for (int iCellD = 0; iCellD < N_CELLS_D; ++iCellD) {
65 m_etaD[iCellD] = eta_D;
66 eta_D += 0.2;
67 }
68
69 if (msgLvl(MSG::DEBUG)) {
70 for (int iCellD = 0; iCellD < N_CELLS_D; ++iCellD) {
71 msg(MSG::DEBUG) << " etaD[" << iCellD << "] = " << m_etaD[iCellD] << endmsg;
72 }
73 }
74
75
76 double eta_BC_A = -1.45;
77 for (int iCell = 0; iCell < N_CELLS_BC; ++iCell) {
78 m_etaBC[iCell] = eta_BC_A;
79 m_etaA[iCell] = eta_BC_A;
80 eta_BC_A += 0.1;
81 }
82
83
84 if (msgLvl(MSG::DEBUG)) {
85 for (int iCell = 0; iCell < N_CELLS_BC; ++iCell) {
86 msg(MSG::DEBUG) << " etaBC[" << iCell << "] = " << m_etaBC[iCell] << endmsg;
87 msg(MSG::DEBUG) << " etaA[" << iCell << "] = " << m_etaA[iCell] << endmsg;
88 }
89 }
90
91
92 ATH_CHECK( m_cellContainerKey.initialize() );
93 ATH_CHECK( m_muContainerKey.initialize() );
94
95 ATH_MSG_DEBUG("TileLookForMuAlg initialization completed");
96
97 return StatusCode::SUCCESS;
98}
99
101//Execution /
103StatusCode TileLookForMuAlg::execute (const EventContext& ctx) const {
104
105 ATH_MSG_DEBUG("TileLookForMuAlg execution started");
106
107 //coverity[STACK_USE]
108 double eneA[N_CELLS_A][N_MODULES]; // calorimeter cell matrices
109 //coverity[STACK_USE]
110 double eneBC[N_CELLS_BC][N_MODULES];
111 //coverity[STACK_USE]
112 double eneD[N_CELLS_D][N_MODULES];
113
114 memset(eneA, 0, sizeof(eneA));
115 memset(eneBC, 0, sizeof(eneBC));
116 memset(eneD, 0, sizeof(eneD));
117
119 ATH_CHECK( muContainer.record(std::make_unique<TileMuContainer>()) );
120
121
122 // Get CaloCell Container
123 std::vector<const CaloCell*> cellList;
124
126 ATH_CHECK( cellContainer.isValid() );
127
130 cellContainer->beginConstCalo(tileCell_ID);
132 cellContainer->endConstCalo(tileCell_ID);
133
134 ATH_MSG_DEBUG( "Calo Container size "
135 << cellContainer->nCellsCalo(tileCell_ID));
136
137 double phi[64] = { 0 };
138// TileID::SAMPLE cellSample;
139 for (; currentCell != lastCell; ++currentCell) {
140 int iCell = -1;
141 double cellEta = (*currentCell)->eta();
142 if (cellEta > -1.5 && cellEta < 1.5) {
143 int cellModule;
144 int cellSample = m_tileID->sample((*currentCell)->ID());
145 switch (cellSample) {
146 case TileID::SAMP_A:
147 iCell = (cellEta + 1.5) * 10;
148 cellModule = m_tileID->module((*currentCell)->ID());
149 eneA[iCell][cellModule] = (*currentCell)->energy();
150 phi[cellModule] = (*currentCell)->phi();
151 break;
152 case TileID::SAMP_BC:
153 iCell = (cellEta + 1.5) * 10;
154 cellModule = m_tileID->module((*currentCell)->ID());
155 eneBC[iCell][cellModule] = (*currentCell)->energy();
156 phi[cellModule] = (*currentCell)->phi();
157 break;
158 case TileID::SAMP_D:
159 iCell = (cellEta + 1.3) * 5;
160 cellModule = m_tileID->module((*currentCell)->ID());
161 eneD[iCell][cellModule] = (*currentCell)->energy();
162 phi[cellModule] = (*currentCell)->phi();
163 cellList.push_back(*currentCell);
164 break;
165 case TileID::SAMP_E:
166 iCell = (cellEta + 1.5) * 10;
167 if (iCell == 4 || iCell == 25) {
168 cellModule = m_tileID->module((*currentCell)->ID());
169 eneA[iCell][cellModule] = (*currentCell)->energy();
170 phi[cellModule] = (*currentCell)->phi();
171 }
172 break;
173 }
174 }
175
176 if (msgLvl(MSG::VERBOSE)) {
177 msg(MSG::VERBOSE) << "scintillators sample, eta, phi, ene => "
178 << m_tileID->sample((*currentCell)->ID()) << ","
179 << cellEta << ","
180 << (*currentCell)->phi() << ","
181 << (*currentCell)->energy() << endmsg;
182
183 msg(MSG::VERBOSE) << "sample, tower, eta => "
184 << m_tileID->sample((*currentCell)->ID()) << ", "
185 << m_tileID->tower((*currentCell)->ID()) << ", "
186 << cellEta << endmsg;
187 }
188 } /* end of Tile cells loop*/
189
190 std::vector<double> muEtaD;
191 std::vector<float> muEneD;
192 std::vector<int> muModule;
193 std::vector<int> muCellD;
194 std::vector<int> muSplitted;
195 std::vector<int> muQualityD;
196 std::vector<int> muFound;
197 muEtaD.reserve(m_nMuMax);
198 muEneD.reserve(m_nMuMax);
199 muModule.reserve(m_nMuMax);
200 muCellD.reserve(m_nMuMax);
201 muSplitted.reserve(m_nMuMax);
202 muQualityD.reserve(m_nMuMax);
203 muFound.reserve(m_nMuMax);
204
205 int nCandidates = 0, ntri = 0;
206 int nSplitted = 0;
207
208 ATH_MSG_VERBOSE("Start the muon search candidates ");
209
210 // find muon candidates
211 int lastMuCell = -3;
212 int lastMuModule = -3;
213 for (int iModule = 0; iModule < N_MODULES; ++iModule) {
214 int prevCell = -2;
215 for (int iCellD = 0; iCellD < N_CELLS_D; ++iCellD) {
216 float energy = eneD[iCellD][iModule];
217 if (energy >= m_loThrD) {
218 int splitted = -1;
219 double eta = m_etaD[iCellD];
220 double hiThr = m_hiThrD[iCellD];
221 int quality = (energy < hiThr) ? 0 : 1;
222 // check for muon splitting (same phi bin and neighboring eta bin)
223 if (prevCell == lastMuCell && iModule == lastMuModule) {
224 int sumQuality = quality + muQualityD.back();
225 float sumEnergy = energy + eneD[prevCell][iModule];
226 double hiPrevThr = m_hiThrD[prevCell];
227 double maxHiThr = (hiThr > hiPrevThr) ? hiThr : hiPrevThr;
228 if ((sumQuality == 0 && sumEnergy < maxHiThr) || sumQuality == 1) {
229 // possible splitting with last found muon candidate
230 splitted = nCandidates - 1; // idx of splitting mu candidate
231 energy = sumEnergy;
232 eta = (eta + m_etaD[prevCell]) / 2;
233 ++nSplitted;
234 ATH_MSG_VERBOSE( "Possible splits between mu candidates ("
235 << (splitted + 1) << ", " << splitted
236 << "): etaD1, etaD2, eta => "
237 << m_etaD[iCellD] << ", "
238 << m_etaD[prevCell] << ", "
239 << eta
240 << "; eneD1, eneD2, energy => "
241 << eneD[iCellD][iModule] << ", "
242 << eneD[prevCell][iModule] << ", "
243 << energy);
244 }
245 }
246 muModule.push_back(iModule);
247 muCellD.push_back(iCellD);
248 muSplitted.push_back(splitted);
249 muFound.push_back(0);
250 muEneD.push_back(energy);
251 muQualityD.push_back(quality);
252 muEtaD.push_back(eta);
253 ++nCandidates;
254 lastMuCell = iCellD;
255 lastMuModule = iModule;
256 ATH_MSG_VERBOSE( "Candidate number= " << nCandidates
257 << ", tower index (iCellD)= " << iCellD
258 << ", module index(iModuleD)= " << iModule
259 << ", Energy(iCellD)(iModuleD) = " << eneD[iCellD][iModule]
260 << ", threshold2(iCellD)= " << m_hiThrD[iCellD]);
261 } else {
262 // ATH_MSG_VERBOSE ( "no candidates" );
263 }
264 prevCell = iCellD;
265 }
266 }
267
268 // debug ----------------------------------------
269 if (msgLvl(MSG::VERBOSE)) {
270 for (int i = 0; i < nCandidates; ++i) {
271 msg(MSG::VERBOSE) << "Candidates list: number phi,ene, eta "
272 << i << ","
273 << muModule[i] << ","
274 << muEneD[i] << ","
275 << muCellD[i]
276 << "nSplitted,muSplitted(cand)" << nSplitted << ", "
277 << muSplitted[i] << endmsg;
278 }
279 }
280
281 //*************** loop on the candidates----------------------*
282
283 for (int iMu = 0; iMu < nCandidates; ++iMu) {
284 int splitted = muSplitted[iMu];
285 if (splitted < 0 || muFound[splitted] == 0) {
286
287 // the most important information on mu is in the 3rd sample
288 // to avoid multiple counting due to splitting in 2nd and 1st Sp. cells
289 // the loop stop when the candidate is found
290
291 int module = muModule[iMu];
293 "loop on mu candidates: iMu, module = " << iMu << ", " << module);
294 int idxD = 6 * muCellD[iMu];
295 ATH_MSG_VERBOSE ("number of cells in BC layer to check = " << m_fromDtoBC[idxD]);
296 int endIdxD = idxD + m_fromDtoBC[idxD];
297 while (++idxD <= endIdxD && muFound[iMu] != 1) {
298 int cellBC = m_fromDtoBC[idxD];
299 float energyBC = eneBC[cellBC][module];
300 ATH_MSG_VERBOSE( "cellBC = " << cellBC
301 << ", module=" << module
302 << ", eneBC =" << energyBC);
303 if (energyBC > m_loThrBC) {
304 int qualityBC = (energyBC < m_hiThrBC[cellBC]) ? 0 : 1;
305 int idxBC = 6 * cellBC;
306 ATH_MSG_VERBOSE ("number of cells in A layer to check for mu = " << m_fromBCtoA[idxBC]);
307 int endIdxBC = idxBC + m_fromBCtoA[idxBC];
308 while (++idxBC <= endIdxBC && muFound[iMu] != 1) {
309 int cellA = m_fromBCtoA[idxBC];
310 float energyA = eneA[cellA][module];
311 ATH_MSG_VERBOSE( "cellA index = " << cellA
312 << ", module=" << module
313 << ", eneA =" << energyA);
314
315 if ( energyA > ( (cellA == 4 || cellA == 25) ? m_loThrITC : m_loThrA ) ) {
316
317 int qualityA = (energyA < m_hiThrA[cellA]) ? 0 : 1;
318
319 // We have a muon like signature
320
321 int muQuality = muQualityD[iMu] + qualityBC + qualityA;
322 if (muQuality <= 1) {
323 muFound[iMu] = 1;
324 double muEta = (muEtaD[iMu] + m_etaBC[cellBC] + m_etaA[cellA]) / 3;
325 double muPhi = phi[module];
326 std::vector<float> muEnergy;
327 muEnergy.reserve(4);
328 muEnergy.push_back(energyA);
329 muEnergy.push_back(energyBC);
330 muEnergy.push_back(muEneD[iMu]);
331 float eneAround = 0;
332
333 ATH_MSG_VERBOSE( "tag ntri eta,phi,ene[0]= " << (++ntri) << ", "
334 << muEta << ", "
335 << muPhi << ", "
336 << muEnergy[0] << ", "
337 << muEnergy[1] << ", "
338 << muEnergy[2]
339 << " tag eta 1st, 2nd, 3rd,"
340 << m_etaA[cellA] << ", "
341 << m_etaBC[cellBC] << ", "
342 << m_etaD[muCellD[iMu]]);
343
344 int nextModule = (module != 63) ? (module + 1) : 0;
345 int prevModule = (module != 0) ? (module - 1) : 63;
346 eneAround = eneA[cellA][nextModule] + eneA[cellA][prevModule]
347 + eneBC[cellBC][nextModule] + eneBC[cellBC][prevModule]; //phi neigh
348
349 int nextCellA = cellA + 1;
350 int prevCellA = cellA - 1;
351 if (nextCellA < N_CELLS_A && prevCellA > 0) {
352 eneAround += eneA[nextCellA][module] + eneA[prevCellA][module]
353 + eneA[nextCellA][nextModule]
354 + eneA[nextCellA][prevModule]
355 + eneA[prevCellA][nextModule]
356 + eneA[prevCellA][prevModule];
357
358 }
359
360 int nextCellBC = cellBC + 1;
361 int prevCellBC = cellBC - 1;
362 if (nextCellBC < N_CELLS_BC && prevCellBC > 0) {
363 eneAround += eneBC[nextCellBC][module]
364 + eneBC[prevCellBC][module]
365 + eneBC[nextCellBC][nextModule]
366 + eneBC[nextCellBC][prevModule]
367 + eneBC[prevCellBC][nextModule]
368 + eneBC[prevCellBC][prevModule];
369
370 }
371
372 muEnergy.push_back(eneAround);
373 std::unique_ptr<TileMu> muon = std::make_unique<TileMu>((float) muEta,
374 (float) muPhi,
375 muEnergy,
376 muQuality);
377
378 ATH_MSG_VERBOSE( "muon tag eta=" << muon->eta()
379 << " muon tag phi=" << muon->phi()
380 << " energydepVec[0]=" << muon->enedep()[0]
381 << " energydepVec[1]=" << muon->enedep()[1]
382 << " energydepVec[2]=" << muon->enedep()[2]
383 << " energydepVec[3]=" << muon->enedep()[3]
384 << " muon tag Q factor=" << muon->quality()
385 << " ene around= " << eneAround);
386
387 muContainer->push_back(muon.release());
388 }
389
390 } else {
391 ATH_MSG_VERBOSE(" tag eneA out");
392 } //endif eneA is in the range
393 } //end loop on pattern 1st layer
394 } else {
395 ATH_MSG_VERBOSE(" tag eneBC out");
396 } //endif eneBC is in the range
397 } //endloop on pattern 2nd layer
398 } else {
399 break;
400 }
401 } //endloop on candidate
402
403//-----debug-----------------------------------------------
404 // cellList contain the 3rd layer cell information
405 if (msgLvl(MSG::VERBOSE)) {
406 for (const CaloCell* cell : cellList) {
407 msg(MSG::VERBOSE) << " tag Cell (sect,side,mod,tow,sam)=("
408 << m_tileID->section(cell->ID()) << " "
409 << m_tileID->side(cell->ID()) << " "
410 << m_tileID->module(cell->ID()) << " "
411 << m_tileID->tower(cell->ID()) << " "
412 << m_tileID->sample(cell->ID())
413 << "),(eta,phi,energy)=("
414 << cell->eta() << ","
415 << cell->phi() << ","
416 << cell->energy() << ")" << endmsg;
417 }
418 }
419
420 //debug---------------------------------------------------
421 // check the mu tag container
422 if (msgLvl(MSG::DEBUG)) {
423 for (const TileMu* mu : *muContainer) {
424 msg(MSG::DEBUG) << "Container name = " << m_muContainerKey.key()
425 << " eta = " << mu->eta()
426 << " phi = " << mu->phi()
427 << " enedep[0] = " << (mu->enedep())[0]
428 << " enedep[1] = " << (mu->enedep())[1]
429 << " enedep[2] = " << (mu->enedep())[2]
430 << " enedep[3] = " << (mu->enedep())[3]
431 << " quality = " << mu->quality() << endmsg;
432 }
433 }
434 //-------------------debug-------------------------
435
436 return StatusCode::SUCCESS;
437}
438
440 ATH_MSG_DEBUG("TileLookForMuAlg finalization completed");
441 return StatusCode::SUCCESS;
442}
443
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
Helpers for checking error return status codes and reporting errors.
#define CHECK(...)
Evaluate an expression and check for errors.
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ServiceHandle< StoreGateSvc > & detStore() const
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
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
virtual bool isValid() override final
Can the handle be successfully dereferenced?
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
std::vector< int > m_fromBCtoA
std::vector< double > m_hiThrBC
SG::ReadHandleKey< CaloCellContainer > m_cellContainerKey
SG::WriteHandleKey< TileMuContainer > m_muContainerKey
TileLookForMuAlg(const std::string &name, ISvcLocator *pSvcLocator)
std::vector< int > m_fromDtoBC
const TileID * m_tileID
virtual StatusCode finalize() override
double m_etaBC[N_CELLS_BC]
virtual StatusCode execute(const EventContext &ctx) const override
std::vector< double > m_hiThrA
virtual StatusCode initialize() override
double m_etaA[N_CELLS_A]
double m_etaD[N_CELLS_D]
std::vector< double > m_hiThrD
Class to store TileMuId quantities.
Definition TileMu.h:25