ATLAS Offline Software
Loading...
Searching...
No Matches
MuonIdHelperSvc.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <iostream>
8#include <format>
9#include <ranges>
10
11
12namespace Muon {
13 using namespace MuonStationIndex;
14
15 MuonIdHelperSvc::MuonIdHelperSvc(const std::string& name, ISvcLocator* svc) :
16 base_class(name, svc) {}
17
19 ATH_CHECK(m_detStore.retrieve());
26
28 using AllHelperArray = std::array<const MuonIdHelper*, 6>;
29 const AllHelperArray allHelpers{m_mdtIdHelper, m_rpcIdHelper, m_tgcIdHelper,
31 AllHelperArray::const_iterator itr = std::ranges::find_if(allHelpers,
32 [](const MuonIdHelper* h){return h != nullptr;});
33 if (itr == allHelpers.end()){
34 ATH_MSG_WARNING("No MuonIdHelper has been created before. Please do not setup the service if no muon layout is loaded");
35 return StatusCode::SUCCESS;
36 }
37 m_primaryHelper = (*itr);
38
39 std::stringstream techStr{};
40
41 for (int tech = 0; tech <= m_primaryHelper->technologyNameIndexMax(); ++tech) {
42 std::string name = m_primaryHelper->technologyString(tech);
43
44 if (name == "MDT") m_technologies.push_back(TechIdx::MDT);
45 if (name == "CSC") m_technologies.push_back(TechIdx::CSC);
46 if (name == "RPC") m_technologies.push_back(TechIdx::RPC);
47 if (name == "TGC") m_technologies.push_back(TechIdx::TGC);
48 if (name == "STGC") m_technologies.push_back(TechIdx::STGC);
49 if (name == "MM") m_technologies.push_back(TechIdx::MM);
50 techStr<< ", " << tech << " " << name;
51 }
52 ATH_MSG_DEBUG(" Technologies: size " << m_primaryHelper->technologyNameIndexMax()<<" "<<techStr.str());
53
54 unsigned int nstationsNames = m_primaryHelper->stationNameIndexMax() + 1;
55 m_stationNameData.resize(nstationsNames);
56 for (int i = 0; i <= m_primaryHelper->stationNameIndexMax(); ++i) {
57 std::string name = m_primaryHelper->stationNameString(i);
58 if (name.compare(MuonIdHelper::BAD_NAME) == 0) continue;
59
61
62 data.stationName = std::move(name);
63 data.isEndcap = m_primaryHelper->isEndcap(i);
64 data.isSmall = m_primaryHelper->isSmall(i);
65
66 if (data.isEndcap) {
67 if (data.stationName[1] == '1')
68 data.chIndex = ChIdx::EML;
69 else if (data.stationName[1] == '2')
70 data.chIndex = ChIdx::EML;
71 else if (data.stationName[1] == '3')
72 data.chIndex = ChIdx::EML;
73 else if (data.stationName[1] == '4')
74 data.chIndex = ChIdx::EIL;
75
76 if (data.stationName[1] == 'O') {
77 if (data.stationName[2] == 'L')
78 data.chIndex = ChIdx::EOL;
79 else
80 data.chIndex = ChIdx::EOS;
81 } else if (data.stationName[1] == 'M') {
82 if (data.stationName[2] == 'L')
83 data.chIndex = ChIdx::EML;
84 else
85 data.chIndex = ChIdx::EMS;
86 } else if (data.stationName[1] == 'I') {
87 if (data.stationName[2] == 'L')
88 data.chIndex = ChIdx::EIL;
89 else
90 data.chIndex = ChIdx::EIS;
91 } else if (data.stationName[1] == 'E') {
92 if (data.stationName[0] == 'B') {
93 data.chIndex = ChIdx::BEE;
94 } else {
95 if (data.stationName[2] == 'L')
96 data.chIndex = ChIdx::EEL;
97 else
98 data.chIndex = ChIdx::EES;
99 }
100 } else if (data.stationName[0] == 'C') {
101 if (data.stationName[2] == 'L')
102 data.chIndex = ChIdx::CSL;
103 else
104 data.chIndex = ChIdx::CSS;
105 }
106 if (data.stationName[0] == 'S' || data.stationName[0] == 'M') {
107 if (data.isSmall)
108 data.chIndex = ChIdx::EIS;
109 else
110 data.chIndex = ChIdx::EIL;
111 }
112
113 } else {
114 if (data.stationName[1] == 'O') {
115 if (data.stationName[2] == 'L')
116 data.chIndex = ChIdx::BOL;
117 else
118 data.chIndex = ChIdx::BOS;
119 } else if (data.stationName[1] == 'M') {
120 if (data.stationName[2] == 'L' || data.stationName[2] == 'E')
121 data.chIndex = ChIdx::BML;
122 else
123 data.chIndex = ChIdx::BMS;
124 } else if (data.stationName[1] == 'I') {
125 if (data.stationName[2] == 'L' || data.stationName[2] == 'M' || data.stationName[2] == 'R')
126 data.chIndex = ChIdx::BIL;
127 else
128 data.chIndex = ChIdx::BIS;
129 }
130 }
131 if (data.chIndex == ChIdx::ChUnknown) {
132 ATH_MSG_ERROR("data.chIndex is negative in MuonIdHelperSvc::initialize ");
133 return StatusCode::FAILURE;
134 }
135 data.stIndex = toStationIndex(data.chIndex);
136
137 if (msgLvl(MSG::DEBUG)) {
138 msg(MSG::DEBUG) << "Adding station " << i << " " << data.stationName << " ";
139 if (data.isEndcap)
140 msg(MSG::DEBUG) << " Endcap, ";
141 else
142 msg(MSG::DEBUG) << " Barrel, ";
143 if (data.isSmall)
144 msg(MSG::DEBUG) << " Small, ";
145 else
146 msg(MSG::DEBUG) << " Large, ";
147
148 msg(MSG::DEBUG) << chName(data.chIndex) << " " << stName(data.stIndex) << endmsg;
149 }
150 }
152 // now, let's check if we are in the inner barrel layer, and if there are RPCs installed
153 // if yes, the MDT chambers must be sMDTs
155 m_BIS_stat = m_mdtIdHelper->stationNameIndex("BIS");
156 for (int eta = MdtIdHelper::stationEtaMin(true); eta <= MdtIdHelper::stationEtaMax(true); ++eta) {
157 for (int phi = 1; phi <= 8; ++phi) {
158 // now, let's check if we are in the inner barrel layer, and if there are RPCs installed
159 // if yes, the MDT chambers must be sMDTs
160 // now try to retrieve RPC identifier with the same station name/eta/phi and check if it is valid
161 bool isValid = false;
162 m_rpcIdHelper->elementID(m_BIS_stat, eta, phi, 1, isValid);
163 // last 4 arguments are: doubletR, check, isValid
164 // there is a BI RPC in the same station, thus, this station was already upgraded and sMDTs are present
165 if (!isValid) continue;
166 m_smdt_stat.emplace(m_mdtIdHelper->elementID(m_BIS_stat, eta, phi));
167 }
168 }
169 }
170
171 std::ranges::for_each(allHelpers, [this](const MuonIdHelper* idHelper){
172 if (!idHelper) return;
173 const TechIdx techIdx = technologyIndex(*idHelper->module_begin());
174 for (auto itr = idHelper->module_begin(); itr != idHelper->module_end(); ++itr) {
175 const auto idx = toStationIndex(chamberIndex(*itr));
176 if (idx == StIndex::StUnknown) continue;
177 m_techPerStation[toInt(idx)].insert(techIdx);
178 }
179 });
180
181 ATH_MSG_DEBUG("Configured the service with the following flags --- hasMDT: "<< hasMDT()<<" hasRPC: "<<hasRPC()
182 <<" hasTGC"<< hasTGC() << " hasCSC: "<< hasCSC() << " hasSTGC: " << hasSTGC() << " hasMM: " << hasMM() );
183 return StatusCode::SUCCESS;
184 }
185
186 int MuonIdHelperSvc::gasGap(const Identifier& id) const {
187 switch (technologyIndex(id)) {
188 using enum TechnologyIndex;
189 case RPC: {
190 return m_rpcIdHelper->gasGap(id);
191 } case TGC: {
192 return m_tgcIdHelper->gasGap(id);
193 } case CSC: {
194 return m_cscIdHelper->wireLayer(id);
195 } case STGC: {
196 return m_stgcIdHelper->gasGap(id);
197 } case MM: {
198 return m_mmIdHelper->gasGap(id);
199 } case MDT: {
200 return m_mdtIdHelper->channel(id);
201 } default:
202 break;
203 }
204 return 0;
205 }
206
207 bool MuonIdHelperSvc::isMuon(const Identifier& id) const {
208 return m_primaryHelper && m_primaryHelper->is_muon(id);
209 }
210 bool MuonIdHelperSvc::isMdt(const Identifier& id) const {
211 return m_mdtIdHelper && m_mdtIdHelper->is_mdt(id);
212 }
213 bool MuonIdHelperSvc::isMM(const Identifier& id) const {
214 return m_mmIdHelper && m_mmIdHelper->is_mm(id);
215 }
216 bool MuonIdHelperSvc::isCsc(const Identifier& id) const {
217 return m_cscIdHelper && m_cscIdHelper->is_csc(id);
218 }
219 bool MuonIdHelperSvc::isRpc(const Identifier& id) const {
220 return m_rpcIdHelper && m_rpcIdHelper->is_rpc(id);
221 }
222
223 bool MuonIdHelperSvc::isTgc(const Identifier& id) const {
224 return m_tgcIdHelper && m_tgcIdHelper->is_tgc(id);
225 }
226
227 bool MuonIdHelperSvc::issTgc(const Identifier& id) const {
228 return m_stgcIdHelper && m_stgcIdHelper->is_stgc(id);
229 }
230
231 const std::set<TechnologyIndex>&
233 assert(toInt(stIndex) < static_cast<int>(m_techPerStation.size()));
234 return m_techPerStation[toInt(stIndex)];
235 }
236 bool MuonIdHelperSvc::issMdt(const Identifier& id) const {
237 if (!isMdt(id)) {
238 return false;
239 }
240 if (stationName(id) == m_BIS_stat) {
241 return m_smdt_stat.find(m_mdtIdHelper->elementID(id)) != m_smdt_stat.end();
242 }
243 return m_mdtIdHelper->isBME(id) || m_mdtIdHelper->isBMG(id);
244 }
245
246 bool MuonIdHelperSvc::hasHPTDC(const Identifier& id) const {
249 // the remaining sMDTs (installed in BI in LS1) all have an HPTDC in Run3
250 // all BME sMDTs have no HPTDC
251 return issMdt(id) && !m_mdtIdHelper->isBME(id);
252 }
253
255 return isRpc(id) || isTgc(id);
256 }
257
258 bool MuonIdHelperSvc::isEndcap(const Identifier& id) const { return m_primaryHelper->isEndcap(id); }
259 bool MuonIdHelperSvc::isSmallChamber(const Identifier& id) const { return m_primaryHelper->isSmall(id); }
260
262 if (!id.is_valid() || !isMuon(id)) {
263 if (id.is_valid()) ATH_MSG_WARNING("chamberIndex: invalid ID " << m_primaryHelper->print_to_string(id));
264 return ChIdx::ChUnknown;
265 }
266 return m_stationNameData[stationName(id)].chIndex;
267 }
268
270 if (!id.is_valid() || !isMuon(id)) {
271 if (id.is_valid()) ATH_MSG_WARNING("stationIndex: invalid ID " << m_primaryHelper->print_to_string(id));
272 return StIdx::StUnknown;
273 }
274 return m_stationNameData[stationName(id)].stIndex;
275 }
276
278#ifndef NDEBUG
279 if (!id.is_valid() || !isMuon(id)) {
280 if (id.is_valid()) ATH_MSG_WARNING("phiIndex: invalid ID " << m_primaryHelper->print_to_string(id));
281 return PhiIdx::PhiUnknown;
282 }
283 if (isMdt(id) || isMM(id)) {
284 ATH_MSG_WARNING("phiIndex: not supported for " << toString(id));
285 return PhiIdx::PhiUnknown;
286 }
287#endif
288 switch (stationIndex(id)) {
289 case StIndex::BI:{
290 return m_rpcIdHelper->doubletR(id) == 1 ? PhiIdx::BI1 : PhiIdx::BI2;
291 } case StIndex::BM: {
292 return m_rpcIdHelper->doubletR(id) == 1 ? PhiIdx::BM1 : PhiIdx::BM2;
293 } case StIndex::BO: {
294 return m_rpcIdHelper->doubletR(id) == 1 ? PhiIdx::BO1 : PhiIdx::BO2;
295 } case StIndex::EI: {
296 switch (technologyIndex(id)) {
297 case TechIdx::CSC:
298 return PhiIdx::CSC;
299 case TechIdx::TGC:
300 return PhiIdx::T4;
301 case TechIdx::STGC:
302 return m_stgcIdHelper->multilayer(id) == 1 ? PhiIdx::STGC1 : PhiIdx::STGC2;
303 default:
304 break;
305 }
306 break;
307 } case StIndex::EM: {
308 const std::string chamberName = stationNameString(id);
309 if (chamberName[1] == '1') {
310 return PhiIdx::T1;
311 } else if (chamberName[1] == '2') {
312 return PhiIdx::T2;
313 } else {
314 return PhiIdx::T3;
315 }
316 } default:
317 break;
318 }
319 return PhiIdx::PhiUnknown;
320 }
321
323 if (isEndcap(id)) return stationEta(id) < 0 ? DetectorRegionIndex::EndcapC : DetectorRegionIndex::EndcapA;
324 return DetectorRegionIndex::Barrel;
325 }
326
330
332 if (isMdt(id)) return TechIdx::MDT;
333 else if (issTgc(id)) return TechIdx::STGC;
334 else if (isMM(id)) return TechIdx::MM;
335 else if (isTgc(id)) return TechIdx::TGC;
336 else if (isRpc(id)) return TechIdx::RPC;
337 else if (isCsc(id)) return TechIdx::CSC;
338 return TechIdx::TechnologyUnknown;
339 }
340 std::string MuonIdHelperSvc::toString(const Identifier& id) const {
341 if (!id.is_valid()) return " Invalid Identifier";
342 switch (technologyIndex(id)) {
343 using enum TechnologyIndex;
344 case MDT:{
345 return toStringGasGap(id);
346 } case RPC: {
347 return std::format("{:} {:} channel {:2d}", toStringGasGap(id),
348 measuresPhi(id) ? "phi" : "eta", m_rpcIdHelper->channel(id));
349 } case TGC: {
350 return std::format("{:} {:} channel {:2d}", toStringGasGap(id),
351 measuresPhi(id) ? "phi" : "eta", m_tgcIdHelper->channel(id));
352 } case CSC: {
353 return std::format("{:} {:} channel {:2d}", toStringGasGap(id),
354 measuresPhi(id) ? "phi" : "eta", m_cscIdHelper->channel(id));
355 } case STGC: {
356 using sTgcType = sTgcIdHelper::sTgcChannelTypes;
357 const int channelType = m_stgcIdHelper->channelType(id);
358 return std::format("{:} {:} channel {:3d}", toStringGasGap(id),
359 channelType == sTgcType::Strip ? "eta" : channelType == sTgcType::Wire ? "phi" : "pad" ,
360 m_stgcIdHelper->channel(id));
361 } case MM: {
362 return std::format("{:} channel {:4d}",toStringGasGap(id), m_mmIdHelper->channel(id));
363 } default:
364 break;
365 }
366 return {};
367 }
368
369 std::string MuonIdHelperSvc::toStringTech(const Identifier& id) const {
371 }
372
373 std::string MuonIdHelperSvc::chamberNameString(const Identifier& id) const {
374 return m_primaryHelper->stationNameString(stationName(id));
375 }
376
377 std::string MuonIdHelperSvc::toStringStation(const Identifier& id) const {
378 return std::format("{:} {:} eta {:2d} phi {:2d}", toStringTech(id),stationNameString(id),
379 stationEta(id), stationPhi(id));
380 }
381 std::string MuonIdHelperSvc::toStringChamber(const Identifier& id) const {
382 if (!id.is_valid()) {
383 return " Invalid Identifier";
384 }
385 if (isRpc(id)) {
386 return std::format("{:} dbR {:1}", toStringStation(id), m_rpcIdHelper->doubletR(id));
387 }
388 return toStringStation(id);
389 }
390
391 std::string MuonIdHelperSvc::toStringDetEl(const Identifier& id) const {
392 switch (technologyIndex(id)) {
393 using enum TechnologyIndex;
394 case MDT: {
395 return std::format("{:} ml {:1d}", toStringChamber(id), m_mdtIdHelper->multilayer(id));
396 } case RPC: {
397 return std::format("{:} dbZ {:1d} dbPhi {:1d}", toStringChamber(id), m_rpcIdHelper->doubletZ(id), m_rpcIdHelper->doubletPhi(id));
398 } case TGC: {
399 return toStringChamber(id);
400 } case CSC: {
401 return std::format("{:} chlay {:1d}",toStringChamber(id), m_cscIdHelper->chamberLayer(id));
402 } case STGC: {
403 return std::format("{:} chlay {:1d}",toStringChamber(id), m_stgcIdHelper->multilayer(id));
404 } case MM: {
405 return std::format("{:} chlay {:1d}",toStringChamber(id), m_mmIdHelper->multilayer(id));
406 } default:
407 break;
408 }
409 return "Invalid detector element";
410 }
411
412 std::string MuonIdHelperSvc::toStringGasGap(const Identifier& id) const {
413 switch (technologyIndex(id)) {
414 using enum TechnologyIndex;
415 case MDT: {
416 return std::format("{:} lay {:1d} tube {:1d}", toStringDetEl(id),
417 m_mdtIdHelper->tubeLayer(id), m_mdtIdHelper->tube(id));
418 } case RPC:
419 case TGC: {
420 return std::format("{:} gap {:1d}", toStringDetEl(id), gasGap(id));
421 } case STGC:
422 case MM:
423 case CSC: {
424 return std::format("{:} lay {:1d}", toStringDetEl(id), gasGap(id));
425 } default:
426 break;
427 }
428 return "invalid gas gap Id";
429 }
430
432 // use phi hits on segment
433 switch (technologyIndex(id)) {
434 using enum TechnologyIndex;
435 case MDT: {
436 return m_mdtIdHelper->elementID(id);
437 } case RPC: {
438 return m_rpcIdHelper->elementID(id);
439 } case TGC: {
440 return m_tgcIdHelper->elementID(id);
441 } case CSC: {
442 return m_cscIdHelper->elementID(id);
443 } case STGC: {
444 return m_stgcIdHelper->elementID(id);
445 } case MM: {
446 return m_mmIdHelper->elementID(id);
447 } default:
448 break;
449 }
450 return Identifier{};
451 }
452
454 // use phi hits on segment
455 switch (technologyIndex(id)) {
457 case MDT: {
458 return m_mdtIdHelper->channelID(id, m_mdtIdHelper->multilayer(id), 1, 1);;
459 } case RPC: {
460 return m_rpcIdHelper->channelID(id, m_rpcIdHelper->doubletZ(id), m_rpcIdHelper->doubletPhi(id), 1, false, 1);
461 } case TGC: {
462 return m_tgcIdHelper->elementID(id);
463 } case CSC: {
464 return m_cscIdHelper->channelID(id, 2, 1, 1, 1);
465 } case MM: {
466 return m_mmIdHelper->channelID(id, m_mmIdHelper->multilayer(id), 1, 1);
467 } case STGC: {
468 return m_stgcIdHelper->channelID(id, m_stgcIdHelper->multilayer(id), 1, sTgcIdHelper::sTgcChannelTypes::Strip, 1);
469 } default:
470 break;
471 }
472 return id;
473 }
474
476 switch (technologyIndex(id)) {
477 using enum TechnologyIndex;
478 case TGC: {
479 return m_tgcIdHelper->channelID(id, m_tgcIdHelper->gasGap(id), m_tgcIdHelper->measuresPhi(id), 1);
480 } case RPC: {
481 return m_rpcIdHelper->channelID(id, m_rpcIdHelper->doubletZ(id), m_rpcIdHelper->doubletPhi(id),
482 m_rpcIdHelper->gasGap(id), m_rpcIdHelper->measuresPhi(id), 1);
483 } case CSC: {
484 return m_cscIdHelper->channelID(id, m_cscIdHelper->chamberLayer(id), m_cscIdHelper->wireLayer(id),
485 m_cscIdHelper->measuresPhi(id), 1);
486 } case MM: {
487 return m_mmIdHelper->channelID(id, m_mmIdHelper->multilayer(id), m_mmIdHelper->gasGap(id), 1);
488 } case STGC: {
489 return m_stgcIdHelper->channelID(id, m_stgcIdHelper->multilayer(id),
490 m_stgcIdHelper->gasGap(id), m_stgcIdHelper->channelType(id), 1);
491 } default:
492 break;
493 }
495 return id;
496 }
497
499 switch (technologyIndex(id)) {
500 using enum TechnologyIndex;
501 case RPC: {
502 return m_rpcIdHelper->channelID(id, m_rpcIdHelper->doubletZ(id), m_rpcIdHelper->doubletPhi(id),
503 m_rpcIdHelper->gasGap(id), false, 1);
504 } case TGC: {
505 return m_tgcIdHelper->channelID(id, m_tgcIdHelper->gasGap(id), false, 1);
506 } case CSC: {
507 return m_cscIdHelper->channelID(id, m_cscIdHelper->chamberLayer(id), m_cscIdHelper->wireLayer(id), 1, 1);
508 } case STGC: {
509 return m_stgcIdHelper->channelID(id, m_stgcIdHelper->multilayer(id), m_stgcIdHelper->gasGap(id),
511 } case MM: {
512 return m_mmIdHelper->channelID(id, m_mmIdHelper->multilayer(id), m_mmIdHelper->gasGap(id), 1);
513 } default:
514 break;
515 }
516 return id;
517 }
518 int MuonIdHelperSvc::sector(const Identifier& id) const {
519 // TGC has different segmentation, return 0 for the moment
520 if (isTgc(id)) {
521 auto initTgcSectorMapping = [&]() -> std::vector<int>* {
522 std::vector<int>* mapping = nullptr;
523 StatusCode sc = m_detStore->retrieve(mapping, "TGC_SectorMapping");
524 if (sc.isFailure() || !mapping) {
525 ATH_MSG_WARNING("sector: failed to retrieve TGC sector mapping");
526 return nullptr;
527 }
528 ATH_MSG_DEBUG("sector: retrieve TGC sector mapping " << mapping->size());
529 return mapping;
530 };
531 static const std::vector<int> tgcSectorMapping = *initTgcSectorMapping();
532
533 IdentifierHash hash;
534 m_tgcIdHelper->get_module_hash(id, hash);
535 if (hash >= tgcSectorMapping.size()) {
536 ATH_MSG_WARNING("sector: TGC not yet supported");
537 return 0;
538 }
539 return tgcSectorMapping[hash];
540 }
541 int sect = 2 * stationPhi(id);
542 if (!isSmallChamber(id)) --sect;
543 return sect;
544 }
545
546 bool MuonIdHelperSvc::hasRPC() const { return m_rpcIdHelper != nullptr; }
547 bool MuonIdHelperSvc::hasTGC() const { return m_tgcIdHelper != nullptr; }
548 bool MuonIdHelperSvc::hasMDT() const { return m_mdtIdHelper != nullptr; }
549 bool MuonIdHelperSvc::hasCSC() const { return m_hasCSC; }
550 bool MuonIdHelperSvc::hasSTGC() const { return m_hasSTGC; }
551 bool MuonIdHelperSvc::hasMM() const { return m_hasMM; }
552
553
554 inline IdentifierHash MuonIdHelperSvc::moduleHash(const MuonIdHelper& idHelper, const Identifier& id) const{
555 IdentifierHash hash{};
556 if (idHelper.get_module_hash(id, hash) ||
557 static_cast<unsigned int>(hash) >= idHelper.module_hash_max()){
558 ATH_MSG_VERBOSE("Failed to deduce module hash "<<toString(id));
559 }
560 return hash;
561 }
563 IdentifierHash hash{};
564 if (idHelper.get_detectorElement_hash(id, hash) ||
565 static_cast<unsigned int>(hash)>= idHelper.detectorElement_hash_max()) {
566 ATH_MSG_VERBOSE("Failed to deduce detector element hash "<<toString(id));
567 }
568 return hash;
569 }
571 switch (technologyIndex(id)){
573 case MDT: {
574 return moduleHash(*m_mdtIdHelper, id);
575 }
576 case RPC: {
577 return moduleHash(*m_rpcIdHelper, id);
578 }
579 case TGC: {
580 return moduleHash(*m_tgcIdHelper, id);
581 }
582 case CSC: {
583 return moduleHash(*m_cscIdHelper, id);
584 }
585 case STGC: {
586 return moduleHash(*m_stgcIdHelper, id);
587 }
588 case MM: {
589 return moduleHash(*m_mmIdHelper, id);
590 }
591 default:
592 break;
593 }
594
595 ATH_MSG_WARNING("moduleHash(): No muon Identifier "<<id);
596 return IdentifierHash{};
597 }
599 switch (technologyIndex(id)){
601 case MDT: {
602 return detElementHash(*m_mdtIdHelper, id);
603 }
604 case RPC: {
605 return detElementHash(*m_rpcIdHelper, id);
606 }
607 case TGC: {
608 return detElementHash(*m_tgcIdHelper, id);
609 }
610 case CSC: {
611 return detElementHash(*m_cscIdHelper, id);
612 }
613 case STGC: {
614 return detElementHash(*m_stgcIdHelper, id);
615 }
616 case MM: {
617 return detElementHash(*m_mmIdHelper, id);
618 }
619 default:
620 break;
621 }
622 ATH_MSG_WARNING("detElementHash(): No muon Identifier "<<id);
623 return IdentifierHash{};
624 }
625 #define IMPL_FIELDGETTER(fieldName, retType) \
626 retType MuonIdHelperSvc::fieldName(const Identifier& id) const { \
627 switch (technologyIndex(id)) { \
628 using enum TechnologyIndex; \
629 case MDT: { \
630 return m_mdtIdHelper->fieldName(id); \
631 } case RPC: { \
632 return m_rpcIdHelper->fieldName(id); \
633 } case TGC: { \
634 return m_tgcIdHelper->fieldName(id); \
635 } case CSC: { \
636 return m_cscIdHelper->fieldName(id); \
637 } case STGC: { \
638 return m_stgcIdHelper->fieldName(id); \
639 } case MM: { \
640 return m_mmIdHelper->fieldName(id); \
641 } default: \
642 break; \
643 } \
644 return {}; \
645 }
648 IMPL_FIELDGETTER(stationName, int);
649 IMPL_FIELDGETTER(stationRegion, int);
650 IMPL_FIELDGETTER(measuresPhi, bool);
651 IMPL_FIELDGETTER(stationNameString, std::string);
652 #undef IMPL_FIELDGETTER
653} // namespace Muon
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_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
bool isValid(const T &p)
Av: we implement here an ATLAS-sepcific convention: all particles which are 99xxxxx are fine.
Definition AtlasPID.h:878
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
static Double_t sc
#define IMPL_FIELDGETTER(fieldName, retType)
Header file for AthHistogramAlgorithm.
This is a "hash" representation of an Identifier.
static int stationEtaMax(bool barrel)
static int stationEtaMin(bool barrel)
Access to min and max of level ranges.
const_id_iterator module_end() const
const_id_iterator module_begin() const
Iterators over full set of ids.
virtual int get_detectorElement_hash(const Identifier &id, IdentifierHash &hash_id) const
static const std::string BAD_NAME
virtual int get_module_hash(const Identifier &id, IdentifierHash &hash_id) const
size_type module_hash_max() const
the maximum hash value
size_type detectorElement_hash_max() const
virtual StatusCode initialize() override
AlgTool initilize.
virtual bool isMM(const Identifier &id) const override
returns whether this is a MM Identifier or not
virtual int stationName(const Identifier &id) const override
Return stationName for all technologies.
const TgcIdHelper * m_tgcIdHelper
virtual std::string chamberNameString(const Identifier &id) const override
print chamber name to string
const MdtIdHelper * m_mdtIdHelper
virtual Identifier detElId(const Identifier &id) const override
create a detector element ID
virtual bool isTgc(const Identifier &id) const override
returns whether this is a TGC Identifier or not
virtual MuonStationIndex::TechnologyIndex technologyIndex(const Identifier &id) const override
calculate layer index from Identifier
virtual IdentifierHash detElementHash(const Identifier &id) const override
Returns the detector element hash associated to an Identifier.
virtual bool isMdt(const Identifier &id) const override
returns whether this is a MDT Identifier or not
ServiceHandle< StoreGateSvc > m_detStore
bool hasCSC() const override
virtual int gasGap(const Identifier &id) const override
returns gas gap: gasGap for RPC + TGC, wireLayer for CSC, tube for MDT
virtual MuonStationIndex::DetectorRegionIndex regionIndex(const Identifier &id) const override
calculate detector region index from Identifier
Gaudi::Property< bool > m_hasMDT
virtual std::string toStringGasGap(const Identifier &id) const override
print all fields up to gas gap to string
virtual bool measuresPhi(const Identifier &id) const override
returns whether channel measures phi or not
std::unordered_set< Identifier > m_smdt_stat
virtual bool issTgc(const Identifier &id) const override
returns whether this is a sTGC Identifier or not
virtual bool issMdt(const Identifier &id) const override
returns whether this is a sMDT Identifier or not
bool hasMDT() const override
virtual std::string toStringDetEl(const Identifier &id) const override
print all fields up to detector element to string
Gaudi::Property< bool > m_hasMM
std::vector< TechIdx > m_technologies
virtual std::string toStringChamber(const Identifier &id) const override
print all fields up to chamber to string
virtual bool isSmallChamber(const Identifier &id) const override
returns whether this is a small chamber, always returns true for TGCs
MuonStationIndex::TechnologyIndex TechIdx
const RpcIdHelper * m_rpcIdHelper
Sub detector specific IdHelpers.
virtual std::string toString(const Identifier &id) const override
print all fields to string
const sTgcIdHelper * m_stgcIdHelper
virtual MuonStationIndex::ChIndex chamberIndex(const Identifier &id) const override
calculate chamber index from Identifier
virtual const std::set< MuonStationIndex::TechnologyIndex > & technologiesInStation(MuonStationIndex::StIndex stIndex) const override
Recieve all technologies in a station.
bool hasSTGC() const override
virtual MuonStationIndex::PhiIndex phiIndex(const Identifier &id) const override
calculate phi index from Identifier (not supported for MDT hits)
virtual std::string toStringTech(const Identifier &id) const override
print all fields up to technology to string
const MmIdHelper * m_mmIdHelper
const MuonIdHelper * m_primaryHelper
std::array< std::set< TechIdx >, static_cast< int >(StIdx::StIndexMax)> m_techPerStation
Array holding which technologies are there per station.
Gaudi::Property< bool > m_hasRPC
virtual bool isTrigger(const Identifier &id) const override
returns whether trigger chamber id or not
std::vector< StationNameData > m_stationNameData
bool hasMM() const override
virtual Identifier gasGapId(const Identifier &id) const override
create a gasGap ID (will return layer Id for MDTs)
MuonIdHelperSvc(const std::string &name, ISvcLocator *svc)
default AlgService constructor
virtual bool isRpc(const Identifier &id) const override
returns whether this is a RPC Identifier or not
Gaudi::Property< bool > m_hasSTGC
Gaudi::Property< bool > m_hasTGC
bool hasRPC() const override
virtual bool isEndcap(const Identifier &id) const override
returns whether this is an endcap Identifier or not
const CscIdHelper * m_cscIdHelper
virtual MuonStationIndex::StIndex stationIndex(const Identifier &id) const override
calculate station index from Identifier
virtual bool isCsc(const Identifier &id) const override
returns whether this is a CSC Identifier or not
virtual std::string toStringStation(const Identifier &id) const override
print all fields up to stationName to string
virtual std::string stationNameString(const Identifier &id) const override
Return the station name string for all technologies.
Gaudi::Property< bool > m_hasCSC
virtual bool isMuon(const Identifier &id) const override
returns whether this is a Muon Identifier or not
virtual MuonStationIndex::LayerIndex layerIndex(const Identifier &id) const override
calculate layer index from Identifier
virtual Identifier layerId(const Identifier &id) const override
create a layer ID, returns tube id for the MDTs
virtual bool hasHPTDC(const Identifier &id) const override
returns whether this Identifier belongs to an MDT with HPTDC or not NOTE that in Run4,...
virtual int sector(const Identifier &id) const override
return sector number 1-16, odd=large, even=small
virtual Identifier chamberId(const Identifier &id) const override
create a chamber ID
virtual IdentifierHash moduleHash(const Identifier &id) const override
Returns the module hash associated to an Identifier.
bool hasTGC() const override
StIndex
enum to classify the different station layers in the muon spectrometer
TechnologyIndex
enum to classify the different layers in the muon spectrometer
DetectorRegionIndex
enum to classify the different layers in the muon spectrometer
PhiIndex
enum to classify the different phi layers in the muon spectrometer
StIndex toStationIndex(ChIndex index)
convert ChIndex into StIndex
constexpr int toInt(const EnumType enumVal)
const std::string & stName(StIndex index)
convert StIndex into a string
const std::string & technologyName(TechnologyIndex index)
convert LayerIndex into a string
const std::string & chName(ChIndex index)
convert ChIndex into a string
LayerIndex toLayerIndex(ChIndex index)
convert ChIndex into LayerIndex
LayerIndex
enum to classify the different layers in the muon spectrometer
ChIndex
enum to classify the different chamber layers in the muon spectrometer
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
Definition TgcBase.h:6
MsgStream & msg
Definition testRead.cxx:32