ATLAS Offline Software
Loading...
Searching...
No Matches
TileTBID.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5/***************************************************************************
6 Access to Tile Calorimeter TB data
7 -----------------------------------------
8 ***************************************************************************/
9
10
13#include "IdDict/IdDictField.h"
14#include "IdDict/IdDictMgr.h"
15#include "IdDict/IdDictRegion.h"
18
19#include <algorithm>
20#include <cassert>
21#include <cstdio>
22#include <iostream>
23
24
26 : AtlasDetectorID("TileTBID", "tile")
28 , m_SYSTEM_INDEX(999)
29 , m_SECTION_INDEX(999)
30 , m_TYPE_INDEX(999)
31 , m_MODULE_INDEX(999)
32 , m_CHANNEL_INDEX(999)
33 , m_dict(nullptr)
37{
38}
39
40TileTBID::~TileTBID() = default;
41
42//
43// TileTBID methods
44//
45std::string
46TileTBID::to_string( const Identifier & id, int level ) const
47{
48 IdContext context;
49 switch (level) {
50 case 1: case -3:
51 case 2: case -2: context = type_context(); break;
52 case 3: case -1: context = module_context(); break;
53 case 4: case 0: context = channel_context(); break;
54 default:
55 return "TileTBID::to_string - unknown context";
56 }
57
58 ExpandedIdentifier exp_id;
59 if ( get_expanded_id(id,exp_id,&context) ) {
60 return "TileTBID::to_string - can not expand ID";
61 } else {
62 return (std::string)(exp_id);
63 }
64}
65
66//
67// get methods
68//
69int
71{
72 int field = 0;
73 if(!m_dict->unpack(id, 0, index, m_tile_region_index, field)) {
74 return field;
75 } else {
76 return 0;
77 }
78}
79
80//
81// check methods
82//
83bool
85{
86 bool result = is_tile(id)
87 && ( section(id) == TileTBID::TILE_TESTBEAM );
88
89 return result;
90}
91
92//
93// TileCal TB ID
94//
97{
99 return compactID;
100}
101
102//
103// Build type & module id
104//
106TileTBID::type_id ( int type, bool checks ) const
107{
108 if(checks) {
109
110 // Check that id is within allowed range
111
112 // Fill expanded id
114 expId << TileTBID::TILE_TESTBEAM << type;
115
116 if (!m_full_type_range.match(expId)) {
117 std::string errorMessage = "TileTBID::type_id() result is not OK: ID, range = "
118 + std::string(expId) + " , " + (std::string)m_full_type_range;
119 throw TileID_Exception(errorMessage , 2);
120 }
121 }
122
123 Identifier compactID(m_base_tile_type);
124 m_type_impl.pack (type,compactID);
125
126 return (compactID);
127}
130{
131 return type_id (type, do_checks());
132}
133
134
136TileTBID::module_id ( int type, int module, bool checks ) const
137{
138 if(checks) {
139
140 // Check that id is within allowed range
141
142 // Fill expanded id
144 expId << TileTBID::TILE_TESTBEAM << type << module;
145
146 if (!m_full_module_range.match(expId)) {
147 std::string errorMessage = "TileTBID::module_id() result is not OK: ID, range = "
148 + std::string(expId) + " , " + (std::string)m_full_type_range;
149 throw TileID_Exception(errorMessage , 1);
150 }
151 }
152
153 Identifier compactID(m_base_tile_type);
154 m_type_impl.pack (type,compactID);
155 m_module_impl.pack (module,compactID);
156
157 return (compactID);
158}
160TileTBID::module_id ( int type, int module ) const
161{
162 return module_id (type, module, do_checks());
163}
164
165//
166// Build channel id
167//
169TileTBID::channel_id ( int type, int module, int channel, bool checks ) const
170{
171 if(checks) {
172
173 // Check that id is within allowed range
174
175 // Fill expanded id
177 expId << TileTBID::TILE_TESTBEAM << type << module << channel;
178
179 if (!m_full_channel_range.match(expId)) {
180 std::string errorMessage = "TileTBID::channel_id() result is not OK: ID, range = "
181 + std::string(expId) + " , " + (std::string)m_full_type_range;
182 throw TileID_Exception(errorMessage , 1);
183 }
184 }
185
186 Identifier compactID(m_base_tile_type);
187 m_type_impl.pack (type,compactID);
188 m_module_impl.pack (module,compactID);
189 m_channel_impl.pack (channel,compactID);
190
191 return (compactID);
192}
194TileTBID::channel_id ( int type, int module, int channel ) const
195{
196 return channel_id (type, module, channel, do_checks());
197}
198
200TileTBID::module_id ( const Identifier & any_id ) const
201{
202 Identifier compactId(any_id);
203 m_channel_impl.reset(compactId);
204
205 return (compactId);
206}
207
210 int channel ) const
211{
212 Identifier compactId(module_id);
213 m_channel_impl.pack(channel,compactId);
214
215 if(m_do_checks) {
216
217 // Check that id is within allowed range
218
219 // Fill expanded id
220 ExpandedIdentifier expId;
221
222 IdContext context = module_context();
223 if (get_expanded_id(compactId, expId, &context)) {
224 std::string errorMessage = "TileTBID::channel_id(module_id,channel) result is not OK: ID = "
225 + compactId.getString() ;
226 throw TileID_Exception(errorMessage , 1);
227
228 // region_id.show();
229 }
230
231 expId << channel;
232
233 if (!m_full_channel_range.match(expId)) {
234 std::string errorMessage = "TileTBID::channel_id() result is not OK: ID, range = "
235 + (std::string)expId + " , " + (std::string)m_full_type_range;
236 throw TileID_Exception(errorMessage , 1);
237 }
238 }
239
240 return compactId;
241}
242
244 int module, Identifier& module_id )
245{
247 IdContext context = type_context();
248 get_expanded_id(type_id, id, &context);
249 id << module;
250 if (!m_full_module_range.match(id)) {
251 return false;
252 }
253
254 Identifier compactId(0);
255 if (!m_dict->pack32(id,0, id.fields() - 1,compactId)) {
256 module_id = compactId;
257 }
258 return true;
259}
260
262 int module, int channel, Identifier& channel_id )
263{
265 IdContext context = type_context();
266 get_expanded_id(type_id, id, &context);
267 id << module << channel;
268 if (!m_full_channel_range.match(id)) {
269 return false;
270 }
271
272 Identifier compactId(0);
273 if (!m_dict->pack32(id,0, id.fields() - 1,compactId)) {
274 channel_id = compactId;
275 }
276 return true;
277}
278
281{
283 IdContext context = module_context();
284 get_expanded_id(module_id, id, &context);
285 id << channel;
286 if (!m_full_channel_range.match(id)) {
287 return false;
288 }
289
290 Identifier compactId(0);
291 if (!m_dict->pack32(id,0, id.fields() - 1,compactId)) {
292 channel_id = compactId;
293 }
294 return true;
295}
296
299{
301 return {id, 0, m_TYPE_INDEX};
302}
303
306{
308 return {id, 0, m_MODULE_INDEX};
309}
310
313{
315 return {id, 0, m_CHANNEL_INDEX};
316}
317
318int TileTBID::get_id (const IdentifierHash& hash_id, Identifier& id, const IdContext* context ) const
319{
320 int result = 1;
321 id.clear();
322
323 size_t begin = (context) ? context->begin_index(): 0;
324 // cannot get hash if end is 0:
325 size_t end = (context) ? context->end_index() : 0;
326
327 if (0 == begin) {
328
329 if ( m_CHANNEL_INDEX == end ) {
330 if (hash_id < (unsigned int)(m_channel_vec.end() - m_channel_vec.begin())) {
331 id = m_channel_vec[hash_id];
332 result = 0;
333 } else {
334 ATH_MSG_ERROR("get_id: channel hash_id is out of range " << hash_id
335 << " => " << m_channel_vec.size());
336 }
337 } else if ( m_MODULE_INDEX == end ) {
338 if (hash_id < (unsigned int)(m_module_vec.end() - m_module_vec.begin())) {
339 id = m_module_vec[hash_id];
340 result = 0;
341 } else {
342 ATH_MSG_ERROR("get_id: module hash_id is out of range "
343 << hash_id << " => " << m_module_vec.size());
344 }
345 } else if ( m_TYPE_INDEX == end ) {
346 if (hash_id < (unsigned int)(m_type_vec.end() - m_type_vec.begin())) {
347 id = m_type_vec[hash_id];
348 result = 0;
349 } else {
350 ATH_MSG_ERROR("get_id: TYPE hash_id is out of range " << hash_id
351 << " => " << m_type_vec.size());
352 }
353 }
354 }
355 return(result);
356}
357
358
359int TileTBID::get_hash (const Identifier& id, IdentifierHash& hash_id, const IdContext* context ) const
360{
361
362 hash_id = 0;
363 int result = 1;
364
365 size_t begin = (context) ? context->begin_index(): 0;
366 size_t end = (context) ? context->end_index() : 0;
367
368 if (0 == begin) {
369 if ( m_CHANNEL_INDEX == end ) {
370 std::vector<Identifier>::const_iterator it = std::lower_bound(m_channel_vec.begin(),m_channel_vec.end(),id);
371 if ( it != m_channel_vec.end() ){
372 hash_id = it - m_channel_vec.begin();
373 result = 0;
374 }
375 } else if ( m_MODULE_INDEX == end ) {
376 std::vector<Identifier>::const_iterator it = std::lower_bound(m_module_vec.begin(),m_module_vec.end(),id);
377 if ( it != m_module_vec.end() ){
378 hash_id = it - m_module_vec.begin();
379 result = 0;
380 }
381 } else if ( m_TYPE_INDEX == end ) {
382 std::vector<Identifier>::const_iterator it = std::lower_bound(m_type_vec.begin(),m_type_vec.end(),id);
383 if ( it != m_type_vec.end() ){
384 hash_id = it - m_type_vec.begin();
385 result = 0;
386 }
387 }
388 }
389
390 return (result);
391}
392
394{
395 ATH_MSG_INFO("initialize_from_dictionary ");
396
397 // Check whether this helper should be reinitialized
398 if (!reinitialize(dict_mgr)) {
399 ATH_MSG_DEBUG("Request to reinitialize not satisfied - tags have not changed");
400 return (0);
401 }
402 else {
403 ATH_MSG_DEBUG("(Re)initialize");
404 }
405
406 ATH_MSG_DEBUG("calling base initialize_from_dictionary");
407
408 // init base object
409 if(AtlasDetectorID::initialize_from_dictionary(dict_mgr)) return (1);
410
411 // Register version of the TileCalo dictionary
412 if (register_dict_tag(dict_mgr, "TileCalorimeter")) return(1);
413
414 m_dict = dict_mgr.find_dictionary ("TileCalorimeter");
415 if(!m_dict) {
416 ATH_MSG_ERROR("cannot access TileCalorimeter dictionary ");
417 return 1;
418 }
419
420 // Initialize the field indices
421 if(initLevelsFromDict()) return (1);
422
423
424 // Find value for the field Tile Calorimeter
425 const IdDictDictionary* atlasDict = dict_mgr.find_dictionary ("ATLAS");
426 int tileField = -1;
427 if (atlasDict->get_label_value("subdet", "TileCalorimeter", tileField)) {
428 ATH_MSG_ERROR("Could not get value for label 'TileCalorimeter' of field 'subdet' in dictionary "
429 << atlasDict->name());
430 return (1);
431 }
432
433 // Find value for the field Tile Testbeam
434 int tiletbField = -1;
435 if (m_dict->get_label_value("section", "Testbeam", tiletbField)) {
436 ATH_MSG_ERROR("Could not get value for label 'Testbeam' of field 'section' in dictionary "
437 << m_dict->name());
438 return (1);
439 }
440
441 // Set up id for region and range prefix
442 ExpandedIdentifier reg_id;
443 reg_id.add(tileField);
444 reg_id.add(tiletbField);
445 Range prefix;
446
447 m_full_channel_range= m_dict->build_multirange(reg_id, prefix, "tbchannel");
448 m_full_module_range = m_dict->build_multirange(reg_id, prefix, "tbmodule");
449 m_full_type_range = m_dict->build_multirange(reg_id, prefix, "type");
450
451 ATH_MSG_DEBUG("initialize_from_dict : " );
452 ATH_MSG_DEBUG(" type range -> " << (std::string)m_full_type_range );
453 ATH_MSG_DEBUG(" module range -> " << (std::string)m_full_module_range );
454 ATH_MSG_DEBUG(" channel range -> " << (std::string)m_full_channel_range);
455
456 // Setup the hash tables
457 if(init_hashes()) return (1);
458
459 return 0;
460
461}
462
463int TileTBID::get_expanded_id (const Identifier& id, ExpandedIdentifier& exp_id, const IdContext* context) const
464{
465 int result = 1;
466
467 size_t begin = (context) ? context->begin_index() : 0;
468 size_t end = (context) ? context->end_index() : m_CHANNEL_INDEX;
469 assert (end <= m_CHANNEL_INDEX);
470
471 if (0 == end) {
472 result = 0;
473 }
474 else if ( 0 == begin) {
476 result = m_dict->unpack(group(), id, empty, end, exp_id);
477 }
478 else {
479 result = m_dict->unpack(group(), id, context->prefix_id(), end, exp_id);
480 }
481 return result;
482}
483
485{
486 if(!m_dict) {
487 ATH_MSG_ERROR("initLevelsFromDict - dictionary NOT initialized ");
488 return (1);
489 }
490
491 // Find out which identifier field corresponds to each level.
492
493 m_SYSTEM_INDEX = 999;
494 m_SECTION_INDEX = 999;
495 m_TYPE_INDEX = 999;
496 m_MODULE_INDEX = 999;
497 m_CHANNEL_INDEX = 999;
498
499 // Save index to a Tile region for unpacking
501 if (m_dict->find_region(expId,m_tile_region_index)){
502 ATH_MSG_ERROR("initLevelsFromDict - unable to find tile region index: expId, reg "
503 << (std::string)expId << " " << m_tile_region_index);
504 return (1);
505 }
506
507 // Fing a Tile region
508 const IdDictField* field = m_dict->find_field("subdet") ;
509 if (field) {
510 m_SYSTEM_INDEX = field->index();
511 }
512 else {
513 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'subdet' field ");
514 return (1);
515 }
516
517 field = m_dict->find_field("section") ;
518 if (field) {
519 m_SECTION_INDEX = field->index();
520 }
521 else {
522 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'section' field ");
523 return (1);
524 }
525
526 field = m_dict->find_field("type") ;
527 if (field) {
528 m_TYPE_INDEX = field->index();
529 }
530 else {
531 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'type' field ");
532 return (1);
533 }
534
535 field = m_dict->find_field("tbmodule") ;
536 if (field) {
537 m_MODULE_INDEX = field->index();
538 }
539 else {
540 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'tbmodule' field ");
541 return (1);
542 }
543
544 field = m_dict->find_field("tbchannel") ;
545 if (field) {
546 m_CHANNEL_INDEX = field->index();
547 }
548 else {
549 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'tbchannel' field ");
550 return (1);
551 }
552
553 /* Set the field implementations */
554 const IdDictRegion& region = m_dict->region(m_tile_region_index);
555
561
565
566 ATH_MSG_DEBUG("initLevelsFromDict decode index and bit fields for each level: " );
567 ATH_MSG_DEBUG(" system [" << m_SYSTEM_INDEX << "] " << m_system_impl );
568 ATH_MSG_DEBUG(" section [" << m_SECTION_INDEX << "] " << m_section_impl );
569 ATH_MSG_DEBUG(" type [" << m_TYPE_INDEX << "] " << m_type_impl );
570 ATH_MSG_DEBUG(" module [" << m_MODULE_INDEX << "] " << m_module_impl );
571 ATH_MSG_DEBUG(" channel [" << m_CHANNEL_INDEX << "] " << m_channel_impl );
572
573 return(0) ;
574}
575
577{
578 // type hash
579 unsigned int nids = 0;
580 std::set<Identifier> ids;
581 for (unsigned int i = 0; i < m_full_type_range.size(); ++i) {
582 const Range& range = m_full_type_range[i];
583 ConstRangeIterator rit(range);
584 auto first = rit.begin();
585 auto last = rit.end();
586 for (; first != last; ++first) {
587 const ExpandedIdentifier& exp_id = (*first);
588 Identifier id = type_id (exp_id[m_TYPE_INDEX]);
589 if(!(ids.insert(id)).second){
590 ATH_MSG_ERROR("init_hashes "
591 << " Error: duplicated id for type id. nids= " << nids
592 << " compact Id " << show_to_string(id));
593 }
594 nids++;
595 }
596 }
597 m_type_hash_max = m_full_type_range.cardinality();
598 if ( fill_vec(ids, m_type_hash_max, m_type_vec) ) return (1);
599
600 // module hash
601 nids = 0;
602 ids.clear();
603 for (unsigned int i = 0; i < m_full_module_range.size(); ++i) {
604 const Range& range = m_full_module_range[i];
605 ConstRangeIterator rit(range);
606 auto first = rit.begin();
607 auto last = rit.end();
608 for (; first != last; ++first) {
609 const ExpandedIdentifier& exp_id = (*first);
610 Identifier id = module_id (exp_id[m_TYPE_INDEX],
611 exp_id[m_MODULE_INDEX]);
612 if(!(ids.insert(id)).second){
613 ATH_MSG_ERROR("init_hashes "
614 << " Error: duplicated id for module id. nids= " << nids
615 << " compact Id " << show_to_string(id));
616 }
617 nids++;
618 }
619 }
621 if ( fill_vec(ids, m_module_hash_max, m_module_vec) ) return (1);
622
623 // channel hash
624 nids = 0;
625 ids.clear();
626 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
627 const Range& range = m_full_channel_range[i];
628 ConstRangeIterator rit(range);
629 auto first = rit.begin();
630 auto last = rit.end();
631 for (; first != last; ++first) {
632 const ExpandedIdentifier& exp_id = (*first);
633 Identifier id = channel_id (exp_id[m_TYPE_INDEX],
634 exp_id[m_MODULE_INDEX],
635 exp_id[m_CHANNEL_INDEX]);
636 if(!(ids.insert(id)).second){
637 ATH_MSG_ERROR("init_hashes "
638 << " Error: duplicated id for channel id. nids= " << nids
639 << " compact Id " << show_to_string(id));
640 }
641 nids++;
642 }
643 }
645 if ( fill_vec(ids, m_channel_hash_max, m_channel_vec) ) return (1);
646
647 return (0);
648}
649
650int TileTBID::fill_vec (std::set<Identifier> & ids,
651 unsigned int hash_max, std::vector<Identifier> & vec)
652{
653
654 if(ids.size() != hash_max) {
655
656 ATH_MSG_ERROR("fill_vec "
657 << " Error: set size NOT EQUAL to hash max. size " << ids.size()
658 << " hash max " << hash_max);
659
660 return (1);
661 }
662
663 vec.resize(hash_max);
664
665 std::set<Identifier>::const_iterator first = ids.begin();
666 std::set<Identifier>::const_iterator last = ids.end();
667
668 int index = 0;
669 for (;first != last; ++first) {
670 vec[index++] = (*first);
671 }
672
673 return (0);
674}
675
679
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_INFO(x,...)
std::vector< size_t > vec
static const Attributes_t empty
bool m_do_checks
Flag for subclasses to know whether or not to perform checks.
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.
virtual bool do_checks(void) const override
Checks are performed by default in debug compilation and NOT in optimized compilation.
std::string show_to_string(Identifier id, const IdContext *context=0, char sep='.') const
or provide the printout in string form
bool is_tile(Identifier id) const
ExpandedIdentifier tile_exp(void) const
int tile_field_value() const
const std::string & group() const
Group name for this helper.
AtlasDetectorID(const std::string &name, const std::string &group)
ConstRangeIterator end() const
ConstRangeIterator begin() 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 IdDictDictionary * find_dictionary(const std::string &name) const
Access dictionary by name.
const IdDictFieldImplementation & implementation(size_t i) const
This is a "hash" representation of an Identifier.
std::string getString() const
Provide a string form of the identifier - hexadecimal.
A Range describes the possible ranges for the field values of an ExpandedIdentifier.
Exception class for Tile Identifiers.
virtual ~TileTBID()
Default destructor.
virtual int initialize_from_dictionary(const IdDictMgr &dict_mgr)
initialization from the identifier dictionary
Definition TileTBID.cxx:393
Identifier type_id(int type) const
identifer for Tile testbeam detectors of a give type
Definition TileTBID.cxx:129
int fill_vec(std::set< Identifier > &ids, unsigned int hash_max, std::vector< Identifier > &vec)
Definition TileTBID.cxx:650
int initLevelsFromDict()
Definition TileTBID.cxx:484
IdContext channel_context() const
idContext for channels
Definition TileTBID.cxx:312
bool is_tiletb(const Identifier &id) const
Test ID if it is TileTBID.
Definition TileTBID.cxx:84
virtual int get_id(const IdentifierHash &hash_id, Identifier &id, const IdContext *context=0) const
create compact id from hash id (return == 0 for OK)
Definition TileTBID.cxx:318
int get_expanded_id(const Identifier &id, ExpandedIdentifier &exp_id, const IdContext *context) const
create expanded Identifier from Identifier (return == 0 for OK)
Definition TileTBID.cxx:463
Identifier module_id(int type, int module) const
identifer for one module of a Tile testbeam detector
Definition TileTBID.cxx:160
TileTBID()
Default constructor.
Definition TileTBID.cxx:25
int section(const Identifier &id) const
extract section field from TileTB identifier
std::string to_string(const Identifier &id, int level=0) const
extract all fields from TileTB identifier Identifier get_all_fields ( const Identifier & id,...
Definition TileTBID.cxx:46
int init_hashes()
Definition TileTBID.cxx:576
int type(const Identifier &id) const
extract type field from TileTB identifier
Identifier channel_id(int type, int module, int channel) const
identifer for one channel of a Tile testbeam detector
Definition TileTBID.cxx:194
IdContext type_context() const
access to IdContext's which define which levels of fields are contained in the id
Definition TileTBID.cxx:298
int get_field(const Identifier &id, size_type index) const
unpack one field from Identifier
Definition TileTBID.cxx:70
int channel(const Identifier &id) const
extract channel field from TileTB identifier
IdContext module_context() const
idContext for modules
Definition TileTBID.cxx:305
virtual int get_hash(const Identifier &id, IdentifierHash &hash_id, const IdContext *context=0) const
create hash id from compact id (return == 0 for OK)
Definition TileTBID.cxx:359
Identifier tiletb_id() const
identifer for all Tile testbeam detectors
Definition TileTBID.cxx:96
Definition index.py:1