ATLAS Offline Software
Loading...
Searching...
No Matches
sTgcIdHelper.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
9#include "IdDict/IdDictMgr.h"
10#include "IdDict/IdDictRegion.h"
12
13/*******************************************************************************/
14// Constructor/Destructor
15sTgcIdHelper::sTgcIdHelper() : MuonIdHelper("sTgcIdHelper", "stgc") {
16 m_module_hashes.fill(-1);
18}
19/*******************************************************************************/
20// Initialize dictionary
22 int status = 0;
23
24 // Check whether this helper should be reinitialized
25 if (!reinitialize(dict_mgr)) {
26 ATH_MSG_INFO("Request to reinitialize not satisfied - tags have not changed");
27 return (0);
28 } else {
29 ATH_MSG_DEBUG("(Re)initialize ");
30 }
31
32 // init base object
33 if (AtlasDetectorID::initialize_from_dictionary(dict_mgr)) return 1;
34
35 // Register version of the MuonSpectrometer dictionary
36 if (register_dict_tag(dict_mgr, "MuonSpectrometer")) return 1;
37
38 m_dict = dict_mgr.find_dictionary("MuonSpectrometer");
39 if (!m_dict) {
40 ATH_MSG_ERROR(" initialize_from_dict - cannot access MuonSpectrometer dictionary ");
41 return 1;
42 }
43
44 // Initialize some of the field indices
45 if (initLevelsFromDict()) return 1;
46
47 int index = technologyIndex("STGC");
48 if (index == -1) {
49 ATH_MSG_DEBUG("initLevelsFromDict - there are no sTGC entries in the dictionary! ");
50 return 0;
51 }
52
53 const IdDictField* field = m_dict->find_field("stgcMultilayer");
54 if (field) {
55 m_DETECTORELEMENT_INDEX = field->index();
56 } else {
57 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'stgcMultilayer' field ");
58 return 1;
59 }
60
61 field = m_dict->find_field("stgcGasGap");
62 if (field) {
63 m_GASGAP_INDEX = field->index();
64 } else {
65 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'stgcGasGap' field ");
66 return 1;
67 }
68
69 field = m_dict->find_field("stgcChannelType");
70 if (field) {
71 m_CHANNELTYPE_INDEX = field->index();
72 } else {
73 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'channelType' field ");
74 return 1;
75 }
76
77 field = m_dict->find_field("stgcChannel");
78 if (field) {
79 m_CHANNEL_INDEX = field->index();
80 } else {
81 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'channel' field ");
82 return 1;
83 }
84
85 // reinitialize the module ndex
86 // m_DETECTORELEMENT_INDEX = m_MODULE_INDEX;
87
88 // save an index to the first region of tgc
89 const IdDictGroup* stgcGroup = m_dict->find_group("stgc");
90 if (!stgcGroup) {
91 ATH_MSG_ERROR("Cannot find stgc group");
92 return 1;
93 } else {
94 m_GROUP_INDEX = stgcGroup->region(0).index();
95 }
96
97 const IdDictRegion& region = m_dict->region(m_GROUP_INDEX);
105
106 ATH_MSG_DEBUG(" sTGC decode index and bit fields for each level: " << std::endl
107 << " muon " << m_muon_impl.show_to_string() << std::endl
108 << " station " << m_sta_impl.show_to_string() << std::endl
109 << " eta " << m_eta_impl.show_to_string() << std::endl
110 << " phi " << m_phi_impl.show_to_string() << std::endl
111 << " technology " << m_tec_impl.show_to_string() << std::endl
112 << " multilayer " << m_mplet_impl.show_to_string() << std::endl
113 << " gasgap " << m_gap_impl.show_to_string() << std::endl
114 << " channelType " << m_typ_impl.show_to_string() << std::endl
115 << " channel " << m_cha_impl.show_to_string());
116
117 //
118 // Build multirange for the valid set of identifiers
119 //
120
121 // Find value for the field MuonSpectrometer
122 int muonField = -1;
123 const IdDictDictionary* atlasDict = dict_mgr.find_dictionary("ATLAS");
124 if (atlasDict->get_label_value("subdet", "MuonSpectrometer", muonField)) {
125 ATH_MSG_ERROR("Could not get value for label 'MuonSpectrometer' of field 'subdet' in dictionary " << atlasDict->name());
126 return 1;
127 }
128
129 // Build MultiRange down to "technology" for all (muon) regions
130 ExpandedIdentifier region_id;
131 region_id.add(muonField);
132 Range prefix;
133 MultiRange muon_range = m_dict->build_multirange(region_id, prefix, "technology");
134 if (muon_range.size() > 0) {
135 ATH_MSG_INFO("MultiRange built successfully to Technology: "
136 << "MultiRange size is " << muon_range.size());
137 } else {
138 ATH_MSG_ERROR("Muon sTGC detector element MultiRange is empty");
139 return 1;
140 }
141
142 // Build MultiRange down to "detector element" for all sTGC regions
143 ExpandedIdentifier detectorElement_region;
144 detectorElement_region.add(muonField);
145 Range detectorElement_prefix;
146 MultiRange muon_detectorElement_range = m_dict->build_multirange(detectorElement_region, detectorElement_prefix, "stgcMultilayer");
147 if (muon_detectorElement_range.size() > 0) {
148 ATH_MSG_INFO("MultiRange built successfully to detector element: "
149 << "Multilayer MultiRange size is " << muon_detectorElement_range.size());
150 } else {
151 ATH_MSG_ERROR("Muon sTGC detector element MultiRange is empty");
152 }
153
154 // Build MultiRange down to "channel" for all sTGC regions
155 ExpandedIdentifier stgc_region;
156 stgc_region.add(muonField);
157 Range stgc_prefix;
158 MultiRange muon_channel_range = m_dict->build_multirange(stgc_region, stgc_prefix, "stgcChannel");
159 if (muon_channel_range.size() > 0) {
160 ATH_MSG_INFO("MultiRange built successfully to channel: "
161 << "MultiRange size is " << muon_channel_range.size());
162 } else {
163 ATH_MSG_ERROR("Muon sTGC detector MultiRange is empty for channels");
164 return 1;
165 }
166
167 // build sTGC module ranges
168 // Find the regions that have a "technology field" that matches the sTGC and save them
169 int stgcField = -1;
170 status += m_dict->get_label_value("technology", "STGC", stgcField);
171
172 for (int i = 0; i < (int)muon_range.size(); ++i) {
173 const Range& range = muon_range[i];
174 if (range.fields() > m_TECHNOLOGY_INDEX) {
175 const Range::field& field = range[m_TECHNOLOGY_INDEX];
176 if (field.match((ExpandedIdentifier::element_type)stgcField)) {
177 m_full_module_range.add(range);
178 ATH_MSG_DEBUG("field size is " << (int)range.cardinality() << " field index = " << i);
179 }
180 }
181 }
182
183 for (int j = 0; j < (int)muon_detectorElement_range.size(); ++j) {
184 const Range& range = muon_detectorElement_range[j];
185 if (range.fields() > m_TECHNOLOGY_INDEX) {
186 const Range::field& field = range[m_TECHNOLOGY_INDEX];
187 if (field.match((ExpandedIdentifier::element_type)stgcField)) {
189 ATH_MSG_DEBUG("detector element field size is " << (int)range.cardinality() << " field index = " << j);
190 }
191 }
192 }
193
194 for (int j = 0; j < (int)muon_channel_range.size(); ++j) {
195 const Range& range = muon_channel_range[j];
196 if (range.fields() > m_TECHNOLOGY_INDEX) {
197 const Range::field& field = range[m_TECHNOLOGY_INDEX];
198 if (field.match((ExpandedIdentifier::element_type)stgcField)) {
199 m_full_channel_range.add(range);
200 ATH_MSG_DEBUG("channel field size is " << (int)range.cardinality() << " field index = " << j);
201 }
202 }
203 }
204
205 // test to see that the multi range is not empty
206 if (m_full_module_range.size() == 0) {
207 ATH_MSG_ERROR("sTGC MultiRange ID is empty for modules");
208 return 1;
209 }
210
211 // test to see that the detector element multi range is not empty
212 if (m_full_detectorElement_range.size() == 0) {
213 ATH_MSG_ERROR("sTGC MultiRange ID is empty for detector elements");
214 return 1;
215 }
216
217 // test to see that the multi range is not empty
218 if (m_full_channel_range.size() == 0) {
219 ATH_MSG_ERROR("sTGC MultiRange ID is empty for channels");
220 return 1;
221 }
222
223 // Setup the hash tables for sTGC
224 ATH_MSG_INFO("Initializing sTGC hash indices ... ");
225 status += init_hashes();
226 status += init_detectorElement_hashes(); // same as module hash
227 status += init_id_to_hashes();
228
229 /*
230 //comment out this bit to test the identifiers
231
232 status = init_channel_hashes();
233 std::cout << " looping over identifiers " << std::endl;
234 const_id_iterator it = channel_begin();
235 const_id_iterator it_end = channel_end();
236 for( ;it!=it_end;++it ){
237 if( !is_stgc(*it) ) (*m_Log) << MSG::DEBUG << "BadStgc: not sTGC " << print_to_string(*it) << endmsg;
238 if( !valid(*it) ) (*m_Log) << MSG::DEBUG << "BadStgc: not valid " << print_to_string(*it) << endmsg;
239 }
240
241 */
242
243 // Setup hash tables for finding neighbors
244 ATH_MSG_INFO("Initializing sTGC hash indices for finding neighbors ... ");
245 status += init_neighbors();
246
247 m_init = true;
248 return (status);
249} // end sTgcIdHelper::initialize_from_dictionary
250/*******************************************************************************/
251inline unsigned int sTgcIdHelper::moduleHashIdx(const Identifier& id) const{
254 constexpr unsigned int C = s_phiDim;
255 constexpr unsigned int BxC = C*s_etaDim;
256 const int stEta = stationEta(id);
257 return (stationName(id) - m_stationShift)*BxC + (stEta + s_etaDim/2 - (stEta>0))*C + (stationPhi(id) -1);
258}
259inline unsigned int sTgcIdHelper::detEleHashIdx(const Identifier& id) const{
260 return moduleHashIdx(id) *s_mlDim + (multilayer(id) -1);
261}
262
264 for (const Identifier& id : m_module_vec) m_stationShift = std::min(m_stationShift, 1u* stationName(id));
265 unsigned int hash_max = module_hash_max();
266 for (unsigned int i = 0; i < hash_max; ++i) {
267 const Identifier& id = m_module_vec[i];
268 const unsigned idx = moduleHashIdx(id);
269 if (idx >= m_module_hashes.size() || m_module_hashes[idx] < hash_max){
270 ATH_MSG_FATAL("Failed to assign module hash to "<<show_to_string(id));
271 return 1;
272 }
273 m_module_hashes[idx] = i;
274 }
275
276 hash_max = detectorElement_hash_max();
277 for (unsigned int i = 0; i < hash_max; ++i) {
278 const Identifier& id = m_detectorElement_vec[i];
279 const unsigned idx = detEleHashIdx(id);
280 if (idx >= m_detectorElement_hashes.size() || m_detectorElement_hashes[idx] < hash_max){
281 ATH_MSG_FATAL("Failed to assign detector hash to "<<show_to_string(id));
282 return 1;
283 }
285 }
286 return 0;
287} // end sTgcIdHelper::init_id_to_hashes()
288/*******************************************************************************/
290 const unsigned int idx = moduleHashIdx(id);
291 if (idx >= m_module_hashes.size()) return 1;
292 hash_id = m_module_hashes[idx];
293 return 0;
294} // end sTgcIdHelper::get_module_hash
295/*******************************************************************************/
297 const unsigned int idx = detEleHashIdx(id);
298 if (idx >= m_detectorElement_hashes.size()) return 1;
299 hash_id = m_detectorElement_hashes[idx];
300 return 0;
301 // return get_module_hash(id, hash_id);
302}
303
304/*******************************************************************************/
306 assert(is_stgc(channelID));
308 m_gap_impl.reset(result);
309 m_typ_impl.reset(result);
310 m_cha_impl.reset(result);
311 return result;
312}
313/*******************************************************************************/
315 Identifier result(moduleID);
317 return result;
318}
320 try {
321 const Identifier result = multilayerID(moduleID, multilayer);
323 return result;
324 } catch (const std::out_of_range&) { isValid = false; }
325 return Identifier{0};
326}
327/*******************************************************************************/
328
329// febID constructs an identifier that can be associcate with a region of the detector that is read out by the same front end board
343 return channelID(channelId, multilayer(channelId), gasGap(channelId),(int)(channelType(channelId) ==sTgcChannelTypes::Strip ? sTgcChannelTypes::Strip : sTgcChannelTypes::Pad), 1);
344}
345
346
347Identifier sTgcIdHelper::hvID(int stationName, int stationEta, int stationPhi, int multilayer, int gasGap, bool isInnerQ1)const{
348 int channel = 1;
349 if(!isInnerQ1 && std::abs(stationEta)==1) channel = 100;
351}
352
353Identifier sTgcIdHelper::hvID(int stationName, int stationEta, int stationPhi, int multilayer, int gasGap, bool isInnerQ1, bool& isValid)const{
354 int channel = 1;
355 if(!isInnerQ1 && std::abs(stationEta)==1) channel = 100;
357}
358
359Identifier sTgcIdHelper::hvID(const std::string& stationName, int stationEta, int stationPhi, int multilayer, int gasGap, bool isInnerQ1)const{
360 int channel = 1;
361 if(!isInnerQ1 && std::abs(stationEta)==1) channel = 100;
363}
364
365Identifier sTgcIdHelper::hvID(const std::string& stationName, int stationEta, int stationPhi, int multilayer, int gasGap, bool isInnerQ1, bool& isValid)const{
366 int channel = 1;
367 if(!isInnerQ1 && std::abs(stationEta)==1) channel = 100;
369}
370
371Identifier sTgcIdHelper::hvID(const Identifier& channelId, bool isInnerQ1)const{
372 int channel = 1;
373 if(std::abs(stationEta(channelId))==1 && !isInnerQ1) channel = 100;
374 return channelID(channelId, multilayer(channelId), gasGap(channelId), sTgcChannelTypes::Strip, channel);
375}
376
377
378Identifier sTgcIdHelper::hvID(const Identifier& channelId, bool isInnerQ1, bool& isValid)const{
379 int channel = 1;
380 if(std::abs(stationEta(channelId))==1 && !isInnerQ1) channel = 100;
381 return channelID(channelId, multilayer(channelId), gasGap(channelId), sTgcChannelTypes::Strip, channel, isValid);
382}
383
384
385
386
387
388
389
390
391
392/*******************************************************************************/
393void sTgcIdHelper::idChannels(const Identifier& id, std::vector<Identifier>& vect) const {
394 vect.clear();
395 Identifier parent = parentID(id);
396 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
397 const Range& range = m_full_channel_range[i];
398 ConstRangeIterator rit(range);
399 for (const auto & expId:rit) {
400 Identifier child;
401 get_id(expId, child);
402 if (parentID(child) == parent) vect.push_back(child);
403 }
404 }
405}
406/*******************************************************************************/
408 ExpandedIdentifier expId;
409 IdContext eta_context(expId, 0, m_ETA_INDEX);
410 if (!get_expanded_id(id, expId, &eta_context)) {
411 int result = -999;
412 for (unsigned int i = 0; i < m_full_module_range.size(); ++i) {
413 const Range& range = m_full_module_range[i];
414 if (range.match(expId)) {
415 const Range::field& eta_field = range[m_ETA_INDEX];
416 if (not eta_field.empty()) {
417 int etamin = eta_field.get_minimum();
418 if (-999 == result) {
419 result = etamin;
420 } else {
421 if (etamin < result) result = etamin;
422 }
423 }
424 }
425 }
426 return result;
427 }
428 return 999; // default
429} // end TgcIdHelper::stationEtaMin
430/*******************************************************************************/
432 ExpandedIdentifier expId;
433 IdContext eta_context(expId, 0, m_ETA_INDEX);
434 if (!get_expanded_id(id, expId, &eta_context)) {
435 int result = -999;
436 for (unsigned int i = 0; i < m_full_module_range.size(); ++i) {
437 const Range& range = m_full_module_range[i];
438 if (range.match(expId)) {
439 const Range::field& eta_field = range[m_ETA_INDEX];
440 if (not eta_field.empty()) {
441 int etamax = eta_field.get_maximum();
442 if (result < etamax) result = etamax;
443 }
444 }
445 }
446 return result;
447 }
448 return -999;
449} // end TgcIdHelper::stationEtaMax
450/*******************************************************************************/
452 ExpandedIdentifier expId;
453 IdContext phi_context(expId, 0, m_PHI_INDEX);
454
455 if (!get_expanded_id(id, expId, &phi_context)) {
456 for (unsigned int i = 0; i < m_full_module_range.size(); ++i) {
457 const Range& range = m_full_module_range[i];
458 if (range.match(expId)) {
459 const Range::field& phi_field = range[m_PHI_INDEX];
460 if (not phi_field.empty()) { return (phi_field.get_minimum()); }
461 }
462 }
463 }
464 // Failed to find the min
465 return 999;
466}
467/*******************************************************************************/
469 ExpandedIdentifier expId;
470 IdContext phi_context(expId, 0, m_PHI_INDEX);
471
472 if (!get_expanded_id(id, expId, &phi_context)) {
473 for (unsigned int i = 0; i < m_full_module_range.size(); ++i) {
474 const Range& range = m_full_module_range[i];
475 if (range.match(expId)) {
476 const Range::field& phi_field = range[m_PHI_INDEX];
477 if (not phi_field.empty()) { return (phi_field.get_maximum()); }
478 }
479 }
480 }
481 // Failed to find the max
482 return -999;
483}
484/*******************************************************************************/
486 ExpandedIdentifier expId;
487 IdContext context = technology_context();
488 if (!get_expanded_id(id, expId, &context)) {
489 int result = -999;
490 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
491 const Range& range = m_full_channel_range[i];
492 if (range.match(expId)) {
493 const Range::field& multilayer_field = range[m_DETECTORELEMENT_INDEX];
494 if (not multilayer_field.empty()) {
495 int multilayermax = multilayer_field.get_maximum();
496 if (result < multilayermax) result = multilayermax;
497 }
498 }
499 }
500 return result;
501 }
502 return -999;
503}
504/*******************************************************************************/
506 ExpandedIdentifier expId;
507 IdContext multilayer_context(expId, 0, m_DETECTORELEMENT_INDEX);
508 if (!get_expanded_id(id, expId, &multilayer_context)) {
509 int result = -999;
510 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
511 const Range& range = m_full_channel_range[i];
512 if (range.match(expId)) {
513 const Range::field& multilayer_field = range[m_DETECTORELEMENT_INDEX];
514 if (not multilayer_field.empty()) {
515 int multilayermin = multilayer_field.get_minimum();
516 if (-999 == result) {
517 result = multilayermin;
518 } else {
519 if (multilayermin < result) result = multilayermin;
520 }
521 }
522 }
523 }
524 return result;
525 }
526 return 999;
527}
528/*******************************************************************************/
530 ExpandedIdentifier expId;
531 IdContext multilayer_context(expId, 0, m_DETECTORELEMENT_INDEX);
532 if (!get_expanded_id(id, expId, &multilayer_context)) {
533 int result = -999;
534 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
535 const Range& range = m_full_channel_range[i];
536 if (range.match(expId)) {
537 const Range::field& multilayer_field = range[m_DETECTORELEMENT_INDEX];
538 if (not multilayer_field.empty()) {
539 int multilayermax = multilayer_field.get_maximum();
540 if (result < multilayermax) result = multilayermax;
541 }
542 }
543 }
544 return result;
545 }
546 return -999;
547}
548/*******************************************************************************/
550 ExpandedIdentifier expId;
551 IdContext gasgap_context(expId, 0, m_GASGAP_INDEX);
552 if (!get_expanded_id(id, expId, &gasgap_context)) {
553 int result = -999;
554 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
555 const Range& range = m_full_channel_range[i];
556 if (range.match(expId)) {
557 const Range::field& gasgap_field = range[m_GASGAP_INDEX];
558 if (not gasgap_field.empty()) {
559 int gasgapmin = gasgap_field.get_minimum();
560 if (-999 == result) {
561 result = gasgapmin;
562 } else {
563 if (gasgapmin < result) result = gasgapmin;
564 }
565 }
566 }
567 }
568 return result;
569 }
570 return 999;
571}
572/*******************************************************************************/
574 ExpandedIdentifier expId;
575 IdContext gasgap_context(expId, 0, m_GASGAP_INDEX);
576 if (!get_expanded_id(id, expId, &gasgap_context)) {
577 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
578 const Range& range = m_full_channel_range[i];
579 if (range.match(expId)) {
580 const Range::field& gasgap_field = range[m_GASGAP_INDEX];
581 if (not gasgap_field.empty()) { return (gasgap_field.get_maximum()); }
582 }
583 }
584 }
585 // Failed to find the max
586 return -999;
587}
588/*******************************************************************************/
590 ExpandedIdentifier expId;
591 IdContext channeltype_context(expId, 0, m_CHANNELTYPE_INDEX);
592 if (!get_expanded_id(id, expId, &channeltype_context)) {
593 int result = -999;
594 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
595 const Range& range = m_full_channel_range[i];
596 if (range.match(expId)) {
597 const Range::field& channeltype_field = range[m_CHANNELTYPE_INDEX];
598 if (not channeltype_field.empty()) {
599 int channeltypemin = channeltype_field.get_minimum();
600 if (-999 == result) {
601 result = channeltypemin;
602 } else {
603 if (channeltypemin < result) result = channeltypemin;
604 }
605 }
606 }
607 }
608 return result;
609 }
610 return 999;
611}
612/*******************************************************************************/
614 ExpandedIdentifier expId;
615 IdContext channeltype_context(expId, 0, m_CHANNELTYPE_INDEX);
616 if (!get_expanded_id(id, expId, &channeltype_context)) {
617 int result = -999;
618 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
619 const Range& range = m_full_channel_range[i];
620 if (range.match(expId)) {
621 const Range::field& channeltype_field = range[m_CHANNELTYPE_INDEX];
622 if (not channeltype_field.empty()) {
623 int channeltypemax = channeltype_field.get_maximum();
624 if (result < channeltypemax) result = channeltypemax;
625 }
626 }
627 }
628 return result;
629 }
630 return -999;
631}
632/*******************************************************************************/
634 ExpandedIdentifier expId;
636 if (!get_expanded_id(id, expId, &channel_context)) {
637 int result = -999;
638 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
639 const Range& range = m_full_channel_range[i];
640 if (range.match(expId)) {
641 const Range::field& channel_field = range[m_CHANNEL_INDEX];
642 if (not channel_field.empty()) {
643 int channelmin = channel_field.get_minimum();
644 if (-999 == result) {
645 result = channelmin;
646 } else {
647 if (channelmin < result) result = channelmin;
648 }
649 }
650 }
651 }
652 return result;
653 }
654 return 999;
655}
656/*******************************************************************************/
658 ExpandedIdentifier expId;
660 if (!get_expanded_id(id, expId, &channel_context)) {
661 int result = -999;
662 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
663 const Range& range = m_full_channel_range[i];
664 if (range.match(expId)) {
665 const Range::field& channel_field = range[m_CHANNEL_INDEX];
666 if (not channel_field.empty()) {
667 int channelmax = channel_field.get_maximum();
668 if (result < channelmax) result = channelmax;
669 }
670 }
671 }
672 return result;
673 }
674 return -999;
675}
676/*******************************************************************************/
677int sTgcIdHelper::padEta(const Identifier& id) const {
678 int ChannelType = channelType(id);
679 int PadEta = 0;
680 if (ChannelType == Pad) {
681 int Channel = channel(id);
682 PadEta = ((Channel - 1) % PadEtaMax) + 1;
683 }
684 return PadEta;
685}
686/*******************************************************************************/
687int sTgcIdHelper::padPhi(const Identifier& id) const {
688 int ChannelType = channelType(id);
689 int PadPhi = 0;
690 if (ChannelType == Pad) {
691 int Channel = channel(id);
692 PadPhi = ((Channel - 1) / PadEtaMax) + 1;
693 }
694 return PadPhi;
695}
696/*******************************************************************************/
697// validation of levels
698bool sTgcIdHelper::valid(const Identifier& id) const {
699 if (!validElement(id)) return false;
700
701 int mplet = multilayer(id);
702 if ((mplet < multilayerMin(id)) || (mplet > multilayerMax(id))) {
703 ATH_MSG_DEBUG("Invalid multilayer=" << mplet << " multilayerMin=" << multilayerMin(id) << " multilayerMax=" << multilayerMax(id));
704 return false;
705 }
706
707 int gasG = gasGap(id);
708 if (gasG < gasGapMin(id) || gasG > gasGapMax(id)) {
709 ATH_MSG_DEBUG("Invalid gasGap=" << gasG << " gasGapMin=" << gasGapMin(id) << " gasGapMax=" << gasGapMax(id));
710 return false;
711 }
712
713 int channeltype = channelType(id);
714 if (channeltype < channelTypeMin(id) || channeltype > channelTypeMax(id)) {
715 ATH_MSG_DEBUG("Invalid channelType=" << channeltype << " channelTypeMin=" << channelTypeMin(id)
716 << " channelTypeMax=" << channelTypeMax(id));
717 return false;
718 }
719
720 int element = channel(id);
721 if (element < channelMin(id) || element > channelMax(id)) {
722 ATH_MSG_DEBUG("Invalid channel=" << element << " channelMin=" << channelMin(id) << " channelMax=" << channelMax(id));
723 return false;
724 }
725
726 if (channeltype == Pad) {
727 int PadEta = padEta(id);
728 int PadPhi = padPhi(id);
729 if (PadEta < PadEtaMin || PadEta > PadEtaMax) {
730 ATH_MSG_DEBUG("Invalid padEta=" << PadEta << " padEtaMin=" << PadEtaMin << " padEtaMax=" << PadEtaMax);
731 return false;
732 }
733 if (PadPhi < PadPhiMin || PadPhi > PadPhiMax) {
734 ATH_MSG_DEBUG("Invalid padEPhi" << PadPhi << " padPhiMin=" << PadPhiMin << " padPhiMax=" << PadPhiMax);
735 return false;
736 }
737 }
738
739 return true;
740} // end sTgcIdHelper::valid
741/*******************************************************************************/
742bool sTgcIdHelper::isStNameInTech(const std::string& name) const { return 'S' == name[0] && 'T' == name[1]; }
744 int station = stationName(id);
745 if (!validStation(station)) {
746 ATH_MSG_DEBUG("Invalid stationName=" << stationNameString(station));
747 return false;
748 }
749
750 int eta = stationEta(id);
751 if (eta < stationEtaMin(id) || eta > stationEtaMax(id)) {
752 ATH_MSG_DEBUG("Invalid stationEta=" << eta << " for stationName=" << stationNameString(station) << " stationIndex=" << station
753 << " stationEtaMin=" << stationEtaMin(id) << " stationEtaMax=" << stationEtaMax(id));
754 return false;
755 }
756
757 int phi = stationPhi(id);
758 if (phi < stationPhiMin(id) || phi > stationPhiMax(id)) {
759 ATH_MSG_DEBUG("Invalid stationPhi=" << phi << " for stationName=" << stationNameString(station) << " stationIndex=" << station
760 << " stationPhiMin=" << stationPhiMin(id) << " stationPhiMax=" << stationPhiMax(id));
761 return false;
762 }
763 return true;
764
765} // end sTgcIdHelper::validElement
766/*******************************************************************************/
767// Private validation of levels
770 ATH_MSG_DEBUG("Invalid stationName=" << stationNameString(stationName));
771 return false;
772 }
774 ATH_MSG_DEBUG("Invalid stationEta=" << stationEta << " for stationName=" << stationNameString(stationName)
775 << " stationIndex=" << stationName << " stationEtaMin=" << stationEtaMin(id)
776 << " stationEtaMax=" << stationEtaMax(id));
777 return false;
778 }
780 ATH_MSG_DEBUG("Invalid stationPhi=" << stationPhi << " for stationName=" << stationNameString(stationName)
781 << " stationIndex=" << stationName << " stationPhiMin=" << stationPhiMin(id)
782 << " stationPhiMax=" << stationPhiMax(id));
783 return false;
784 }
785 return true;
786} // end sTgcIdHelper::validElement
787/*******************************************************************************/
788// Check values down to readout channel level
790 int channelType, int channel) const {
791 if (!validElement(id, stationName, stationEta, stationPhi)) return false;
792
793 if ((multilayer < multilayerMin(id)) || (multilayer > multilayerMax(id))) {
794 ATH_MSG_DEBUG("Invalid multilayer=" << multilayer << " multilayerMin=" << multilayerMin(id)
795 << " multilayerMax=" << multilayerMax(id));
796 return false;
797 }
798
799 if (gasGap < gasGapMin(id) || gasGap > gasGapMax(id)) {
800 ATH_MSG_DEBUG("Invalid gasGap=" << gasGap << " gasGapMin=" << gasGapMin(id) << " gasGapMax=" << gasGapMax(id));
801 return false;
802 }
804 ATH_MSG_DEBUG("Invalid channelType=" << channelType << " channelTypeMin=" << channelTypeMin(id)
805 << " channelTypeMax=" << channelTypeMax(id));
806 return false;
807 }
808 if (channel < channelMin(id) || channel > channelMax(id)) {
809 ATH_MSG_DEBUG("Invalid channel=" << channel << " channelMin=" << channelMin(id) << " channelMax=" << channelMax(id));
810 return false;
811 }
812 if (channelType == Pad) {
813 int PadEta = padEta(id);
814 int PadPhi = padPhi(id);
815 if (PadEta < PadEtaMin || PadEta > PadEtaMax) {
816 ATH_MSG_DEBUG("Invalid padEta=" << PadEta << " padEtaMin=" << PadEtaMin << " padEtaMax=" << PadEtaMax);
817 return false;
818 }
819 if (PadPhi < PadPhiMin || PadPhi > PadPhiMax) {
820 ATH_MSG_DEBUG("Invalid padEPhi" << PadPhi << " padPhiMin=" << PadPhiMin << " padPhiMax=" << PadPhiMax);
821 return false;
822 }
823 }
824 return true;
825} // end sTgcIdHelper::validChannel
826/*******************************************************************************/
827// Check values down to readout channel level
829 int channelType, int padEta, int padPhi) const {
830 if (!validElement(id, stationName, stationEta, stationPhi)) return false;
831
832 if ((multilayer < multilayerMin(id)) || (multilayer > multilayerMax(id))) {
833 ATH_MSG_DEBUG("Invalid multilayer=" << multilayer << " multilayerMin=" << multilayerMin(id)
834 << " multilayerMax=" << multilayerMax(id));
835 return false;
836 }
837
838 if (gasGap < gasGapMin(id) || gasGap > gasGapMax(id)) {
839 ATH_MSG_DEBUG("Invalid gasGap=" << gasGap << " gasGapMin=" << gasGapMin(id) << " gasGapMax=" << gasGapMax(id));
840 return false;
841 }
842 if (channelType != Pad) {
843 ATH_MSG_DEBUG("Invalid channelType=" << channelType << " channelType must be " << Pad << " when specifying padEta and padPhi");
844 return false;
845 }
846 int channel = (padPhi - 1) * PadEtaMax + padEta;
847 if (channel < channelMin(id) || channel > channelMax(id)) {
848 ATH_MSG_DEBUG("Invalid channel=" << channel << " channelMin=" << channelMin(id) << " channelMax=" << channelMax(id)
849 << " for given padEta=" << padEta << " and padPhi=" << padPhi);
850 return false;
851 }
853 ATH_MSG_DEBUG("Invalid padEta=" << padEta << " padEtaMin=" << PadEtaMin << " padEtaMax=" << PadEtaMax);
854 return false;
855 }
857 ATH_MSG_DEBUG("Invalid padEPhi" << padPhi << " padPhiMin=" << PadPhiMin << " padPhiMax=" << PadPhiMax);
858 return false;
859 }
860 return true;
861} // end sTgcIdHelper::validChannel
862 /*******************************************************************************/
863 // Construct ID from components
865 // pack fields independently
866 Identifier result((Identifier::value_type)0);
872 return result;
873}
875 try {
878 return result;
879 } catch (const std::out_of_range&) { isValid = false; }
880 return Identifier{0};
881}
882
883/*******************************************************************************/
884Identifier sTgcIdHelper::elementID(const std::string& stationNameStr, int stationEta, int stationPhi, bool& isValid) const {
885 return elementID(stationNameIndex(stationNameStr), stationEta, stationPhi, isValid);
886}
887Identifier sTgcIdHelper::elementID(const std::string& stationNameStr, int stationEta, int stationPhi) const {
888 return elementID(stationNameIndex(stationNameStr), stationEta, stationPhi);
889}
890
891/*******************************************************************************/
893/*******************************************************************************/
895 int channel) const {
896 // pack fields independently
897 Identifier result((Identifier::value_type)0);
904 m_gap_impl.pack(gasGap, result);
907
908 return result;
909}
911 int channel, bool& isValid) const {
912 try {
915 return result;
916 } catch (const std::out_of_range&) { isValid = false; }
917 return Identifier{0};
918}
919/*******************************************************************************/
920Identifier sTgcIdHelper::channelID(const std::string& stationNameStr, int stationEta, int stationPhi, int multilayer, int gasGap,
921 int channelType, int channel) const {
923}
924Identifier sTgcIdHelper::channelID(const std::string& stationNameStr, int stationEta, int stationPhi, int multilayer, int gasGap,
925 int channelType, int channel, bool& isValid) const {
927}
928
929/*******************************************************************************/
939 try{
942 return result;
943 } catch (const std::out_of_range&) { isValid = false; }
944 return Identifier{0};
945}
946/*******************************************************************************/
948 int padPhi) const {
949 int channel = -1;
950 if (channelType == Pad) {
951 channel = (padPhi - 1) * PadEtaMax + padEta;
952 } else {
953 return Identifier{-1};
954 }
955 // pack fields independently
956 Identifier result((Identifier::value_type)0);
963 m_gap_impl.pack(gasGap, result);
965
967
968 return result;
969}
971 int padPhi, bool& isValid) const {
972 try {
974 isValid = (channelType) == Pad &&
976 return result;
977 } catch (const std::out_of_range&) { isValid = false; }
978 return Identifier{0};
979}
980/*******************************************************************************/
981Identifier sTgcIdHelper::padID(const std::string& stationNameStr, int stationEta, int stationPhi, int multilayer, int gasGap,
982 int channelType, int padEta, int padPhi) const {
984}
985
986Identifier sTgcIdHelper::padID(const std::string& stationNameStr, int stationEta, int stationPhi, int multilayer, int gasGap,
987 int channelType, int padEta, int padPhi, bool& isValid) const {
989}
990
991/*******************************************************************************/
1004 bool& isValid) const {
1005 try {
1007 isValid = (channelType == Pad) && valid(result);
1008 return result;
1009 } catch (const std::out_of_range&) { isValid = false; }
1010 return Identifier{0};
1011}
1012/*******************************************************************************/
1013// get parent id from strip or gang identifier
1015 assert(is_stgc(id));
1016 Identifier result(id);
1017 m_mplet_impl.reset(result);
1018 m_gap_impl.reset(result);
1019 m_typ_impl.reset(result);
1020 m_cha_impl.reset(result);
1021 return result;
1022}
1023/*******************************************************************************/
1024// Access to components of the ID
1025int sTgcIdHelper::multilayer(const Identifier& id) const { return m_mplet_impl.unpack(id); }
1026/*******************************************************************************/
1027// Access to components of the ID
1028int sTgcIdHelper::gasGap(const Identifier& id) const { return m_gap_impl.unpack(id); }
1029/*******************************************************************************/
1030int sTgcIdHelper::channelType(const Identifier& id) const { return m_typ_impl.unpack(id); }
1031/*******************************************************************************/
1033bool sTgcIdHelper::measuresPhi(const Identifier& id) const { return (channelType(id) == Strip) ? 0 : 1; }
1034/*******************************************************************************/
1035int sTgcIdHelper::channel(const Identifier& id) const { return m_cha_impl.unpack(id); }
1036/*******************************************************************************/
1037// Access to min and max of level ranges
1039/*******************************************************************************/
1041/*******************************************************************************/
1043/*******************************************************************************/
1045/*******************************************************************************/
1047/*******************************************************************************/
1049/*******************************************************************************/
1051/*******************************************************************************/
1053/*******************************************************************************/
1055/*******************************************************************************/
1057/*******************************************************************************/
1059/*******************************************************************************/
1061/*******************************************************************************/
1063/*******************************************************************************/
1065/*******************************************************************************/
1067/*******************************************************************************/
1069/*******************************************************************************/
1072 int stgcField = technologyIndex("STGC");
1073 if (m_dict) { stgcField = stgc_field_value(); }
1074 return stgcField;
1075}
1076/*******************************************************************************/
1078/*******************************************************************************/
1080
1081/*******************************************************************************/
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(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
int muon_field_value() const
virtual int initialize_from_dictionary(const IdDictMgr &dict_mgr) override
Initialization from the identifier dictionary.
bool reinitialize(const IdDictMgr &dict_mgr)
Test whether an idhelper should be reinitialized based on the change of tags.
int register_dict_tag(const IdDictMgr &dict_mgr, const std::string &dict_name)
Register the file and tag names for a particular IdDict dictionary.
std::string show_to_string(Identifier id, const IdContext *context=0, char sep='.') const
or provide the printout in string form
int stgc_field_value() const
void add(element_type value)
Append a value into a new field.
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
Definition IdContext.h:26
int get_label_value(const std::string &field, const std::string &label, int &value) const
const std::string & name() const
Dictionary name.
const IdDictRegion & region(size_t index) const
const IdDictDictionary * find_dictionary(const std::string &name) const
Access dictionary by name.
size_t index() const
const IdDictFieldImplementation & implementation(size_t i) const
element_type get_minimum() const
Query the values.
bool empty() const
If true, this field does not have any constraints, and may hold any value representable by element_ty...
element_type get_maximum() const
This is a "hash" representation of an Identifier.
A MultiRange combines several Ranges.
Definition MultiRange.h:17
size_type size() const
int stationNameIndex(const std::string &name) const
int stationEta(const Identifier &id) const
IdDictFieldImplementation m_phi_impl
size_t m_GROUP_INDEX
IdDictFieldImplementation m_tec_impl
int get_expanded_id(const Identifier &id, ExpandedIdentifier &exp_id, const IdContext *context) const
Create expanded id from compact id (return == 0 for OK)
size_type m_PHI_INDEX
virtual int get_id(const IdentifierHash &hash_id, Identifier &id, const IdContext *context=0) const override
Create compact id from hash id (return == 0 for OK)
size_type m_CHANNEL_INDEX
int technologyIndex(const std::string &name) const
IdDictFieldImplementation m_sta_impl
MultiRange m_full_module_range
bool is_stgc(const Identifier &id) const
IdDictFieldImplementation m_eta_impl
size_type module_hash_max() const
the maximum hash value
MultiRange m_full_detectorElement_range
size_type m_ETA_INDEX
const IdDictDictionary * m_dict
IdContext technology_context() const
access to IdContext's which define which levels or fields are contained in the Muon id
int stationPhi(const Identifier &id) const
size_type m_DETECTORELEMENT_INDEX
int stationName(const Identifier &id) const
int initLevelsFromDict()
id_vec m_detectorElement_vec
virtual int init_detectorElement_hashes()
size_type detectorElement_hash_max() const
IdDictFieldImplementation m_muon_impl
void resetAndSet(const IdDictFieldImplementation &dict, const int new_val, Identifier &id) const
bool validStation(int stationName, int technology) const
MultiRange m_full_channel_range
IdContext channel_context() const
id for channel
const std::string & stationNameString(const int &index) const
MuonIdHelper(const std::string &logName, const std::string &group)
id_vec m_module_vec
size_type m_TECHNOLOGY_INDEX
A Range describes the possible ranges for the field values of an ExpandedIdentifier.
static int padPhiMax()
int padPhi(const Identifier &id) const
static int padEtaMax()
static constexpr unsigned int s_etaDim
-3, -2, -1, 1, 2, 3
std::array< unsigned int, s_modHashDim > m_module_hashes
IdDictFieldImplementation m_cha_impl
void idChannels(const Identifier &id, std::vector< Identifier > &vect) const
int multilayer(const Identifier &id) const
bool valid(const Identifier &id) const
virtual int get_detectorElement_hash(const Identifier &id, IdentifierHash &hash_id) const override
static int channelMin()
static int gasGapMin()
static constexpr unsigned int s_mlDim
2 multilayer
bool SmallSector(int stationName) const
unsigned int m_stationShift
Minimal station index found.
static int stationPhiMax()
static int padPhiMin()
IdDictFieldImplementation m_gap_impl
int stgcTechnology() const
Utility methods.
virtual int get_module_hash(const Identifier &id, IdentifierHash &hash_id) const override
Identifier hvID(int stationName, int stationEta, int stationPhi, int multilayer, int gasGap, bool isInnerQ1) const
int channelType(const Identifier &id) const
static int channelMax()
unsigned int detEleHashIdx(const Identifier &id) const
Identifier elementID(int stationName, int stationEta, int stationPhi) const
int padEta(const Identifier &id) const
int init_id_to_hashes()
Identifier parentID(const Identifier &id) const
static int multilayerMax()
static int gasGapMax()
size_type m_CHANNELTYPE_INDEX
Identifier febID(int stationName, int stationEta, int stationPhi, int multilayer, int gasGap, int channelType) const
virtual int initialize_from_dictionary(const IdDictMgr &dict_mgr) override
Initialization from the identifier dictionary.
static int padEtaMin()
static int stationPhiMin()
int channel(const Identifier &id) const override
static int stationEtaMin()
static int multilayerMin()
bool measuresPhi(const Identifier &id) const override
returns measuresPhi
Identifier padID(int stationName, int stationEta, int stationPhi, int multilayer, int gasGap, int channelType, int padEta, int padPhi) const
bool validChannel(const Identifier &id, int stationName, int stationEta, int stationPhi, int multilayer, int gasGap, int channelType, int channel) const
IdDictFieldImplementation m_mplet_impl
static int stationEtaMax()
bool LargeSector(int stationName) const
int gasGap(const Identifier &id) const override
get the hashes
static constexpr unsigned int s_phiDim
8 phi station
Identifier channelID(int stationName, int stationEta, int stationPhi, int multilayer, int gasGap, int channelType, int channel) const
unsigned int moduleHashIdx(const Identifier &id) const
bool validElement(const Identifier &id) const
Identifier multilayerID(const Identifier &channeldID) const
static int channelTypeMax()
int numberOfMultilayers(const Identifier &id) const
IdDictFieldImplementation m_typ_impl
std::array< unsigned int, s_detHashDim > m_detectorElement_hashes
size_type m_GASGAP_INDEX
bool isStNameInTech(const std::string &stationName) const override
The valid element checks converted the identifier to a stationName string in order to assess whether ...
static int channelTypeMin()
struct color C
Definition index.py:1