ATLAS Offline Software
Loading...
Searching...
No Matches
RpcIdHelper.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
13RpcIdHelper::RpcIdHelper() : MuonIdHelper("RpcIdHelper", "rpc") {}
14
15// Initialize dictionary
17 int status = 0;
18
19 // Check whether this helper should be reinitialized
20 if (!reinitialize(dict_mgr)) {
21 ATH_MSG_INFO("Request to reinitialize not satisfied - tags have not changed");
22 return (0);
23 } else {
24 ATH_MSG_DEBUG("(Re)initialize");
25 }
26
27 // init base object
28 if (AtlasDetectorID::initialize_from_dictionary(dict_mgr)) return 1;
29
30 // Register version of the MuonSpectrometer dictionary
31 if (register_dict_tag(dict_mgr, "MuonSpectrometer")) return 1;
32
33 m_dict = dict_mgr.find_dictionary("MuonSpectrometer");
34 if (!m_dict) {
35 ATH_MSG_ERROR(" initialize_from_dict - cannot access MuonSpectrometer dictionary ");
36 return 1;
37 }
38
39 // Initialize some of the field indices
40 if (initLevelsFromDict()) return 1;
41
42 const IdDictField* field = m_dict->find_field("doubletR");
43 if (field) {
44 m_DOUBLETR_INDEX = field->index();
45 } else {
46 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'doubletR' field ");
47 status = 1;
48 }
49
50 field = m_dict->find_field("doubletZ");
51 if (field) {
52 m_DOUBLETZ_INDEX = field->index();
53 } else {
54 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'doubletZ' field ");
55 status = 1;
56 }
57
58 field = m_dict->find_field("doubletPhi");
59 if (field) {
60 m_DOUBLETPHI_INDEX = field->index();
61 } else {
62 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'doubletPhi' field ");
63 status = 1;
64 }
65
66 field = m_dict->find_field("rpcGasGap");
67 if (field) {
68 m_GASGAP_INDEX = field->index();
69 } else {
70 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'rpcGasGap' field ");
71 status = 1;
72 }
73
74 field = m_dict->find_field("rpcMeasuresPhi");
75 if (field) {
76 m_MEASURESPHI_INDEX = field->index();
77 } else {
78 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'rpcMeasuresPhi' field ");
79 status = 1;
80 }
81
82 field = m_dict->find_field("rpcStrip");
83 if (field) {
84 m_CHANNEL_INDEX = field->index();
85 } else {
86 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'rpcStrip' field ");
87 status = 1;
88 }
89
90 // reinitialze the module context
93
94 // save an index to the first region of rpc
95 const IdDictGroup* rpcGroup = m_dict->find_group("rpc");
96 if (!rpcGroup) {
97 ATH_MSG_ERROR("Cannot find rpc group");
98 } else {
99 m_GROUP_INDEX = rpcGroup->region(0).index();
100 }
101
102 const IdDictRegion& region = m_dict->region(m_GROUP_INDEX);
112
113 ATH_MSG_DEBUG(" RPC decode index and bit fields for each level: " << std::endl
114 << " muon " << m_muon_impl.show_to_string() << std::endl
115 << " station " << m_sta_impl.show_to_string() << std::endl
116 << " eta " << m_eta_impl.show_to_string() << std::endl
117 << " phi " << m_phi_impl.show_to_string() << std::endl
118 << " technology " << m_tec_impl.show_to_string() << std::endl
119 << " TR " << m_dbr_impl.show_to_string() << std::endl
120 << " TZ " << m_dbz_impl.show_to_string() << std::endl
121 << " TPHI " << m_dbp_impl.show_to_string() << std::endl
122 << " gas gap " << m_gap_impl.show_to_string() << std::endl
123 << " phi " << m_mea_impl.show_to_string() << std::endl
124 << " strip " << m_str_impl.show_to_string());
125
126 //
127 // Build multirange for the valid set of identifiers
128 //
129
130 // Find value for the field MuonSpectrometer
131 int muonField = -1;
132 const IdDictDictionary* atlasDict = dict_mgr.find_dictionary("ATLAS");
133 if (atlasDict->get_label_value("subdet", "MuonSpectrometer", muonField)) {
134 ATH_MSG_ERROR("Could not get value for label 'MuonSpectrometer' of field 'subdet' in dictionary " << atlasDict->name());
135 return 1;
136 }
137
138 // Build MultiRange down to "doubletR" for all (muon) regions
139 ExpandedIdentifier region_id;
140 region_id.add(muonField);
141 Range prefix;
142 MultiRange muon_range = m_dict->build_multirange(region_id, prefix, "doubletR");
143
144 if (muon_range.size() > 0) {
145 ATH_MSG_INFO("MultiRange built successfully to doubletR: "
146 << "MultiRange size is " << muon_range.size());
147 } else {
148 ATH_MSG_ERROR("Muon MultiRange is empty");
149 }
150
151 // Build MultiRange down to "detectorElement" for all mdt regions
152
153 ExpandedIdentifier detectorElement_region;
154 detectorElement_region.add(muonField);
155 Range detectorElement_prefix;
156 MultiRange muon_detectorElement_range = m_dict->build_multirange(detectorElement_region, detectorElement_prefix, "doubletPhi");
157 if (muon_detectorElement_range.size() > 0) {
158 ATH_MSG_INFO("MultiRange built successfully to detectorElement: "
159 << "DetectorElement MultiRange size is " << muon_detectorElement_range.size());
160 } else {
161 ATH_MSG_ERROR("Muon RPC ReadoutElement MultiRange is empty");
162 return 1;
163 }
164
165 // Build MultiRange down to "rpcStrip" for all rpc regions
166 ExpandedIdentifier rpc_region;
167 rpc_region.add(muonField);
168 Range rpc_prefix;
169 MultiRange muon_channel_range = m_dict->build_multirange(rpc_region, rpc_prefix, "rpcStrip");
170
171 if (muon_channel_range.size() > 0) {
172 ATH_MSG_INFO("MultiRange built successfully to rpcStrip: "
173 << "MultiRange size is " << muon_channel_range.size());
174 } else {
175 ATH_MSG_ERROR("Muon RPC channel MultiRange is empty");
176 return 1;
177 }
178
179 // build RPC module ranges
180 // Find the regions that have a "RPC doubletR field" and save them
181 int rpcField = -1;
182 status = m_dict->get_label_value("technology", "RPC", rpcField);
183
184 for (int i = 0; i < (int)muon_range.size(); ++i) {
185 const Range& range = muon_range[i];
186 if (range.fields() > m_TECHNOLOGY_INDEX) {
187 const Range::field& field = range[m_TECHNOLOGY_INDEX];
188 if (field.match((ExpandedIdentifier::element_type)rpcField)) {
189 m_full_module_range.add(range);
190 ATH_MSG_DEBUG("field size is " << (int)range.cardinality() << " field index = " << i);
191 }
192 }
193 }
194
195 for (int j = 0; j < (int)muon_detectorElement_range.size(); ++j) {
196 const Range& range = muon_detectorElement_range[j];
197 if (range.fields() > m_TECHNOLOGY_INDEX) {
198 const Range::field& field = range[m_TECHNOLOGY_INDEX];
199 if (field.match((ExpandedIdentifier::element_type)rpcField)) {
201 ATH_MSG_DEBUG("detectorElement field size is " << (int)range.cardinality() << " field index = " << j);
202 }
203 }
204 }
205
206 for (int j = 0; j < (int)muon_channel_range.size(); ++j) {
207 const Range& range = muon_channel_range[j];
208 if (range.fields() > m_TECHNOLOGY_INDEX) {
209 const Range::field& field = range[m_TECHNOLOGY_INDEX];
210 if (field.match((ExpandedIdentifier::element_type)rpcField)) {
211 m_full_channel_range.add(range);
212 ATH_MSG_DEBUG("channel field size is " << (int)range.cardinality() << " field index = " << j);
213 }
214 }
215 }
216
217 // test to see that the multi range is not empty
218 if (m_full_module_range.size() == 0) {
219 ATH_MSG_ERROR("RPC MultiRange ID is empty for modules");
220 status = 1;
221 } else {
222 ATH_MSG_DEBUG(" full module range size is " << m_full_module_range.size());
223 }
224
226 if (m_full_detectorElement_range.size() == 0) {
227 ATH_MSG_ERROR("MDT MultiRange ID is empty for detector elements");
228 status = 1;
229 }
230
231 // test to see that the multi range is not empty
232 if (m_full_channel_range.size() == 0) {
233 ATH_MSG_ERROR("RPC MultiRange ID is empty for channels");
234 status = 1;
235 } else {
236 ATH_MSG_DEBUG(" full channel range size is " << m_full_channel_range.size());
237 }
238
239 // Setup the hash tables for RPC
240 ATH_MSG_INFO("Initializing RPC hash indices ... ");
241 status = init_hashes();
242 status = init_detectorElement_hashes(); // doubletZ
243 status = init_id_to_hashes();
244
245 // Setup hash tables for finding neighbors
246 ATH_MSG_INFO("Initializing RPC hash indices for finding neighbors ... ");
247 status = init_neighbors();
248
249 // retrieve the maximum number of gas gaps
250 ExpandedIdentifier expId;
251 IdContext gasGap_context(expId, 0, m_GASGAP_INDEX);
252 for (const auto& id : m_detectorElement_vec) { // channel Identifiers not filled for RPCs, thus using detector element ones
253 if (!get_expanded_id(id, expId, &gasGap_context)) {
254 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
255 const Range& range = m_full_channel_range[i];
256 if (range.match(expId)) {
257 const Range::field& gap_field = range[m_GASGAP_INDEX];
258 if (not gap_field.empty()) {
259 unsigned int max = (gap_field.get_maximum());
260 if (m_gasGapMax == UINT_MAX)
262 else if (max > m_gasGapMax)
264 }
265 }
266 }
267 }
268 }
269 if (m_gasGapMax == UINT_MAX) {
270 ATH_MSG_ERROR("No maximum number of RPC gas gaps was retrieved");
271 status = 1;
272 } else {
273 ATH_MSG_DEBUG(" Maximum number of RPC gas gaps is " << m_gasGapMax);
274 }
275 m_init = true;
276 return (status);
277}
278
280 unsigned int hash_max = module_hash_max();
281 for (unsigned int i = 0; i < hash_max; ++i) {
282 const Identifier& id = m_module_vec[i];
283 m_module_hashes[id] = i;
284 }
285
286 hash_max = detectorElement_hash_max();
287 for (unsigned int i = 0; i < hash_max; ++i) {
288 const Identifier& id = m_detectorElement_vec[i];
290 }
291 return 0;
292}
293
295 const auto itr = m_module_hashes.find(parentID(id));
296 if (itr == m_module_hashes.end()) {
297 hash_id = IdentifierHash(-1);
298 return 1;
299 }
300 hash_id = itr->second;
301 return 0;
302}
303
305 Identifier detElId = id;
306 // Certain chambers require doublet Phi in hashing (See isExtraDetElId()) - do not reset m_dpb_impl in these cases
307 if (!isExtraDetElId(id)) {
308 m_dbp_impl.reset(detElId);
309 }
310 m_gap_impl.reset(detElId);
311 m_mea_impl.reset(detElId);
312 m_str_impl.reset(detElId);
313 auto itr = m_detectorElement_hashes.find(detElId);
314 if (itr == m_detectorElement_hashes.end()) {
315 ATH_MSG_VERBOSE("Cannot find a valid detector element hash for "<<print_to_string(id));
316 hash_id = IdentifierHash(-1);
317 return 1;
318 }
319 hash_id = itr->second;
320 return 0;
321}
322
323void RpcIdHelper::idChannels(const Identifier& id, std::vector<Identifier>& vect) const {
324 vect.clear();
325 Identifier parent = parentID(id);
326 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
327 const Range& range = m_full_channel_range[i];
328 ConstRangeIterator rit(range);
329 for (const auto & expId:rit) {
330 Identifier child;
331 get_id(expId, child);
332 if (parentID(child) == parent) vect.push_back(child);
333 }
334 }
335}
336
337// Access to min and max of level ranges
338
340 ExpandedIdentifier expId;
341 IdContext eta_context(expId, 0, m_ETA_INDEX);
342 if (!get_expanded_id(id, expId, &eta_context)) {
343 int result = 999;
344 for (const Range& range : m_full_module_range) {
345 if (range.match(expId)) {
346 const Range::field& eta_field = range[m_ETA_INDEX];
347 if (not eta_field.empty()) {
348 result = std::min(eta_field.get_minimum(), result);
349 }
350 }
351 }
352 return (result);
353 }
354 return 999; // default
355}
356
358 ExpandedIdentifier expId;
359 IdContext eta_context(expId, 0, m_ETA_INDEX);
360 if (!get_expanded_id(id, expId, &eta_context)) {
361 int result = -999;
362 for (const Range& range : m_full_module_range) {
363 if (range.match(expId)) {
364 const Range::field& eta_field = range[m_ETA_INDEX];
365 if (not eta_field.empty()) {
366 result = std::max(result, eta_field.get_maximum());
367 }
368 }
369 }
370 return (result);
371 }
372 return -999;
373}
374
376 ExpandedIdentifier expId;
377 IdContext phi_context(expId, 0, m_PHI_INDEX);
378 if (!get_expanded_id(id, expId, &phi_context)) {
379 for (unsigned int i = 0; i < m_full_module_range.size(); ++i) {
380 const Range& range = m_full_module_range[i];
381 if (range.match(expId)) {
382 const Range::field& phi_field = range[m_PHI_INDEX];
383 if (not phi_field.empty()) { return (phi_field.get_minimum()); }
384 }
385 }
386 }
387 // Failed to find the min
388 return 999;
389}
390
392 ExpandedIdentifier expId;
393 IdContext phi_context(expId, 0, m_PHI_INDEX);
394 if (!get_expanded_id(id, expId, &phi_context)) {
395 for (unsigned int i = 0; i < m_full_module_range.size(); ++i) {
396 const Range& range = m_full_module_range[i];
397 if (range.match(expId)) {
398 const Range::field& phi_field = range[m_PHI_INDEX];
399 if (not phi_field.empty()) { return (phi_field.get_maximum()); }
400 }
401 }
402 }
403 // Failed to find the max
404 return -999;
405}
406
408 ExpandedIdentifier expId;
409 IdContext doubletR_context(expId, 0, m_DOUBLETR_INDEX);
410 if (!get_expanded_id(id, expId, &doubletR_context)) {
411 for (unsigned int i = 0; i < m_full_module_range.size(); ++i) {
412 const Range& range = m_full_module_range[i];
413 if (range.match(expId)) {
414 const Range::field& r_field = range[m_DOUBLETR_INDEX];
415 if (not r_field.empty()) { return (r_field.get_minimum()); }
416 }
417 }
418 }
419 // Failed to find the min
420 return 999;
421}
422
424 ExpandedIdentifier expId;
425 IdContext doubletR_context(expId, 0, m_DOUBLETR_INDEX);
426 if (!get_expanded_id(id, expId, &doubletR_context)) {
427 for (unsigned int i = 0; i < m_full_module_range.size(); ++i) {
428 const Range& range = m_full_module_range[i];
429 if (range.match(expId)) {
430 const Range::field& r_field = range[m_DOUBLETR_INDEX];
431 if (not r_field.empty()) { return (r_field.get_maximum()); }
432 }
433 }
434 }
435 // Failed to find the max
436 return -999;
437}
438
440 ExpandedIdentifier expId;
441 IdContext doubletZ_context(expId, 0, m_DOUBLETZ_INDEX);
442 if (!get_expanded_id(id, expId, &doubletZ_context)) {
443 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
444 const Range& range = m_full_channel_range[i];
445 if (range.match(expId)) {
446 const Range::field& z_field = range[m_DOUBLETZ_INDEX];
447 if (not z_field.empty()) { return (z_field.get_minimum()); }
448 }
449 }
450 }
451 // Failed to find the min
452 return 999;
453}
454
456 ExpandedIdentifier expId;
457 IdContext doubletZ_context(expId, 0, m_DOUBLETZ_INDEX);
458 if (!get_expanded_id(id, expId, &doubletZ_context)) {
459 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
460 const Range& range = m_full_channel_range[i];
461 if (range.match(expId)) {
462 const Range::field& z_field = range[m_DOUBLETZ_INDEX];
463 if (not z_field.empty()) { return (z_field.get_maximum()); }
464 }
465 }
466 }
467 // Failed to find the max
468 return -999;
469}
470
472 ExpandedIdentifier expId;
473 IdContext doubletPhi_context(expId, 0, m_DOUBLETPHI_INDEX);
474 if (!get_expanded_id(id, expId, &doubletPhi_context)) {
475 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
476 const Range& range = m_full_channel_range[i];
477 if (range.match(expId)) {
478 const Range::field& dphi_field = range[m_DOUBLETPHI_INDEX];
479 if (not dphi_field.empty()) { return (dphi_field.get_minimum()); }
480 }
481 }
482 }
483 // Failed to find the min
484 return 999;
485}
486
488 ExpandedIdentifier expId;
489 IdContext doubletPhi_context(expId, 0, m_DOUBLETPHI_INDEX);
490 if (!get_expanded_id(id, expId, &doubletPhi_context)) {
491 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
492 const Range& range = m_full_channel_range[i];
493 if (range.match(expId)) {
494 const Range::field& dphi_field = range[m_DOUBLETPHI_INDEX];
495 if (not dphi_field.empty()) { return (dphi_field.get_maximum()); }
496 }
497 }
498 }
499 // Failed to find the max
500 return -999;
501}
502
503int RpcIdHelper::gasGapMin(const Identifier& id) const {
504 ExpandedIdentifier expId;
505 IdContext gasGap_context(expId, 0, m_GASGAP_INDEX);
506 if (!get_expanded_id(id, expId, &gasGap_context)) {
507 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
508 const Range& range = m_full_channel_range[i];
509 if (range.match(expId)) {
510 const Range::field& gas_field = range[m_GASGAP_INDEX];
511 if (not gas_field.empty()) { return (gas_field.get_minimum()); }
512 }
513 }
514 }
515 // Failed to find the min
516 return 999;
517}
518
519int RpcIdHelper::gasGapMax(const Identifier& id) const {
520 ExpandedIdentifier expId;
521 IdContext gasGap_context(expId, 0, m_GASGAP_INDEX);
522 if (!get_expanded_id(id, expId, &gasGap_context)) {
523 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
524 const Range& range = m_full_channel_range[i];
525 if (range.match(expId)) {
526 const Range::field& gap_field = range[m_GASGAP_INDEX];
527 if (not gap_field.empty()) { return (gap_field.get_maximum()); }
528 }
529 }
530 }
531 // Failed to find the max
532 return -999;
533}
534
536 ExpandedIdentifier expId;
537 IdContext measuresPhi_context(expId, 0, m_MEASURESPHI_INDEX);
538 if (!get_expanded_id(id, expId, &measuresPhi_context)) {
539 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
540 const Range& range = m_full_channel_range[i];
541 if (range.match(expId)) {
542 const Range::field& mphi_field = range[m_MEASURESPHI_INDEX];
543 if (not mphi_field.empty()) { return (mphi_field.get_minimum()); }
544 }
545 }
546 }
547 // Failed to find the min
548 return 999;
549}
550
552 ExpandedIdentifier expId;
553 IdContext measuresPhi_context(expId, 0, m_MEASURESPHI_INDEX);
554 if (!get_expanded_id(id, expId, &measuresPhi_context)) {
555 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
556 const Range& range = m_full_channel_range[i];
557 if (range.match(expId)) {
558 const Range::field& mphi_field = range[m_MEASURESPHI_INDEX];
559 if (not mphi_field.empty()) { return (mphi_field.get_maximum()); }
560 }
561 }
562 }
563 // Failed to find the max
564 return -999;
565}
566
567int RpcIdHelper::stripMin(const Identifier& id) const {
568 ExpandedIdentifier expId;
569 IdContext strip_context(expId, 0, m_CHANNEL_INDEX);
570 if (!get_expanded_id(id, expId, &strip_context)) {
571 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
572 const Range& range = m_full_channel_range[i];
573 if (range.match(expId)) {
574 const Range::field& strip_field = range[m_CHANNEL_INDEX];
575 if (not strip_field.empty()) { return (strip_field.get_minimum()); }
576 }
577 }
578 }
579 // Failed to find the min
580 return 999;
581}
582
583int RpcIdHelper::stripMax(const Identifier& id) const {
584 ExpandedIdentifier expId;
585 IdContext strip_context(expId, 0, m_CHANNEL_INDEX);
586 if (!get_expanded_id(id, expId, &strip_context)) {
587 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
588 const Range& range = m_full_channel_range[i];
589 if (range.match(expId)) {
590 const Range::field& strip_field = range[m_CHANNEL_INDEX];
591 if (not strip_field.empty()) { return (strip_field.get_maximum()); }
592 }
593 }
594 }
595 // Failed to find the max
596 return -999;
597}
598
599// Public validation of levels
600
601bool RpcIdHelper::valid(const Identifier& id) const {
602 if (!validElement(id)) return false;
603
604 int dbz = doubletZ(id);
605 if ((dbz < doubletZMin(id)) || (dbz > doubletZMax(id))) {
606 ATH_MSG_DEBUG("Invalid doubletZ=" << dbz << " doubletZMin=" << doubletZMin(id) << " doubletZMax=" << doubletZMax(id));
607 return false;
608 }
609
610 int dbp = doubletPhi(id);
611 if ((dbp < doubletPhiMin(id)) || (dbp > doubletPhiMax(id))) {
612 ATH_MSG_DEBUG("Invalid doubletPhi=" << dbp << " doubletPhiMin=" << doubletPhiMin(id) << " doubletPhiMax=" << doubletPhiMax(id));
613 return false;
614 }
615
616 int gasG = gasGap(id);
617 if ((gasG < gasGapMin(id)) || (gasG > gasGapMax(id))) {
618 ATH_MSG_DEBUG("Invalid gasGap=" << gasG << " gasGapMin=" << gasGapMin(id) << " gasGapMax=" << gasGapMax(id));
619 return false;
620 }
621
622 int mPhi = measuresPhi(id);
623 if ((mPhi < measuresPhiMin(id)) || (mPhi > measuresPhiMax(id))) {
624 ATH_MSG_DEBUG("Invalid measuresPhi=" << mPhi << " measuresPhiMin=" << measuresPhiMin(id)
625 << " measuresPhiMax=" << measuresPhiMax(id));
626 return false;
627 }
628
629 int str = strip(id);
630 if ((str < stripMin(id)) || (str > stripMax(id))) {
631 ATH_MSG_DEBUG("Invalid strip=" << str << " stripMin=" << stripMin(id) << " stripMax=" << stripMax(id));
632 return false;
633 }
634 return true;
635}
636bool RpcIdHelper::isStNameInTech(const std::string& stationName) const { return stationName[0] == 'B'; }
638 int station = stationName(id);
639 if (!validStation(station)) {
640 ATH_MSG_DEBUG("Invalid stationName=" << stationNameString(station));
641 return false;
642 }
643
644 int eta = stationEta(id);
645 if (eta < stationEtaMin(id) || eta > stationEtaMax(id)) {
646 ATH_MSG_DEBUG("Invalid stationEta=" << eta << " for stationName=" << stationNameString(station)
647 << " stationEtaMin=" << stationEtaMin(id) << " stationEtaMax=" << stationEtaMax(id));
648 return false;
649 }
650
651 int phi = stationPhi(id);
652 if ((phi < stationPhiMin(id)) || (phi > stationPhiMax(id))) {
653 ATH_MSG_DEBUG("Invalid stationPhi=" << phi << " for stationName=" << stationNameString(station)
654 << " stationPhiMin=" << stationPhiMin(id) << " stationPhiMax=" << stationPhiMax(id));
655 return false;
656 }
657
658 int dbr = doubletR(id);
659 if ((dbr < doubletRMin(id)) || (dbr > doubletRMax(id))) {
660 ATH_MSG_DEBUG("Invalid doubletR=" << dbr << " for stationName=" << stationNameString(station) << " doubletRMin=" << doubletRMin(id)
661 << " doubletRMax=" << doubletRMax(id));
662 return false;
663 }
664 return true;
665}
666
667bool RpcIdHelper::validPad(const Identifier& id) const {
668 if (!validElement(id)) return false;
669
670 int dbz = doubletZ(id);
671 if ((dbz < doubletZMin(id)) || (dbz > doubletZMax(id))) {
672 ATH_MSG_DEBUG("Invalid doubletZ=" << dbz << " doubletZMin=" << doubletZMin(id) << " doubletZMax=" << doubletZMax(id));
673 return false;
674 }
675
676 int dbp = doubletPhi(id);
677 if ((dbp < doubletPhiMin(id)) || (dbp > doubletPhiMax(id))) {
678 ATH_MSG_DEBUG("Invalid doubletPhi=" << dbp << " doubletPhiMin=" << doubletPhiMin(id) << " doubletPhiMax=" << doubletPhiMax(id));
679 return false;
680 }
681 return true;
682}
683
684// Private validation of levels
685
688 ATH_MSG_VERBOSE("Invalid stationName=" << stationNameString(stationName));
689 return false;
690 }
692 ATH_MSG_VERBOSE("Invalid stationEta=" << stationEta << " for stationName=" << stationNameString(stationName)
693 << " stationEtaMin=" << stationEtaMin(id) << " stationEtaMax=" << stationEtaMax(id));
694 return false;
695 }
696 if ((stationPhi < stationPhiMin(id)) || (stationPhi > stationPhiMax(id))) {
697 ATH_MSG_VERBOSE("Invalid stationPhi=" << stationPhi << " for stationName=" << stationNameString(stationName)
698 << " stationPhiMin=" << stationPhiMin(id) << " stationPhiMax=" << stationPhiMax(id));
699 return false;
700 }
701 if ((doubletR < doubletRMin(id)) || (doubletR > doubletRMax(id))) {
702 ATH_MSG_VERBOSE("Invalid doubletR=" << doubletR << " for stationName=" << stationNameString(stationName)
703 << " doubletRMin=" << doubletRMin(id) << " doubletRMax=" << doubletRMax(id));
704 return false;
705 }
706 return true;
707}
708
709// Check values down to detector element level
710
712 int doubletPhi, int gasGap, int measuresPhi, int strip) const {
713 if (!validElement(id, stationName, stationEta, stationPhi, doubletR)) return false;
714
715 if ((doubletZ < doubletZMin(id)) || (doubletZ > doubletZMax(id))) {
716 ATH_MSG_VERBOSE("Invalid doubletZ=" << doubletZ << " doubletZMin=" << doubletZMin(id) << " doubletZMax=" << doubletZMax(id));
717 return false;
718 }
719 if ((doubletPhi < doubletPhiMin(id)) || (doubletPhi > doubletPhiMax(id))) {
720 ATH_MSG_VERBOSE("Invalid doubletPhi=" << doubletPhi << " doubletPhiMin=" << doubletPhiMin(id)
721 << " doubletPhiMax=" << doubletPhiMax(id));
722 return false;
723 }
724 if ((gasGap < gasGapMin(id)) || (gasGap > gasGapMax(id))) {
725 ATH_MSG_VERBOSE("Invalid gasGap=" << gasGap << " gasGapMin=" << gasGapMin(id) << " gasGapMax=" << gasGapMax(id));
726 return false;
727 }
728 if ((measuresPhi < measuresPhiMin(id)) || (measuresPhi > measuresPhiMax(id))) {
729 ATH_MSG_VERBOSE("Invalid measuresPhi=" << measuresPhi << " measuresPhiMin=" << measuresPhiMin(id)
730 << " measuresPhiMax=" << measuresPhiMax(id));
731 return false;
732 }
733 if ((strip < stripMin(id)) || (strip > stripMax(id))) {
734 ATH_MSG_VERBOSE("Invalid strip=" << strip << " stripMin=" << stripMin(id) << " stripMax=" << stripMax(id));
735 return false;
736 }
737 return true;
738}
739
740// Check values down to the pad
741
743 int doubletPhi) const {
744 if (!validElement(id, stationName, stationEta, stationPhi, doubletR)) return false;
745
746 if ((doubletZ < doubletZMin(id)) || (doubletZ > doubletZMax(id))) {
747 ATH_MSG_DEBUG("Invalid doubletZ=" << doubletZ << " doubletZMin=" << doubletZMin(id) << " doubletZMax=" << doubletZMax(id));
748 return false;
749 }
750 if ((doubletPhi < doubletPhiMin(id)) || (doubletPhi > doubletPhiMax(id))) {
751 ATH_MSG_DEBUG("Invalid doubletPhi=" << doubletPhi << " doubletPhiMin=" << doubletPhiMin(id)
752 << " doubletPhiMax=" << doubletPhiMax(id));
753 return false;
754 }
755 return true;
756}
757
759 //
760 // create a vector(s) to retrieve the hashes for compact ids. For
761 // the moment, we implement a hash for detector channels
762 //
763 m_st_BMS = stationNameIndex("BMS");
764 m_st_BIL = stationNameIndex("BIL");
765
766 // detector element hash
768 unsigned int nids = 0;
769 std::set<Identifier> ids;
770 for (unsigned int i = 0; i < m_full_detectorElement_range.size(); ++i) {
771 const Range& range = m_full_detectorElement_range[i];
772 ConstRangeIterator rit(range);
773 for (const auto & expId:rit) {
774 Identifier id;
775 get_id(expId, id);
776 Identifier doubletZ_id = doubletZID(id);
777 if (!isExtraDetElId(id)) {
778 if (!ids.insert(doubletZ_id).second)
779 ATH_MSG_DEBUG("init_detectorElement_hashes "
780 << "Please check the dictionary for possible duplication for " << id);
781 } else if (!ids.insert(id).second) {
782 ATH_MSG_ERROR("init_detectorElement_hashes "
783 << " Error: duplicated id for detector element id. nid " << (int)nids
784 << " doubletPhi ID " << id);
785 return 1;
786
787 }
788 nids++;
789 }
790 }
791 m_detectorElement_hash_max = ids.size();
792 ATH_MSG_INFO("The detector element hash max is " << (int)m_detectorElement_hash_max);
793
794 m_detectorElement_vec.insert(m_detectorElement_vec.end(), ids.begin(), ids.end());
795 return 0;
796}
797
799 // pack fields independently
800 Identifier result((Identifier::value_type)0);
807 return result;
808}
809
811 try {
814 return result;
815 } catch (const std::out_of_range&) { isValid = false; }
816 return Identifier{0};
817}
818
819Identifier RpcIdHelper::elementID(const std::string& stationNameStr, int stationEta, int stationPhi, int doubletR) const {
820 return elementID(stationNameIndex(stationNameStr), stationEta, stationPhi, doubletR);
821}
822Identifier RpcIdHelper::elementID(const std::string& stationNameStr, int stationEta, int stationPhi, int doubletR, bool& isValid) const {
824}
825
831
833 try {
834 const Identifier result = elementID(id, doubletR);
836 return result;
837 } catch (const std::out_of_range&) { isValid = false; }
838 return Identifier{0};
839}
840Identifier RpcIdHelper::elementID(const Identifier& id) const { return parentID(id); }
841
842
844 int measuresPhi) const {
845 // pack fields independently
846 Identifier result((Identifier::value_type)0);
855 m_gap_impl.pack(gasGap, result);
857 return result;
858}
860 int measuresPhi, bool& isValid) const {
861 try {
864 return result;
865 } catch (const std::out_of_range&) { isValid = false; }
866 return Identifier{0};
867}
868
874
882 try {
885 return result;
886 } catch (const std::out_of_range&) { isValid = false; }
887 return Identifier{0};
888}
889
891 int gasGap) const {
892 // pack fields independently
893 Identifier result((Identifier::value_type)0);
902 m_gap_impl.pack(gasGap, result);
903
904 return result;
905}
907 bool& isValid) const {
908 try {
911 return result;
912 } catch (const std::out_of_range&) { isValid = false; }
913 return Identifier{0};
914}
915
921
928 try {
931 return result;
932 } catch (const std::out_of_range&) { isValid = false; }
933 return Identifier{0};
934}
935
937 int measuresPhi, int strip) const {
938 // pack fields independently
939 Identifier result((Identifier::value_type)0);
948 m_gap_impl.pack(gasGap, result);
950 m_str_impl.pack(strip, result);
951 return result;
952}
954 int measuresPhi, int strip, bool& isValid) const {
955 try {
956 const Identifier result =
959 return result;
960 } catch (const std::out_of_range&) { isValid = false; }
961 return Identifier{0};
962}
963Identifier RpcIdHelper::channelID(const std::string& stationNameStr, int stationEta, int stationPhi, int doubletR, int doubletZ,
964 int doubletPhi, int gasGap, int measuresPhi, int strip) const {
966}
967Identifier RpcIdHelper::channelID(const std::string& stationNameStr, int stationEta, int stationPhi, int doubletR, int doubletZ,
968 int doubletPhi, int gasGap, int measuresPhi, int strip, bool& isValid) const {
970 isValid);
971}
972
984 bool& isValid) const {
985 try {
988 return result;
989 } catch (const std::out_of_range&) { isValid = false; }
990 return Identifier{0};
991}
992
993// get the parent id from the strip identifier
995 assert(is_rpc(id));
996 Identifier result(id);
997 m_dbz_impl.reset(result);
998 m_dbp_impl.reset(result);
999 m_gap_impl.reset(result);
1000 m_mea_impl.reset(result);
1001 m_str_impl.reset(result);
1002 return result;
1003}
1004
1005// doubletZ Identifier
1007 assert(is_rpc(id));
1008 Identifier result(id);
1009 m_dbp_impl.reset(result);
1010 m_gap_impl.reset(result);
1011 m_mea_impl.reset(result);
1012 m_str_impl.reset(result);
1013 return result;
1014}
1015
1017 // pack fields independently
1018 Identifier result((Identifier::value_type)0);
1024 m_dbr_impl.pack(doubletR, result);
1025 m_dbz_impl.pack(doubletZ, result);
1027 return result;
1028}
1030 bool& isValid) const {
1031 try {
1034 return result;
1035 } catch (const std::out_of_range&) { isValid = false; }
1036 return Identifier{0};
1037}
1038
1040 // pack fields independently
1041 Identifier result(id);
1044 return result;
1045}
1047 try {
1050 return result;
1051 } catch (const std::out_of_range&) { isValid = false; }
1052 return Identifier{0};
1053}
1054// Access to components of the ID
1055
1056int RpcIdHelper::doubletR(const Identifier& id) const { return m_dbr_impl.unpack(id); }
1057
1058int RpcIdHelper::doubletZ(const Identifier& id) const { return m_dbz_impl.unpack(id); }
1059
1060int RpcIdHelper::doubletPhi(const Identifier& id) const { return m_dbp_impl.unpack(id); }
1061
1062int RpcIdHelper::gasGap(const Identifier& id) const { return m_gap_impl.unpack(id); }
1063
1064bool RpcIdHelper::measuresPhi(const Identifier& id) const { return m_mea_impl.unpack(id); }
1065
1066int RpcIdHelper::strip(const Identifier& id) const { return m_str_impl.unpack(id); }
1067
1068int RpcIdHelper::channel(const Identifier& id) const { return strip(id); }
1069
1070// Access to min and max of level ranges
1071
1073
1075
1077
1079
1081
1083
1085
1087
1089
1091
1093
1095
1097
1099
1101
1103
1105
1107 int rpcField = technologyIndex("RPC");
1108 if (m_dict) { rpcField = rpc_field_value(); }
1109 return rpcField;
1110}
1111
1112inline
1114 const int station = stationName(id);
1140
1141
1142 if (station == m_st_BMS) {
1143 const int eta = stationEta(id);
1144 const int dZ = doubletZ(id);
1145 if (std::abs(eta) != 4 && dZ != 3) {
1146 return false;
1147 }
1148 const int dP = doubletPhi(id);
1149 const int dR = doubletR(id);
1150 return (dZ == 3 && dP == 2) ||
1151 (std::abs(eta) == 4 && dZ !=1 && dR != 2 && dP == 2);
1152 } else if (m_st_BIL == station) {
1153 return std::abs(stationEta(id)) == 2 && doubletPhi(id) == 2;
1154 }
1155
1156 return false;
1157}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(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
#define max(a, b)
Definition cfImp.cxx:41
int muon_field_value() const
virtual int initialize_from_dictionary(const IdDictMgr &dict_mgr) override
Initialization from the identifier dictionary.
std::string print_to_string(Identifier id, const IdContext *context=0) const
or provide the printout in string form
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.
int rpc_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)
bool is_rpc(const Identifier &id) const
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
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
int stationPhi(const Identifier &id) const
size_type m_DETECTORELEMENT_INDEX
int stationName(const Identifier &id) const
int initLevelsFromDict()
IdContext detectorElement_context() const
id for detector element
id_vec m_detectorElement_vec
size_type detectorElement_hash_max() const
IdDictFieldImplementation m_muon_impl
void resetAndSet(const IdDictFieldImplementation &dict, const int new_val, Identifier &id) const
size_type m_MODULE_INDEX
bool validStation(int stationName, int technology) const
size_type m_detectorElement_hash_max
MultiRange m_full_channel_range
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.
Identifier padID(const Identifier &elementID, int doubletZ, int doubletPhi) const
Identifier channelID(int stationName, int stationEta, int stationPhi, int doubletR, int doubletZ, int doubletPhi, int gasGap, int measuresPhi, int strip) const
void idChannels(const Identifier &id, std::vector< Identifier > &vect) const
size_type m_DOUBLETPHI_INDEX
int init_id_to_hashes()
bool validPad(const Identifier &id) const
size_type m_GASGAP_INDEX
static int doubletRMin()
int gasGap(const Identifier &id) const override
get the hashes
int gasGapMax() const
static int measuresPhiMax()
IdDictFieldImplementation m_mea_impl
static int doubletZMax()
size_type m_DOUBLETZ_INDEX
Identifier panelID(const Identifier &padID, int gasGap, int measuresPhi) const
Identifier parentID(const Identifier &id) const
std::unordered_map< Identifier, unsigned int > m_detectorElement_hashes
bool validElement(const Identifier &id) const
static int gasGapMin()
IdDictFieldImplementation m_dbr_impl
bool isExtraDetElId(const Identifier &id) const
virtual int init_detectorElement_hashes() override
Identifier elementID(int stationName, int stationEta, int stationPhi, int doubletR) const
int channel(const Identifier &id) const override
IdDictFieldImplementation m_dbz_impl
Identifier gapID(const Identifier &padID, int gasGap) const
std::unordered_map< Identifier, unsigned int > m_module_hashes
unsigned int m_gasGapMax
static int doubletRMax()
static int stationPhiMin()
int doubletPhi(const Identifier &id) const
virtual int initialize_from_dictionary(const IdDictMgr &dict_mgr) override
Initialization from the identifier dictionary.
int rpcTechnology() const
Utility methods.
static int doubletPhiMax()
virtual int get_detectorElement_hash(const Identifier &id, IdentifierHash &hash_id) const override
static int stationPhiMax()
int doubletR(const Identifier &id) const
static int stripMax()
bool valid(const Identifier &id) const
int strip(const Identifier &id) const
static int doubletZMin()
bool measuresPhi(const Identifier &id) const override
static int stationEtaMin()
static int measuresPhiMin()
static int doubletPhiMin()
size_type m_DOUBLETR_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 stationEtaMax()
virtual int get_module_hash(const Identifier &id, IdentifierHash &hash_id) const override
Identifier doubletZID(const Identifier &id) const
int doubletZ(const Identifier &id) const
size_type m_MEASURESPHI_INDEX
bool validChannel(const Identifier &id, int stationName, int stationEta, int stationPhi, int doubletR, int doubletZ, int doubletPhi, int gasGap, int measuresPhi, int strip) const
IdDictFieldImplementation m_gap_impl
static int stripMin()
IdDictFieldImplementation m_dbp_impl
IdDictFieldImplementation m_str_impl