ATLAS Offline Software
Loading...
Searching...
No Matches
LArOnline_SuperCellID.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
8#include "IdDict/IdDictMgr.h"
12#include <cmath>
13#include <set>
14#include <string>
15
16/* See comments in Base class */
17
19 LArOnlineID_Base("LArOnline_SuperCellID", "LArOnline_SuperCell", true)
20{
21}
22
23
25
26/* =================================================================== */
28/* =================================================================== */
29{
30 ATH_MSG_INFO("initialize_from_dictionary");
31
32 // Check whether this helper should be reinitialized
33 if (!reinitialize(dict_mgr)) {
34 ATH_MSG_DEBUG("Request to reinitialize not satisfied - tags have not changed");
35 return (0);
36 }
37 else {
38 ATH_MSG_DEBUG("(Re)initialize");
39 }
40
41 // init base object
42 if(AtlasDetectorID::initialize_from_dictionary(dict_mgr)) return (1);
43 m_dict = dict_mgr.find_dictionary ("LArCalorimeter");
44 if(!m_dict) {
45 ATH_MSG_ERROR("initialize_from_dictionary - cannot access LArCalorimeter dictionary ");
46 return 1;
47 }
48
49 // Register version of the dictionary used
50 if (register_dict_tag(dict_mgr, "LArCalorimeter")) return(1);
51
52 // initialize dictionary version
53 AtlasDetectorID::setDictVersion(dict_mgr, "LArCalorimeter");
54
55 /* Initialize the field indices */
57
58 ATH_MSG_INFO("Finished initLevelsFromDict");
59
60
61 /* Find value for the field LAr Calorimeter */
62 const IdDictDictionary* atlasDict = dict_mgr.find_dictionary ("ATLAS");
63 int larField = -1;
64 if (atlasDict->get_label_value("subdet", "LArCalorimeter", larField)) {
65 ATH_MSG_ERROR("Could not get value for label 'LArCalorimeter' of field 'subdet' in dictionary "
66 << atlasDict->name());
67 return (1);
68 }
69
70 /* Find value for the field LArOnline */
71 int larOnlineField = -4;
72 if (m_dict->get_label_value("part", "LArOnline", larOnlineField)) {
73 ATH_MSG_ERROR("Could not get value for label 'LArOnline' of field 'part' in dictionary "
74 << m_dict->name());
75 return (1);
76 }
77
78 /* Find value for the field calibLArOnline */
79 int larOnlineCalibField = -5;
80 if (m_dict->get_label_value("part", "LArOnlineCalib", larOnlineCalibField)) {
81 ATH_MSG_ERROR("Could not get value for label 'LArOnlineCalib' of field 'part' in dictionary "
82 << m_dict->name());
83 return (1);
84 }
85
86 /* Set up id for Region and range prefix */
87 ExpandedIdentifier region_id;
88 region_id.add(larField);
89 region_id.add(larOnlineField);
90 Range prefix;
91
92 /*Full range for all channels*/
93 m_full_laronline_range = m_dict->build_multirange( region_id, group(), prefix);
94 m_full_feb_range = m_dict->build_multirange( region_id, group(), prefix, "slar_slot");
95 m_full_feedthrough_range = m_dict->build_multirange( region_id , group(), prefix, "slar_feedthrough");
96
97 ATH_MSG_DEBUG(" initialize_from_dictionary :");
98 ATH_MSG_DEBUG(" feedthrough range -> " + (std::string)m_full_feedthrough_range);
99 ATH_MSG_DEBUG(" feedthrough slot range -> " + (std::string)m_full_feb_range);
100 ATH_MSG_DEBUG(" channel range -> " + (std::string)m_full_laronline_range);
101
102 /* Setup the hash tables */
103 ATH_MSG_DEBUG("[initialize_from_dictionary] version= " << dictionaryVersion());
104 if( dictionaryVersion() == "fullAtlas" ) {
105 if(LArOnlineID_Base::init_hashes()) return (1);
106 }
107
108 // Setup for hash calculation for channels (febs is further below)
109
110 // Febs have a uniform number of channels
111 // The lookup table only needs to contain the
112 // hash offset for each feb
113
114 // The implementation requires:
115
116 // 1) a lookup table for each feb containing hash offset
117 // 2) a decoder to access the "index" corresponding to the
118 // bec/side/ft/slot fields. These fields use x bits, so the
119 // vector has a length of 2**x.
120
121 /* Create decoder for fields bec to slot */
123 m_bec_impl.bits() +
124 m_side_impl.bits() +
125 m_feedthrough_impl.bits() +
126 m_slot_impl.bits();
127 IdDictFieldImplementation::size_type bits_offset = m_bec_impl.bits_offset();
128 m_bec_slot_impl.set_bits(bits, bits_offset);
129 int size = (1 << bits);
130
131 // Set up vector as lookup table for hash calculation.
132 m_chan_hash_calcs.resize(size);
133
134 for (unsigned int i = 0; i < m_febHashMax; ++i) {
135
136 HWIdentifier febId = feb_Id(i) ;
137
138 HashCalc hc;
139
140 HWIdentifier min = channel_Id ( febId, 0);
141
143 hc.m_hash = min_hash;
145
146 if (m_bec_slot_impl.unpack(min) >= size) {
147 ATH_MSG_DEBUG("Min > " << size);
149 ATH_MSG_DEBUG(" " << m_bec_slot_impl.unpack(min));
150 }
151 }
152
153 // Check channel hash calculation
154 for (unsigned int i = 0; i < m_channelHashMax; ++i) {
155 HWIdentifier id = channel_Id(i);
156 if (channel_Hash(id) != i) {
157 ATH_MSG_ERROR(" ***** Error channel ranges, id, hash, i = " << show_to_string(id));
158 ATH_MSG_ERROR(" , " << channel_Hash(id));
159 ATH_MSG_ERROR(" , " << i);
160 }
161 }
162
163
164
165 // Setup for hash calculation for febs
166
167 // We calculate the feb hash by saving the hash of each
168 // feedthrough in a HashCalc object and then adding on the slot
169 // number for a particular feb
170
171 // The implementation requires:
172
173 // 1) a lookup table for each ft containing hash offset
174 // 2) a decoder to access the "index" corresponding to the
175 // bec/side/ft fields. These fields use x bits, so the
176 // vector has a length of 2**x.
177
178 /* Create decoder for fields bec to ft */
179 bits = m_bec_impl.bits() +
180 m_side_impl.bits() +
181 m_feedthrough_impl.bits();
182 bits_offset = m_bec_impl.bits_offset();
183 m_bec_ft_impl.set_bits(bits, bits_offset);
184 size = (1 << bits);
185
186 // Set up vector as lookup table for hash calculation.
187 m_feb_hash_calcs.resize(size);
188
189 // Get context for conversion to expanded ids
190 IdContext ftContext = feedthroughContext();
191 ExpandedIdentifier ftExpId;
192
193 for (unsigned int i = 0; i < m_feedthroughHashMax; ++i) {
194
196
197 HashCalcFeb hc;
198
199 // Set the hash id for each feedthrough, and then check if one
200 // needs to also save the slot values
202 hc.m_hash = min_hash;
203
204 // For each feedthrough we save the possible slot values for
205 // the hash calculation.
206 if (get_expanded_id(min, ftExpId, &ftContext)) {
207 ATH_MSG_WARNING(" ***** Warning cannot get ft expanded id for " << show_to_string(min));
208 }
209
210 // Now and save values if we either have an
211 // enumerated set of slots, or more than one FT
212 for (unsigned int i = 0; i < m_full_feb_range.size(); ++i) {
213 if (m_full_feb_range[i].match(ftExpId)) {
214 const Range::field& slotField = m_full_feb_range[i][m_slot_index];
215 if (slotField.isBounded() || slotField.isEnumerated()) {
216 // save values
217 unsigned int nvalues = slotField.get_indices();
218 hc.m_slot_values.reserve(std::max(hc.m_slot_values.size()*3/2, hc.m_slot_values.size() + nvalues));
219 for (unsigned int j = 0; j < nvalues; ++j) {
220 hc.m_slot_values.push_back(slotField.get_value_at(j));
221 }
222 }
223 }
224 }
225
226 // Set hash calculator
227 m_feb_hash_calcs[m_bec_ft_impl.unpack(min)] = std::move(hc);
228
229
230 if (m_bec_ft_impl.unpack(min) >= size) {
231 ATH_MSG_DEBUG("Min > " << size << " " << show_to_string(min)
232 << " " << m_bec_ft_impl.unpack(min) << " " << min_hash);
233 }
234 }
235
236 // Check feb hash calculation
237 for (unsigned int i = 0; i < m_febHashMax; ++i) {
238 HWIdentifier id = feb_Id(i);
239 if (feb_Hash(id) != i) {
240 ATH_MSG_ERROR(" ***** Error feb ranges, id, hash, i = "
241 << show_to_string(id) << " , " << feb_Hash(id) << " , " << i);
242 }
243 }
244
245 return 0;
246}
247
249/*========================================================*/
250{
251 int ft = feedthrough(id);
252 return ( barrel_ec(id)==1
253 &&
254 ( ft==3 || ft==10 || ft==16 || ft==22 )
255 );
256}
257
258
259//pos_neg : 0 = negative eta side (C side)
260// 1 = positive eta side (A side)
261
263 /*======================================================*/
264 //
265 int bec= barrel_ec(id);
266 int ft = feedthrough(id);
267 int sl = slot(id);
268 int ch = channel(id);
269 bool sideCondition= (pos_neg(id)==1 && ch>95) || (pos_neg(id)==0 && ch<64);
270
271 return (bec==1 && sl==2 && sideCondition && (ft==2 || ft==9 ||
272 ft==15 || ft==21));
273}
274
276 /*======================================================*/
277 //
278 int bec= barrel_ec(id);
279 int ft = feedthrough(id);
280 int sl = slot(id);
281 int ch = channel(id);
282 bool sideCondition=(pos_neg(id)==1 && ch<=95) || (pos_neg(id)==0 && ch>=64);
283
284 return (bec == 1 &&
285 ((sl == 1 &&
286 (ft == 0 || ft == 1 || ft == 2 || ft == 4 || ft == 5 || ft == 7 || ft == 8 || ft == 9 || ft == 11 || ft == 12 || ft == 13 || ft == 14 || ft == 15 ||
287 ft == 17 || ft == 18 || ft == 19 || ft == 20 || ft == 21 || ft == 23 || ft == 24)) ||
288 (sl==2 && sideCondition && (ft==2 ||ft==9 || ft==15 || ft==21))));
289}
290
292 int bec= barrel_ec(id);
293 int ft = feedthrough(id);
294 return (bec == 1 && !( ft==3 || ft==10 || ft==16 || ft==22 || ft==6));
295}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define min(a, b)
Definition cfImp.cxx:40
virtual std::string dictionaryVersion(void) const override
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.
virtual void setDictVersion(const IdDictMgr &dict_mgr, const std::string &name) override
int register_dict_tag(const IdDictMgr &dict_mgr, const std::string &dict_name)
Register the file and tag names for a particular IdDict dictionary.
std::string show_to_string(Identifier id, const IdContext *context=0, char sep='.') const
or provide the printout in string form
const std::string & group() const
Group name for this helper.
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.
size_type get_indices() const
bool isEnumerated() const
element_type get_value_at(size_type index) const
bool isBounded() const
This is a "hash" representation of an Identifier.
Define the Hash identifier for channels and febs.
int feedthrough(const HWIdentifier id) const
Return the feedthrough of a hardware cell identifier : feedthrough = [0,31] Barrel - A/C side or H/...
MultiRange m_full_laronline_range
HWIdentifier feedthrough_Id(int barrel_ec, int pos_neg, int feedthrough) const
Create a feedthrough identifier from fields.
int slot(const HWIdentifier id) const
Return the slot number of a hardware cell identifier: slot = [1,15] Slot-ID in top part of the crat...
const IdDictDictionary * m_dict
int barrel_ec(const HWIdentifier id) const
Return the position barrel or endcap of a hardware cell identifier: barrel_ec = [0,...
IdentifierHash channel_Hash(HWIdentifier channelId) const
Create channel_hash from channel_Id.
HWIdentifier channel_Id(int barrel_ec, int pos_neg, int feedthrough, int slot, int channel) const
create channel identifier from fields
int get_expanded_id(const HWIdentifier &id, ExpandedIdentifier &exp_id, const IdContext *context) const
create expanded HWIdentifier from HWIdentifier (return == 0 for OK)
IdentifierHash channel_Hash_binary_search(HWIdentifier channelId) const
IdentifierHash feb_Hash_binary_search(HWIdentifier channelId) const
int channel(const HWIdentifier id) const
Return the channel number of a hardware cell identifier channel = [0,127] in all FEB.
MultiRange m_full_feb_range
IdDictFieldImplementation m_bec_ft_impl
LArOnlineID_Base(const std::string &name, const std::string &group, bool is_slar)
Default constructor.
int pos_neg(const HWIdentifier id) const
Return the side of a hardware cell identifier pos_neg = [0,1] positive-side or negative-side Barrel...
IdDictFieldImplementation m_feedthrough_impl
IdentifierHash feb_Hash(HWIdentifier febId) const
Create feb hash identifiers from feb identifiers.
IdContext feedthroughContext() const
Define context for feedthroughs.
IdDictFieldImplementation m_slot_impl
size_type m_feedthroughHashMax
IdDictFieldImplementation m_side_impl
std::vector< HashCalcFeb > m_feb_hash_calcs
int initLevelsFromDict(const std::string &group_name)
IdDictFieldImplementation m_bec_impl
IdDictFieldImplementation m_bec_slot_impl
HWIdentifier feb_Id(int barrel_ec, int pos_neg, int feedthrough, int slot) const
Create feb_Id from fields.
MultiRange m_full_feedthrough_range
std::vector< HashCalc > m_chan_hash_calcs
bool isHECchannel(const HWIdentifier id) const override final
~LArOnline_SuperCellID()
Default destructor.
bool isEMECOW(const HWIdentifier id) const override final
int initialize_from_dictionary(const IdDictMgr &dict_mgr) override final
initialization from the identifier dictionary
bool isEMECIW(const HWIdentifier id) const override final
bool isEMECchannel(const HWIdentifier id) const override final
LArOnline_SuperCellID()
Default constructor.
A Range describes the possible ranges for the field values of an ExpandedIdentifier.
bool match(std::string s1, std::string s2)
match the individual directories of two strings
Definition hcg.cxx:357