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 return 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 return 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 return 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 return 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 return 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 return 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 return 1;
99 } else {
100 m_GROUP_INDEX = rpcGroup->region(0).index();
101 }
102
103 const IdDictRegion& region = m_dict->region(m_GROUP_INDEX);
113
114 ATH_MSG_DEBUG(" RPC decode index and bit fields for each level: " << std::endl
115 << " muon " << m_muon_impl.show_to_string() << std::endl
116 << " station " << m_sta_impl.show_to_string() << std::endl
117 << " eta " << m_eta_impl.show_to_string() << std::endl
118 << " phi " << m_phi_impl.show_to_string() << std::endl
119 << " technology " << m_tec_impl.show_to_string() << std::endl
120 << " TR " << m_dbr_impl.show_to_string() << std::endl
121 << " TZ " << m_dbz_impl.show_to_string() << std::endl
122 << " TPHI " << m_dbp_impl.show_to_string() << std::endl
123 << " gas gap " << m_gap_impl.show_to_string() << std::endl
124 << " phi " << m_mea_impl.show_to_string() << std::endl
125 << " strip " << m_str_impl.show_to_string());
126
127 //
128 // Build multirange for the valid set of identifiers
129 //
130
131 // Find value for the field MuonSpectrometer
132 int muonField = -1;
133 const IdDictDictionary* atlasDict = dict_mgr.find_dictionary("ATLAS");
134 if (atlasDict->get_label_value("subdet", "MuonSpectrometer", muonField)) {
135 ATH_MSG_ERROR("Could not get value for label 'MuonSpectrometer' of field 'subdet' in dictionary " << atlasDict->name());
136 return 1;
137 }
138
139 // Build MultiRange down to "doubletR" for all (muon) regions
140 ExpandedIdentifier region_id;
141 region_id.add(muonField);
142 Range prefix;
143 MultiRange muon_range = m_dict->build_multirange(region_id, prefix, "doubletR");
144
145 if (muon_range.size() > 0) {
146 ATH_MSG_INFO("MultiRange built successfully to doubletR: "
147 << "MultiRange size is " << muon_range.size());
148 } else {
149 ATH_MSG_ERROR("Muon MultiRange is empty");
150 return 1;
151 }
152
153 // Build MultiRange down to "detectorElement" for all mdt regions
154
155 ExpandedIdentifier detectorElement_region;
156 detectorElement_region.add(muonField);
157 Range detectorElement_prefix;
158 MultiRange muon_detectorElement_range = m_dict->build_multirange(detectorElement_region, detectorElement_prefix, "doubletPhi");
159 if (muon_detectorElement_range.size() > 0) {
160 ATH_MSG_INFO("MultiRange built successfully to detectorElement: "
161 << "DetectorElement MultiRange size is " << muon_detectorElement_range.size());
162 } else {
163 ATH_MSG_ERROR("Muon RPC ReadoutElement MultiRange is empty");
164 return 1;
165 }
166
167 // Build MultiRange down to "rpcStrip" for all rpc regions
168 ExpandedIdentifier rpc_region;
169 rpc_region.add(muonField);
170 Range rpc_prefix;
171 MultiRange muon_channel_range = m_dict->build_multirange(rpc_region, rpc_prefix, "rpcStrip");
172
173 if (muon_channel_range.size() > 0) {
174 ATH_MSG_INFO("MultiRange built successfully to rpcStrip: "
175 << "MultiRange size is " << muon_channel_range.size());
176 } else {
177 ATH_MSG_ERROR("Muon RPC channel MultiRange is empty");
178 return 1;
179 }
180
181 // build RPC module ranges
182 // Find the regions that have a "RPC doubletR field" and save them
183 int rpcField = -1;
184 status = m_dict->get_label_value("technology", "RPC", rpcField);
185
186 for (int i = 0; i < (int)muon_range.size(); ++i) {
187 const Range& range = muon_range[i];
188 if (range.fields() > m_TECHNOLOGY_INDEX) {
189 const Range::field& field = range[m_TECHNOLOGY_INDEX];
190 if (field.match((ExpandedIdentifier::element_type)rpcField)) {
191 m_full_module_range.add(range);
192 ATH_MSG_DEBUG("field size is " << (int)range.cardinality() << " field index = " << i);
193 }
194 }
195 }
196
197 for (int j = 0; j < (int)muon_detectorElement_range.size(); ++j) {
198 const Range& range = muon_detectorElement_range[j];
199 if (range.fields() > m_TECHNOLOGY_INDEX) {
200 const Range::field& field = range[m_TECHNOLOGY_INDEX];
201 if (field.match((ExpandedIdentifier::element_type)rpcField)) {
203 ATH_MSG_DEBUG("detectorElement field size is " << (int)range.cardinality() << " field index = " << j);
204 }
205 }
206 }
207
208 for (int j = 0; j < (int)muon_channel_range.size(); ++j) {
209 const Range& range = muon_channel_range[j];
210 if (range.fields() > m_TECHNOLOGY_INDEX) {
211 const Range::field& field = range[m_TECHNOLOGY_INDEX];
212 if (field.match((ExpandedIdentifier::element_type)rpcField)) {
213 m_full_channel_range.add(range);
214 ATH_MSG_DEBUG("channel field size is " << (int)range.cardinality() << " field index = " << j);
215 }
216 }
217 }
218
219 // test to see that the multi range is not empty
220 if (m_full_module_range.size() == 0) {
221 ATH_MSG_ERROR("RPC MultiRange ID is empty for modules");
222 return 1;
223 } else {
224 ATH_MSG_DEBUG(" full module range size is " << m_full_module_range.size());
225 }
226
228 if (m_full_detectorElement_range.size() == 0) {
229 ATH_MSG_ERROR("MDT MultiRange ID is empty for detector elements");
230 return 1;
231 }
232
233 // test to see that the multi range is not empty
234 if (m_full_channel_range.size() == 0) {
235 ATH_MSG_ERROR("RPC MultiRange ID is empty for channels");
236 return 1;
237 } else {
238 ATH_MSG_DEBUG(" full channel range size is " << m_full_channel_range.size());
239 }
240
241 // Setup the hash tables for RPC
242 ATH_MSG_INFO("Initializing RPC hash indices ... ");
243 status += init_hashes();
244 status += init_detectorElement_hashes(); // doubletZ
245 status += init_id_to_hashes();
246
247 // Setup hash tables for finding neighbors
248 ATH_MSG_INFO("Initializing RPC hash indices for finding neighbors ... ");
249 status += init_neighbors();
250
251 // retrieve the maximum number of gas gaps
252 ExpandedIdentifier expId;
253 IdContext gasGap_context(expId, 0, m_GASGAP_INDEX);
254 for (const auto& id : m_detectorElement_vec) { // channel Identifiers not filled for RPCs, thus using detector element ones
255 if (!get_expanded_id(id, expId, &gasGap_context)) {
256 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
257 const Range& range = m_full_channel_range[i];
258 if (range.match(expId)) {
259 const Range::field& gap_field = range[m_GASGAP_INDEX];
260 if (not gap_field.empty()) {
261 unsigned int max = (gap_field.get_maximum());
262 if (m_gasGapMax == UINT_MAX)
264 else if (max > m_gasGapMax)
266 }
267 }
268 }
269 }
270 }
271 if (m_gasGapMax == UINT_MAX) {
272 ATH_MSG_ERROR("No maximum number of RPC gas gaps was retrieved");
273 return 1;
274 } else {
275 ATH_MSG_DEBUG(" Maximum number of RPC gas gaps is " << m_gasGapMax);
276 }
277 m_init = true;
278 return (status);
279}
280
282 unsigned int hash_max = module_hash_max();
283 for (unsigned int i = 0; i < hash_max; ++i) {
284 const Identifier& id = m_module_vec[i];
285 m_module_hashes[id] = i;
286 }
287
288 hash_max = detectorElement_hash_max();
289 for (unsigned int i = 0; i < hash_max; ++i) {
290 const Identifier& id = m_detectorElement_vec[i];
292 }
293 return 0;
294}
295
297 const auto itr = m_module_hashes.find(parentID(id));
298 if (itr == m_module_hashes.end()) {
299 hash_id = IdentifierHash(-1);
300 return 1;
301 }
302 hash_id = itr->second;
303 return 0;
304}
305
307 Identifier detElId = id;
308 // Certain chambers require doublet Phi in hashing (See isExtraDetElId()) - do not reset m_dpb_impl in these cases
309 if (!isExtraDetElId(id)) {
310 m_dbp_impl.reset(detElId);
311 }
312 m_gap_impl.reset(detElId);
313 m_mea_impl.reset(detElId);
314 m_str_impl.reset(detElId);
315 auto itr = m_detectorElement_hashes.find(detElId);
316 if (itr == m_detectorElement_hashes.end()) {
317 ATH_MSG_VERBOSE("Cannot find a valid detector element hash for "<<print_to_string(id));
318 hash_id = IdentifierHash(-1);
319 return 1;
320 }
321 hash_id = itr->second;
322 return 0;
323}
324
325void RpcIdHelper::idChannels(const Identifier& id, std::vector<Identifier>& vect) const {
326 vect.clear();
327 Identifier parent = parentID(id);
328 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
329 const Range& range = m_full_channel_range[i];
330 ConstRangeIterator rit(range);
331 for (const auto & expId:rit) {
332 Identifier child;
333 get_id(expId, child);
334 if (parentID(child) == parent) vect.push_back(child);
335 }
336 }
337}
338
339// Access to min and max of level ranges
340
342 ExpandedIdentifier expId;
343 IdContext eta_context(expId, 0, m_ETA_INDEX);
344 if (!get_expanded_id(id, expId, &eta_context)) {
345 int result = 999;
346 for (const Range& range : m_full_module_range) {
347 if (range.match(expId)) {
348 const Range::field& eta_field = range[m_ETA_INDEX];
349 if (not eta_field.empty()) {
350 result = std::min(eta_field.get_minimum(), result);
351 }
352 }
353 }
354 return (result);
355 }
356 return 999; // default
357}
358
360 ExpandedIdentifier expId;
361 IdContext eta_context(expId, 0, m_ETA_INDEX);
362 if (!get_expanded_id(id, expId, &eta_context)) {
363 int result = -999;
364 for (const Range& range : m_full_module_range) {
365 if (range.match(expId)) {
366 const Range::field& eta_field = range[m_ETA_INDEX];
367 if (not eta_field.empty()) {
368 result = std::max(result, eta_field.get_maximum());
369 }
370 }
371 }
372 return (result);
373 }
374 return -999;
375}
376
378 ExpandedIdentifier expId;
379 IdContext phi_context(expId, 0, m_PHI_INDEX);
380 if (!get_expanded_id(id, expId, &phi_context)) {
381 for (unsigned int i = 0; i < m_full_module_range.size(); ++i) {
382 const Range& range = m_full_module_range[i];
383 if (range.match(expId)) {
384 const Range::field& phi_field = range[m_PHI_INDEX];
385 if (not phi_field.empty()) { return (phi_field.get_minimum()); }
386 }
387 }
388 }
389 // Failed to find the min
390 return 999;
391}
392
394 ExpandedIdentifier expId;
395 IdContext phi_context(expId, 0, m_PHI_INDEX);
396 if (!get_expanded_id(id, expId, &phi_context)) {
397 for (unsigned int i = 0; i < m_full_module_range.size(); ++i) {
398 const Range& range = m_full_module_range[i];
399 if (range.match(expId)) {
400 const Range::field& phi_field = range[m_PHI_INDEX];
401 if (not phi_field.empty()) { return (phi_field.get_maximum()); }
402 }
403 }
404 }
405 // Failed to find the max
406 return -999;
407}
408
410 ExpandedIdentifier expId;
411 IdContext doubletR_context(expId, 0, m_DOUBLETR_INDEX);
412 if (!get_expanded_id(id, expId, &doubletR_context)) {
413 for (unsigned int i = 0; i < m_full_module_range.size(); ++i) {
414 const Range& range = m_full_module_range[i];
415 if (range.match(expId)) {
416 const Range::field& r_field = range[m_DOUBLETR_INDEX];
417 if (not r_field.empty()) { return (r_field.get_minimum()); }
418 }
419 }
420 }
421 // Failed to find the min
422 return 999;
423}
424
426 ExpandedIdentifier expId;
427 IdContext doubletR_context(expId, 0, m_DOUBLETR_INDEX);
428 if (!get_expanded_id(id, expId, &doubletR_context)) {
429 for (unsigned int i = 0; i < m_full_module_range.size(); ++i) {
430 const Range& range = m_full_module_range[i];
431 if (range.match(expId)) {
432 const Range::field& r_field = range[m_DOUBLETR_INDEX];
433 if (not r_field.empty()) { return (r_field.get_maximum()); }
434 }
435 }
436 }
437 // Failed to find the max
438 return -999;
439}
440
442 ExpandedIdentifier expId;
443 IdContext doubletZ_context(expId, 0, m_DOUBLETZ_INDEX);
444 if (!get_expanded_id(id, expId, &doubletZ_context)) {
445 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
446 const Range& range = m_full_channel_range[i];
447 if (range.match(expId)) {
448 const Range::field& z_field = range[m_DOUBLETZ_INDEX];
449 if (not z_field.empty()) { return (z_field.get_minimum()); }
450 }
451 }
452 }
453 // Failed to find the min
454 return 999;
455}
456
458 ExpandedIdentifier expId;
459 IdContext doubletZ_context(expId, 0, m_DOUBLETZ_INDEX);
460 if (!get_expanded_id(id, expId, &doubletZ_context)) {
461 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
462 const Range& range = m_full_channel_range[i];
463 if (range.match(expId)) {
464 const Range::field& z_field = range[m_DOUBLETZ_INDEX];
465 if (not z_field.empty()) { return (z_field.get_maximum()); }
466 }
467 }
468 }
469 // Failed to find the max
470 return -999;
471}
472
474 ExpandedIdentifier expId;
475 IdContext doubletPhi_context(expId, 0, m_DOUBLETPHI_INDEX);
476 if (!get_expanded_id(id, expId, &doubletPhi_context)) {
477 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
478 const Range& range = m_full_channel_range[i];
479 if (range.match(expId)) {
480 const Range::field& dphi_field = range[m_DOUBLETPHI_INDEX];
481 if (not dphi_field.empty()) { return (dphi_field.get_minimum()); }
482 }
483 }
484 }
485 // Failed to find the min
486 return 999;
487}
488
490 ExpandedIdentifier expId;
491 IdContext doubletPhi_context(expId, 0, m_DOUBLETPHI_INDEX);
492 if (!get_expanded_id(id, expId, &doubletPhi_context)) {
493 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
494 const Range& range = m_full_channel_range[i];
495 if (range.match(expId)) {
496 const Range::field& dphi_field = range[m_DOUBLETPHI_INDEX];
497 if (not dphi_field.empty()) { return (dphi_field.get_maximum()); }
498 }
499 }
500 }
501 // Failed to find the max
502 return -999;
503}
504
505int RpcIdHelper::gasGapMin(const Identifier& id) const {
506 ExpandedIdentifier expId;
507 IdContext gasGap_context(expId, 0, m_GASGAP_INDEX);
508 if (!get_expanded_id(id, expId, &gasGap_context)) {
509 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
510 const Range& range = m_full_channel_range[i];
511 if (range.match(expId)) {
512 const Range::field& gas_field = range[m_GASGAP_INDEX];
513 if (not gas_field.empty()) { return (gas_field.get_minimum()); }
514 }
515 }
516 }
517 // Failed to find the min
518 return 999;
519}
520
521int RpcIdHelper::gasGapMax(const Identifier& id) const {
522 ExpandedIdentifier expId;
523 IdContext gasGap_context(expId, 0, m_GASGAP_INDEX);
524 if (!get_expanded_id(id, expId, &gasGap_context)) {
525 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
526 const Range& range = m_full_channel_range[i];
527 if (range.match(expId)) {
528 const Range::field& gap_field = range[m_GASGAP_INDEX];
529 if (not gap_field.empty()) { return (gap_field.get_maximum()); }
530 }
531 }
532 }
533 // Failed to find the max
534 return -999;
535}
536
538 ExpandedIdentifier expId;
539 IdContext measuresPhi_context(expId, 0, m_MEASURESPHI_INDEX);
540 if (!get_expanded_id(id, expId, &measuresPhi_context)) {
541 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
542 const Range& range = m_full_channel_range[i];
543 if (range.match(expId)) {
544 const Range::field& mphi_field = range[m_MEASURESPHI_INDEX];
545 if (not mphi_field.empty()) { return (mphi_field.get_minimum()); }
546 }
547 }
548 }
549 // Failed to find the min
550 return 999;
551}
552
554 ExpandedIdentifier expId;
555 IdContext measuresPhi_context(expId, 0, m_MEASURESPHI_INDEX);
556 if (!get_expanded_id(id, expId, &measuresPhi_context)) {
557 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
558 const Range& range = m_full_channel_range[i];
559 if (range.match(expId)) {
560 const Range::field& mphi_field = range[m_MEASURESPHI_INDEX];
561 if (not mphi_field.empty()) { return (mphi_field.get_maximum()); }
562 }
563 }
564 }
565 // Failed to find the max
566 return -999;
567}
568
569int RpcIdHelper::stripMin(const Identifier& id) const {
570 ExpandedIdentifier expId;
571 IdContext strip_context(expId, 0, m_CHANNEL_INDEX);
572 if (!get_expanded_id(id, expId, &strip_context)) {
573 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
574 const Range& range = m_full_channel_range[i];
575 if (range.match(expId)) {
576 const Range::field& strip_field = range[m_CHANNEL_INDEX];
577 if (not strip_field.empty()) { return (strip_field.get_minimum()); }
578 }
579 }
580 }
581 // Failed to find the min
582 return 999;
583}
584
585int RpcIdHelper::stripMax(const Identifier& id) const {
586 ExpandedIdentifier expId;
587 IdContext strip_context(expId, 0, m_CHANNEL_INDEX);
588 if (!get_expanded_id(id, expId, &strip_context)) {
589 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
590 const Range& range = m_full_channel_range[i];
591 if (range.match(expId)) {
592 const Range::field& strip_field = range[m_CHANNEL_INDEX];
593 if (not strip_field.empty()) { return (strip_field.get_maximum()); }
594 }
595 }
596 }
597 // Failed to find the max
598 return -999;
599}
600
601// Public validation of levels
602
603bool RpcIdHelper::valid(const Identifier& id) const {
604 if (!validElement(id)) return false;
605
606 int dbz = doubletZ(id);
607 if ((dbz < doubletZMin(id)) || (dbz > doubletZMax(id))) {
608 ATH_MSG_DEBUG("Invalid doubletZ=" << dbz << " doubletZMin=" << doubletZMin(id) << " doubletZMax=" << doubletZMax(id));
609 return false;
610 }
611
612 int dbp = doubletPhi(id);
613 if ((dbp < doubletPhiMin(id)) || (dbp > doubletPhiMax(id))) {
614 ATH_MSG_DEBUG("Invalid doubletPhi=" << dbp << " doubletPhiMin=" << doubletPhiMin(id) << " doubletPhiMax=" << doubletPhiMax(id));
615 return false;
616 }
617
618 int gasG = gasGap(id);
619 if ((gasG < gasGapMin(id)) || (gasG > gasGapMax(id))) {
620 ATH_MSG_DEBUG("Invalid gasGap=" << gasG << " gasGapMin=" << gasGapMin(id) << " gasGapMax=" << gasGapMax(id));
621 return false;
622 }
623
624 int mPhi = measuresPhi(id);
625 if ((mPhi < measuresPhiMin(id)) || (mPhi > measuresPhiMax(id))) {
626 ATH_MSG_DEBUG("Invalid measuresPhi=" << mPhi << " measuresPhiMin=" << measuresPhiMin(id)
627 << " measuresPhiMax=" << measuresPhiMax(id));
628 return false;
629 }
630
631 int str = strip(id);
632 if ((str < stripMin(id)) || (str > stripMax(id))) {
633 ATH_MSG_DEBUG("Invalid strip=" << str << " stripMin=" << stripMin(id) << " stripMax=" << stripMax(id));
634 return false;
635 }
636 return true;
637}
638bool RpcIdHelper::isStNameInTech(const std::string& stationName) const { return stationName[0] == 'B'; }
640 int station = stationName(id);
641 if (!validStation(station)) {
642 ATH_MSG_DEBUG("Invalid stationName=" << stationNameString(station));
643 return false;
644 }
645
646 int eta = stationEta(id);
647 if (eta < stationEtaMin(id) || eta > stationEtaMax(id)) {
648 ATH_MSG_DEBUG("Invalid stationEta=" << eta << " for stationName=" << stationNameString(station)
649 << " stationEtaMin=" << stationEtaMin(id) << " stationEtaMax=" << stationEtaMax(id));
650 return false;
651 }
652
653 int phi = stationPhi(id);
654 if ((phi < stationPhiMin(id)) || (phi > stationPhiMax(id))) {
655 ATH_MSG_DEBUG("Invalid stationPhi=" << phi << " for stationName=" << stationNameString(station)
656 << " stationPhiMin=" << stationPhiMin(id) << " stationPhiMax=" << stationPhiMax(id));
657 return false;
658 }
659
660 int dbr = doubletR(id);
661 if ((dbr < doubletRMin(id)) || (dbr > doubletRMax(id))) {
662 ATH_MSG_DEBUG("Invalid doubletR=" << dbr << " for stationName=" << stationNameString(station) << " doubletRMin=" << doubletRMin(id)
663 << " doubletRMax=" << doubletRMax(id));
664 return false;
665 }
666 return true;
667}
668
669bool RpcIdHelper::validPad(const Identifier& id) const {
670 if (!validElement(id)) return false;
671
672 int dbz = doubletZ(id);
673 if ((dbz < doubletZMin(id)) || (dbz > doubletZMax(id))) {
674 ATH_MSG_DEBUG("Invalid doubletZ=" << dbz << " doubletZMin=" << doubletZMin(id) << " doubletZMax=" << doubletZMax(id));
675 return false;
676 }
677
678 int dbp = doubletPhi(id);
679 if ((dbp < doubletPhiMin(id)) || (dbp > doubletPhiMax(id))) {
680 ATH_MSG_DEBUG("Invalid doubletPhi=" << dbp << " doubletPhiMin=" << doubletPhiMin(id) << " doubletPhiMax=" << doubletPhiMax(id));
681 return false;
682 }
683 return true;
684}
685
686// Private validation of levels
687
690 ATH_MSG_VERBOSE("Invalid stationName=" << stationNameString(stationName));
691 return false;
692 }
694 ATH_MSG_VERBOSE("Invalid stationEta=" << stationEta << " for stationName=" << stationNameString(stationName)
695 << " stationEtaMin=" << stationEtaMin(id) << " stationEtaMax=" << stationEtaMax(id));
696 return false;
697 }
698 if ((stationPhi < stationPhiMin(id)) || (stationPhi > stationPhiMax(id))) {
699 ATH_MSG_VERBOSE("Invalid stationPhi=" << stationPhi << " for stationName=" << stationNameString(stationName)
700 << " stationPhiMin=" << stationPhiMin(id) << " stationPhiMax=" << stationPhiMax(id));
701 return false;
702 }
703 if ((doubletR < doubletRMin(id)) || (doubletR > doubletRMax(id))) {
704 ATH_MSG_VERBOSE("Invalid doubletR=" << doubletR << " for stationName=" << stationNameString(stationName)
705 << " doubletRMin=" << doubletRMin(id) << " doubletRMax=" << doubletRMax(id));
706 return false;
707 }
708 return true;
709}
710
711// Check values down to detector element level
712
714 int doubletPhi, int gasGap, int measuresPhi, int strip) const {
715 if (!validElement(id, stationName, stationEta, stationPhi, doubletR)) return false;
716
717 if ((doubletZ < doubletZMin(id)) || (doubletZ > doubletZMax(id))) {
718 ATH_MSG_VERBOSE("Invalid doubletZ=" << doubletZ << " doubletZMin=" << doubletZMin(id) << " doubletZMax=" << doubletZMax(id));
719 return false;
720 }
721 if ((doubletPhi < doubletPhiMin(id)) || (doubletPhi > doubletPhiMax(id))) {
722 ATH_MSG_VERBOSE("Invalid doubletPhi=" << doubletPhi << " doubletPhiMin=" << doubletPhiMin(id)
723 << " doubletPhiMax=" << doubletPhiMax(id));
724 return false;
725 }
726 if ((gasGap < gasGapMin(id)) || (gasGap > gasGapMax(id))) {
727 ATH_MSG_VERBOSE("Invalid gasGap=" << gasGap << " gasGapMin=" << gasGapMin(id) << " gasGapMax=" << gasGapMax(id));
728 return false;
729 }
730 if ((measuresPhi < measuresPhiMin(id)) || (measuresPhi > measuresPhiMax(id))) {
731 ATH_MSG_VERBOSE("Invalid measuresPhi=" << measuresPhi << " measuresPhiMin=" << measuresPhiMin(id)
732 << " measuresPhiMax=" << measuresPhiMax(id));
733 return false;
734 }
735 if ((strip < stripMin(id)) || (strip > stripMax(id))) {
736 ATH_MSG_VERBOSE("Invalid strip=" << strip << " stripMin=" << stripMin(id) << " stripMax=" << stripMax(id));
737 return false;
738 }
739 return true;
740}
741
742// Check values down to the pad
743
745 int doubletPhi) const {
746 if (!validElement(id, stationName, stationEta, stationPhi, doubletR)) return false;
747
748 if ((doubletZ < doubletZMin(id)) || (doubletZ > doubletZMax(id))) {
749 ATH_MSG_DEBUG("Invalid doubletZ=" << doubletZ << " doubletZMin=" << doubletZMin(id) << " doubletZMax=" << doubletZMax(id));
750 return false;
751 }
752 if ((doubletPhi < doubletPhiMin(id)) || (doubletPhi > doubletPhiMax(id))) {
753 ATH_MSG_DEBUG("Invalid doubletPhi=" << doubletPhi << " doubletPhiMin=" << doubletPhiMin(id)
754 << " doubletPhiMax=" << doubletPhiMax(id));
755 return false;
756 }
757 return true;
758}
759
761 //
762 // create a vector(s) to retrieve the hashes for compact ids. For
763 // the moment, we implement a hash for detector channels
764 //
765 m_st_BMS = stationNameIndex("BMS");
766 m_st_BIL = stationNameIndex("BIL");
767
768 // detector element hash
770 unsigned int nids = 0;
771 std::set<Identifier> ids;
772 for (unsigned int i = 0; i < m_full_detectorElement_range.size(); ++i) {
773 const Range& range = m_full_detectorElement_range[i];
774 ConstRangeIterator rit(range);
775 for (const auto & expId:rit) {
776 Identifier id;
777 get_id(expId, id);
778 Identifier doubletZ_id = doubletZID(id);
779 if (!isExtraDetElId(id)) {
780 if (!ids.insert(doubletZ_id).second)
781 ATH_MSG_DEBUG("init_detectorElement_hashes "
782 << "Please check the dictionary for possible duplication for " << id);
783 } else if (!ids.insert(id).second) {
784 ATH_MSG_ERROR("init_detectorElement_hashes "
785 << " Error: duplicated id for detector element id. nid " << (int)nids
786 << " doubletPhi ID " << id);
787 return 1;
788
789 }
790 nids++;
791 }
792 }
793 m_detectorElement_hash_max = ids.size();
794 ATH_MSG_INFO("The detector element hash max is " << (int)m_detectorElement_hash_max);
795
796 m_detectorElement_vec.insert(m_detectorElement_vec.end(), ids.begin(), ids.end());
797 return 0;
798}
799
801 // pack fields independently
802 Identifier result((Identifier::value_type)0);
809 return result;
810}
811
813 try {
816 return result;
817 } catch (const std::out_of_range&) { isValid = false; }
818 return Identifier{0};
819}
820
821Identifier RpcIdHelper::elementID(const std::string& stationNameStr, int stationEta, int stationPhi, int doubletR) const {
822 return elementID(stationNameIndex(stationNameStr), stationEta, stationPhi, doubletR);
823}
824Identifier RpcIdHelper::elementID(const std::string& stationNameStr, int stationEta, int stationPhi, int doubletR, bool& isValid) const {
826}
827
833
835 try {
836 const Identifier result = elementID(id, doubletR);
838 return result;
839 } catch (const std::out_of_range&) { isValid = false; }
840 return Identifier{0};
841}
842Identifier RpcIdHelper::elementID(const Identifier& id) const { return parentID(id); }
843
844
846 int measuresPhi) const {
847 // pack fields independently
848 Identifier result((Identifier::value_type)0);
857 m_gap_impl.pack(gasGap, result);
859 return result;
860}
862 int measuresPhi, bool& isValid) const {
863 try {
866 return result;
867 } catch (const std::out_of_range&) { isValid = false; }
868 return Identifier{0};
869}
870
876
884 try {
887 return result;
888 } catch (const std::out_of_range&) { isValid = false; }
889 return Identifier{0};
890}
891
893 int gasGap) const {
894 // pack fields independently
895 Identifier result((Identifier::value_type)0);
904 m_gap_impl.pack(gasGap, result);
905
906 return result;
907}
909 bool& isValid) const {
910 try {
913 return result;
914 } catch (const std::out_of_range&) { isValid = false; }
915 return Identifier{0};
916}
917
923
930 try {
933 return result;
934 } catch (const std::out_of_range&) { isValid = false; }
935 return Identifier{0};
936}
937
939 int measuresPhi, int strip) const {
940 // pack fields independently
941 Identifier result((Identifier::value_type)0);
950 m_gap_impl.pack(gasGap, result);
952 m_str_impl.pack(strip, result);
953 return result;
954}
956 int measuresPhi, int strip, bool& isValid) const {
957 try {
958 const Identifier result =
961 return result;
962 } catch (const std::out_of_range&) { isValid = false; }
963 return Identifier{0};
964}
965Identifier RpcIdHelper::channelID(const std::string& stationNameStr, int stationEta, int stationPhi, int doubletR, int doubletZ,
966 int doubletPhi, int gasGap, int measuresPhi, int strip) const {
968}
969Identifier RpcIdHelper::channelID(const std::string& stationNameStr, int stationEta, int stationPhi, int doubletR, int doubletZ,
970 int doubletPhi, int gasGap, int measuresPhi, int strip, bool& isValid) const {
972 isValid);
973}
974
986 bool& isValid) const {
987 try {
990 return result;
991 } catch (const std::out_of_range&) { isValid = false; }
992 return Identifier{0};
993}
994
995// get the parent id from the strip identifier
997 assert(is_rpc(id));
998 Identifier result(id);
999 m_dbz_impl.reset(result);
1000 m_dbp_impl.reset(result);
1001 m_gap_impl.reset(result);
1002 m_mea_impl.reset(result);
1003 m_str_impl.reset(result);
1004 return result;
1005}
1006
1007// doubletZ Identifier
1009 assert(is_rpc(id));
1010 Identifier result(id);
1011 m_dbp_impl.reset(result);
1012 m_gap_impl.reset(result);
1013 m_mea_impl.reset(result);
1014 m_str_impl.reset(result);
1015 return result;
1016}
1017
1019 // pack fields independently
1020 Identifier result((Identifier::value_type)0);
1026 m_dbr_impl.pack(doubletR, result);
1027 m_dbz_impl.pack(doubletZ, result);
1029 return result;
1030}
1032 bool& isValid) const {
1033 try {
1036 return result;
1037 } catch (const std::out_of_range&) { isValid = false; }
1038 return Identifier{0};
1039}
1040
1042 // pack fields independently
1043 Identifier result(id);
1046 return result;
1047}
1049 try {
1052 return result;
1053 } catch (const std::out_of_range&) { isValid = false; }
1054 return Identifier{0};
1055}
1056// Access to components of the ID
1057
1058int RpcIdHelper::doubletR(const Identifier& id) const { return m_dbr_impl.unpack(id); }
1059
1060int RpcIdHelper::doubletZ(const Identifier& id) const { return m_dbz_impl.unpack(id); }
1061
1062int RpcIdHelper::doubletPhi(const Identifier& id) const { return m_dbp_impl.unpack(id); }
1063
1064int RpcIdHelper::gasGap(const Identifier& id) const { return m_gap_impl.unpack(id); }
1065
1066bool RpcIdHelper::measuresPhi(const Identifier& id) const { return m_mea_impl.unpack(id); }
1067
1068int RpcIdHelper::strip(const Identifier& id) const { return m_str_impl.unpack(id); }
1069
1070int RpcIdHelper::channel(const Identifier& id) const { return strip(id); }
1071
1072// Access to min and max of level ranges
1073
1075
1077
1079
1081
1083
1085
1087
1089
1091
1093
1095
1097
1099
1101
1103
1105
1107
1109 int rpcField = technologyIndex("RPC");
1110 if (m_dict) { rpcField = rpc_field_value(); }
1111 return rpcField;
1112}
1113
1114inline
1116 const int station = stationName(id);
1142
1143
1144 if (station == m_st_BMS) {
1145 const int eta = stationEta(id);
1146 const int dZ = doubletZ(id);
1147 if (std::abs(eta) != 4 && dZ != 3) {
1148 return false;
1149 }
1150 const int dP = doubletPhi(id);
1151 const int dR = doubletR(id);
1152 return (dZ == 3 && dP == 2) ||
1153 (std::abs(eta) == 4 && dZ !=1 && dR != 2 && dP == 2);
1154 } else if (m_st_BIL == station) {
1155 return std::abs(stationEta(id)) == 2 && doubletPhi(id) == 2;
1156 }
1157
1158 return false;
1159}
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.
bool is_rpc(Identifier id) const
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)
const std::string & stationNameString(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
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