ATLAS Offline Software
Loading...
Searching...
No Matches
LArFCAL_Base_ID.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"
11
12#include "CxxUtils/StrFormat.h"
13#include <iostream>
14#include <fstream>
15
17
18#define MAX_BUFFER_LEN 1024
19
20
22 const std::string& group,
23 bool supercell)
25 m_slar (supercell ? 1 : 0)
26{
27}
28
29
31{
32 return(m_slar_impl.unpack(id)) != 0;
33}
34
36{
38 IdContext module_cntxt = module_context();
39 if(!get_expanded_id(modId, expId, &module_cntxt)) {
40 int result = -999;
41 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
42 const Range& range = m_full_channel_range[i];
43 if (range.match(expId)) {
44 const Range::field& eta_field = range[m_ETA_INDEX];
45 if (not eta_field.empty()) {
46 int etamin = eta_field.get_minimum();
47 if (-999 == result) {
48 result = etamin;
49 }
50 else {
51 if (etamin < result) result = etamin;
52 }
53 }
54 }
55 }
56 return (result);
57 }
58 return (-999);
59}
60
62{
64 IdContext module_cntxt = module_context();
65 if(!get_expanded_id(modId, expId, &module_cntxt)) {
66 int result = -999;
67 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
68 const Range& range = m_full_channel_range[i];
69 if (range.match(expId)) {
70 const Range::field& eta_field = range[m_ETA_INDEX];
71 if (not eta_field.empty()) {
72 int etamax = eta_field.get_maximum();
73 if (result < etamax) result = etamax;
74 }
75 }
76 }
77 return (result);
78 }
79 return (-999); // default
80}
81
83{
85 IdContext module_cntxt = module_context();
86 if(!get_expanded_id(modId, expId, &module_cntxt)) {
87 int result = -999;
88 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
89 const Range& range = m_full_channel_range[i];
90 if (range.match(expId)) {
91 const Range::field& phi_field = range[m_PHI_INDEX];
92 if (not phi_field.empty()) {
93 int phimin = phi_field.get_minimum();
94 if (-999 == result) {
95 result = phimin;
96 }
97 else {
98 if (phimin < result) result = phimin;
99 }
100 }
101 }
102 }
103 return (result);
104 }
105 return (-999); // default
106}
107
109{
110 ExpandedIdentifier expId;
111 IdContext module_cntxt = module_context();
112 if(!get_expanded_id(modId, expId, &module_cntxt)) {
113 int result = -999;
114 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
115 const Range& range = m_full_channel_range[i];
116 if (range.match(expId)) {
117 const Range::field& phi_field = range[m_PHI_INDEX];
118 if (not phi_field.empty()) {
119 int phimax = phi_field.get_maximum();
120 if (result < phimax) result = phimax;
121 }
122 }
123 }
124 return (result);
125 }
126 return (-999); // default
127}
128
131{
132 return region_context();
133}
134
136 const std::string& group_name)
137/*=================================================================*/
138{
139 ATH_MSG_DEBUG("initialize_from_dictionary");
140
141 // Check whether this helper should be reinitialized
142 if (!reinitialize(dict_mgr)) {
143 ATH_MSG_DEBUG("Request to reinitialize not satisfied - tags have not changed");
144 return (0);
145 } else {
146 ATH_MSG_DEBUG("(Re)initialize");
147 }
148
149 // init base object
151 "LArCalorimeter"))
152 return (1);
153
154 // initialize dictionary version
155 AtlasDetectorID::setDictVersion(dict_mgr, "LArCalorimeter");
156
157 // Initialize the field indices
158 if (initLevelsFromDict(group_name)) return (1);
159
160 // Find value for the field LAr Calorimeter
161 const IdDictDictionary* atlasDict = dict_mgr.find_dictionary ("ATLAS");
162 int larField = -1;
163 if (atlasDict->get_label_value("subdet", "LArCalorimeter", larField)) {
164 ATH_MSG_ERROR("Could not get value for label 'LArCalorimeter' of field 'subdet' in dictionary " << atlasDict->name());
165 return (1);
166 }
167
168
169 // Find value for the field LArFCAL
170 int larFcalField = -1;
171 if (dict()->get_label_value("part", "LArFCAL", larFcalField)) {
172 ATH_MSG_ERROR("Could not get value for label 'LArFCAL' of field 'part' in dictionary " << atlasDict->name());
173 return (1);
174 }
175
176 // Set up id for region and range prefix
177
179 region_id.add(larField);
180 region_id.add(larFcalField);
181 Range prefix;
182 m_full_channel_range = dict()->build_multirange(region_id, group_name, prefix);
183 m_full_module_range = dict()->build_multirange(region_id, group_name, prefix, "module");
184
185 ATH_MSG_DEBUG(" initialize_from_dict : ");
186 ATH_MSG_DEBUG(" channel range -> " << (std::string)m_full_channel_range);
187 ATH_MSG_DEBUG(" module range -> " << (std::string)m_full_module_range);
188
189 // Setup the hash tables
190 if(init_hashes()) return (1);
191
192 // initilize m_two_sym_sides
193 m_two_sym_sides = ( dictionaryVersion() == "fullAtlas" );
194
195 if (fill_vec_of_dict_regions (group_name)) return 1;
196
197 m_vecOfPhiMin.resize(regions().hash_max());
198 for (unsigned int i = 1; i < regions().hash_max(); ++i) {
199 Identifier modId = module_id(i);
200 m_vecOfPhiMin[i] = phi_min_init(modId);
201 }
202
203 // Setup hash tables for finding neighbours
204 if(m_do_neighbours) {
205 if(init_neighbours(dict_mgr)) return (1);
206 }
207
208 return 0;
209
210}
211
212void LArFCAL_Base_ID::module_id_checks ( int pos_neg, int module ) const
213{
214
215 // Check that id is within allowed range
216 // Fill expanded id
218 expId << pos_neg << module;
219
220 if (!m_full_module_range.match(expId)) {
221 std::string errorMessage = "LArFCAL_Base_ID::module_id() result is not OK: ID, range = "
222 + std::string(expId) + " , " + (std::string)m_full_module_range;
223 throw LArID_Exception(errorMessage , 6);
224 }
225}
226
227void LArFCAL_Base_ID::channel_id_checks ( int pos_neg, int module, int eta, int phi) const
228{
229
230 // Check that id is within allowed range
231 // Fill expanded id
233 expId << pos_neg << module << eta << phi << m_slar ;
234
235 if (!m_full_channel_range.match(expId)) {
236 std::string errorMessage = "LArFCAL_Base_ID::channel_id() result is not OK: ID, range = "
237 + std::string(expId) + " , " + (std::string)m_full_channel_range;
238 throw LArID_Exception(errorMessage , 10);
239 }
240}
241
243 int eta, int phi) const
244{
245 // Check that id is within allowed range
246 // Fill expanded id
247 ExpandedIdentifier expId;
248
249 IdContext context = module_context();
250 if (get_expanded_id(moduleId, expId, &context)) {
251 std::string errorMessage = "LArFCAL_Base_ID::channel_id(modId) result is not OK: ID = "
252 + show_to_string(moduleId) ;
253 throw LArID_Exception(errorMessage , 10);
254 }
255
256 expId << eta << phi << m_slar ;
257
258 if (!m_full_channel_range.match(expId)) {
259 std::string errorMessage = "LArFCAL_Base_ID::channel_id(modId) result is not OK: ID, range = "
260 + std::string(expId) + " , " + (std::string)m_full_channel_range;
261 throw LArID_Exception(errorMessage , 10);
262 }
263}
264
265int LArFCAL_Base_ID::get_expanded_id (const Identifier& id, ExpandedIdentifier& exp_id, const IdContext* context) const
266{
267 // We assume that the context is >= region
268 exp_id.clear();
269 exp_id << lar_field_value()
271 << pos_neg(id)
272 << module(id);
273 if(context && context->end_index() >= m_ETA_INDEX) {
274 exp_id << eta(id);
275 if(context->end_index() >= m_PHI_INDEX) {
276 exp_id << phi(id);
277 if ( context->end_index() >= m_SLAR_INDEX) {
278 exp_id << (unsigned)is_supercell(id);
279 }
280 }
281 }
282 return (0);
283}
284
285int LArFCAL_Base_ID::initLevelsFromDict(const std::string& /*group_name*/)
286{
287 if(!dict()) {
288 ATH_MSG_ERROR("initLevelsFromDict - dictionary NOT initialized ");
289 return (1);
290 }
291
292 // Find out which identifier field corresponds to each level.
293
294 m_fcal_region_index = 999 ;
295 m_LAR_INDEX = 999 ;
296 m_FCAL_INDEX = 999 ;
297 m_POSNEG_INDEX = 999 ;
298 m_MODULE_INDEX = 999 ;
299 m_ETA_INDEX = 999 ;
300 m_PHI_INDEX = 999 ;
301 m_SLAR_INDEX = 999 ;
302
303 // Save index to a FCAL region for unpacking
305 if (dict()->find_region(id,m_fcal_region_index)){
306 ATH_MSG_ERROR("initLevelsFromDict - unable to find fcal region index: id, reg " << id << m_fcal_region_index);
307 return (1);
308 }
309
310 const IdDictField* field = dict()->find_field("subdet") ;
311 if (field) {
312 m_LAR_INDEX = field->index();
313 }
314 else {
315 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'subdet' field ");
316 return (1);
317 }
318
319 field = dict()->find_field("part") ;
320 if (field) {
321 m_FCAL_INDEX = field->index();
322 }
323 else {
324 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'part' field ");
325 return (1);
326 }
327
328 field = dict()->find_field("barrel-endcap") ;
329 if (field) {
330 m_POSNEG_INDEX = field->index();
331 }
332 else {
333 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'barrel-endcap' field ");
334 return (1);
335 }
336
337 field = dict()->find_field("module") ;
338 if (field) {
339 m_MODULE_INDEX = field->index();
340 }
341 else {
342 if(dictionaryVersion() != "H8TestBeam" ) {
343 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'module' field ");
344 }
345 return (1);
346 }
347
348 field = dict()->find_field("eta-fcal") ;
349 if (field) {
350 m_ETA_INDEX = field->index();
351 }
352 else {
353 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'eta' field ");
354 return (1);
355 }
356
357 field = dict()->find_field("phi-fcal") ;
358 if (field) {
359 m_PHI_INDEX = field->index();
360 }
361 else {
362 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'phi' field ");
363 return (1);
364 }
365
366 field = dict()->find_field("is-slar-fcal") ;
367 if (field) {
368 m_SLAR_INDEX = field->index();
369 }
370 else {
371 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'is-slar-fcal' field");
372 return (1);
373 }
374
375 // Set the field implementations
376
377 const IdDictRegion& region = dict()->region(m_fcal_region_index);
378
379 /*
380 std::cout << "LArFCAL_Base_ID::initLevelsFromDict - found levels " << std::endl ;
381 std::cout << "part " << m_FCAL_INDEX << std::endl ;
382 std::cout << "pos-neg " << m_POSNEG_INDEX << std::endl ;
383 std::cout << "module " << m_MODULE_INDEX << std::endl ;
384 std::cout << "eta " << m_ETA_INDEX << std::endl ;
385 std::cout << "phi " << m_PHI_INDEX << std::endl ;
386 */
387
395
396 ATH_MSG_DEBUG("decode index and bit fields for each level:");
397 ATH_MSG_DEBUG("lar " << m_lar_impl.show_to_string());
398 ATH_MSG_DEBUG("fcal " << m_fcal_impl.show_to_string());
399 ATH_MSG_DEBUG("pn " << m_pn_impl.show_to_string());
400 ATH_MSG_DEBUG("mod " << m_module_impl.show_to_string());
401 ATH_MSG_DEBUG("eta " << m_eta_impl.show_to_string());
402 ATH_MSG_DEBUG("phi " << m_phi_impl.show_to_string());
403 ATH_MSG_DEBUG("is-slar " << m_slar_impl.show_to_string());
404
405 return(0) ;
406}
407
409{
410 if (channels().init (*this, "channels",
414 return 1;
415 if (regions().init (*this, "regions",
419 return 1;
420
421 return (0);
422}
423
425 std::vector<IdentifierHash>& neighbourList) const
426{
427 int result = 1;
428
429 neighbourList.clear();
430
431 if(!m_do_neighbours) {
432 ATH_MSG_WARNING("neighbours not initialized !!! returning empty list");
433 return result;
434 }
435
436 if(id>=channel_hash_max()) {
437 ATH_MSG_WARNING("neighbours requested for non-existing channel -- id/max " << id << "/" << channel_hash_max());
438 return result;
439 }
440
441 if( dictionaryVersion() == "fullAtlas" || dictionaryVersion() == "H6TestBeam" ) {
442
443 if ( (option & LArNeighbours::all2D) == LArNeighbours::all2D ){
444 if ( !m_neighbours_2d_vec[(unsigned int)id].empty() ) {
445 neighbourList.insert(neighbourList.end(),
446 m_neighbours_2d_vec[(unsigned int)id].begin(),
447 m_neighbours_2d_vec[(unsigned int)id].end());
448 }
449 }
450
451 if ( (option & LArNeighbours::prevInSamp) ){
452 if ( !m_neighbours_3d_prev_vec[(unsigned int)id].empty() ) {
453 neighbourList.insert(neighbourList.end(),
454 m_neighbours_3d_prev_vec[(unsigned int)id].begin(),
455 m_neighbours_3d_prev_vec[(unsigned int)id].end());
456 }
457 }
458
459 if ( (option & LArNeighbours::nextInSamp) ){
460 if ( !m_neighbours_3d_next_vec[(unsigned int)id].empty() ) {
461 neighbourList.insert(neighbourList.end(),
462 m_neighbours_3d_next_vec[(unsigned int)id].begin(),
463 m_neighbours_3d_next_vec[(unsigned int)id].end());
464 }
465 }
466
467 } else {
468 ATH_MSG_WARNING(" NO FCAL neighbours (yet) in the context of " << dictionaryVersion());
469 }
470 return result;
471}
472
473int LArFCAL_Base_ID::init_neighbours_from_file(const std::string& filename, std::vector<std::set<IdentifierHash> > & vec)
474{
475 ATH_MSG_DEBUG("init_neighbours_from_file");
476 // Find the full path to filename:
477 std::string file = PathResolver::find_file (filename, "DATAPATH");
478 ATH_MSG_DEBUG("Reading file " << file);
479 std::ifstream fin;
480 if (!file.empty()) {
481 fin.open(file.c_str());
482 }
483 else {
484 ATH_MSG_ERROR("Could not find input file " << filename);
485 return 1;
486 }
487 if (fin.bad()) {
488 ATH_MSG_ERROR("Could not open file " << file);
489 return 1;
490 }
491
492 //
493 // Parse the input file
494 //
495
496 vec.resize(channel_hash_max());
497
498 char aLine[MAX_BUFFER_LEN];
499 std::string sLine;
500 bool isComment = true;
501 char AorC,dot;
502 int isamp,iphi,ieta;
503
504 while( isComment ) {
505 sLine.resize( 0 );
506 do {
507 fin.getline(aLine,sizeof(aLine)-1);
508 sLine = std::string(aLine);
509 } while (sLine.empty() && !fin.eof());
510 isComment = ( sLine.find('#') != std::string::npos );
511 }
512 do {
513 unsigned int ic, inext;
514 Identifier thisCell,nextCell;
515 while ( sLine.empty() && !fin.eof()) {
516 fin.getline(aLine,sizeof(aLine)-1);
517 sLine = std::string(aLine);
518 }
519 std::istringstream es( sLine.c_str() );
520
521 if ( es >> AorC >> isamp >> dot >> iphi >> dot >> ieta ) {
522 thisCell = channel_id((AorC=='A'||AorC=='S'?2:-2),isamp,ieta,iphi);
523 ic = channel_hash(thisCell);
524 while ( es >> AorC >> isamp >> dot >> iphi >> dot >> ieta ) {
525 nextCell = channel_id((AorC=='A'||AorC=='S'?2:-2),isamp,ieta,iphi);
526 inext = channel_hash(nextCell);
527 vec[ic].insert(vec[ic].end(),inext);
528 }
529 sLine.resize(0);
530 }
531 }while (!fin.eof()) ;
532 fin.close();
533
534 return 0;
535}
536
537int
539{
540
541 ATH_MSG_DEBUG("init_neighbours");
542
543 int status;
544 std::string f2d,f3dnext,f3dprev;
545
546 if ( m_slar ) {
547 f2d = "FCalSuperCells2DNeighborsNew-April2014.txt";
548 f3dnext = "FCalSuperCells3DNeighborsNextNew-April2014.txt";
549 f3dprev = "FCalSuperCells3DNeighborsPrevNew-April2014.txt";
550 }
551 else {
552 f2d = dict_mgr.find_metadata("FCAL2DNEIGHBORS");
553 f3dnext = dict_mgr.find_metadata("FCAL3DNEIGHBORSNEXT");
554 f3dprev = dict_mgr.find_metadata("FCAL3DNEIGHBORSPREV");
555 }
556 if (f2d.empty() || f3dnext.empty() || f3dprev.empty()) {
557 ATH_MSG_ERROR("init_neighbours: cannot find neighbours files: f2d: " << f2d << " f3dnext: " << f3dnext << " f3dprev: " << f3dprev);
558 throw std::runtime_error("LArFCAL_Base_ID::init_neighbours: Cannot find the FCAL Neighbour file names");
559 }
560
561 status = init_neighbours_2d(f2d);
562 if ( status == 0 )
563 status = init_neighbours_3d_next(f3dnext);
564 if ( status == 0 )
565 status = init_neighbours_3d_prev(f3dprev);
566
567 ATH_MSG_DEBUG("init_neighbours status: " << status);
568
569 if ( status == 0 )
570 return (0);
571 else
572 return (1);
573}
574
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_MSG_ERROR(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define MAX_BUFFER_LEN
std::vector< size_t > vec
Provide helper functions to create formatted strings.
static const Attributes_t empty
virtual std::string dictionaryVersion(void) const override
bool m_do_neighbours
Flag for subclasses to know whether or not to perform neighbour initialization.
bool reinitialize(const IdDictMgr &dict_mgr)
Test whether an idhelper should be reinitialized based on the change of tags.
int lar_fcal_field_value() const
virtual void setDictVersion(const IdDictMgr &dict_mgr, const std::string &name) override
ExpandedIdentifier lar_fcal_exp(void) const
int lar_field_value() const
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.
size_type hash_max() const
Return one more than the largest hash code.
const HashGroup & regions() const
Return the HashGroup for regions.
int initialize_base_from_dictionary(const IdDictMgr &dict_mgr, const std::string &dict_name)
Do basic initialization of the helper.
IdContext region_context() const
Return the context for regions.
size_type channel_hash_max() const
One more than the largest channel (cell) hash code.
CaloIDHelper(const std::string &name, const std::string &group)
Constructor.
Identifier region_id(IdentifierHash hashId) const
Return the region Identifier for a given hash code (no checking).
int fill_vec_of_dict_regions(const std::string &group_name="")
Initialize the list of detector regions.
const IdDictDictionary * dict() const
Return the dictionary for this subdetector.
const std::string & name() const
Return the name for this helper.
const HashGroup & channels() const
Return the HashGroup for channels (cells).
void clear()
Erase all fields.
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
Definition IdContext.h:26
size_type end_index() const
Definition IdContext.h:46
MultiRange build_multirange() const
Get MultiRange for full dictionary.
int get_label_value(const std::string &field, const std::string &label, int &value) const
const std::string & name() const
Dictionary name.
const IdDictField * find_field(const std::string &name) const
const IdDictRegion & region(size_t i) const
Region at index i.
const IdDictDictionary * find_dictionary(const std::string &name) const
Access dictionary by name.
const std::string & find_metadata(const std::string &name) const
Access to meta data, name/value pairs.
Definition IdDictMgr.cxx:87
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.
size_type m_MODULE_INDEX
int eta_max(const Identifier regId) const
max value of eta index (-999 == failure)
int phi_max(const Identifier regId) const
max value of phi index (-999 == failure)
IdDictFieldImplementation m_slar_impl
int phi_min_init(const Identifier regId) const
int init_neighbours_3d_prev(const std::string &filename)
size_type m_POSNEG_INDEX
IdDictFieldImplementation m_pn_impl
int init_neighbours_3d_next(const std::string &filename)
int eta(const Identifier id) const
eta [0,63] module 1 ; [0,31] module 2 ; [0,15] module 3
Identifier module_id(const ExpandedIdentifier &exp_id) const
module identifier for a channel from ExpandedIdentifier
IdDictFieldImplementation m_fcal_impl
int init_neighbours_from_file(const std::string &filename, std::vector< std::set< IdentifierHash > > &vec)
IdDictFieldImplementation m_eta_impl
IdDictFieldImplementation m_module_impl
bool is_supercell(const Identifier id) const
Test if the identifier represents a supercell.
virtual int initialize_base_from_dictionary(const IdDictMgr &dict_mgr, const std::string &group_name)
initialization from the identifier dictionary
int get_neighbours(const IdentifierHash id, const LArNeighbours::neighbourOption &option, std::vector< IdentifierHash > &neighbourList) const
access to hashes for neighbours return == 0 for neighbours found option = all2D,...
std::vector< std::set< IdentifierHash > > m_neighbours_3d_next_vec
int init_neighbours(const IdDictMgr &dict_mgr)
IdentifierHash channel_hash(Identifier channelId) const
Convert a connected channel (cell) Identifier to a hash code.
int eta_min(const Identifier regId) const
min value of eta index (-999 == failure)
int phi(const Identifier id) const
phi [0,15]
int init_neighbours_2d(const std::string &filename)
void module_id_checks(int pos_neg, int module) const
std::vector< std::set< IdentifierHash > > m_neighbours_3d_prev_vec
std::vector< short int > m_vecOfPhiMin
IdDictFieldImplementation m_phi_impl
IdContext module_context() const
context for modules – method kept for backward compatibility.
int initLevelsFromDict(const std::string &group_name)
size_type m_fcal_region_index
std::vector< std::set< IdentifierHash > > m_neighbours_2d_vec
Identifier channel_id(const ExpandedIdentifier &exp_id) const
cell identifier for a channel from ExpandedIdentifier
int pos_neg(const Identifier id) const
pos_neg : +/- 2 (A/C side)
void channel_id_checks(int pos_neg, int module, int eta, int phi) const
MultiRange m_full_module_range
MultiRange m_full_channel_range
IdDictFieldImplementation m_lar_impl
LArFCAL_Base_ID(const std::string &name, const std::string &group, bool supercell)
virtual int get_expanded_id(const Identifier &id, ExpandedIdentifier &exp_id, const IdContext *context) const
create expanded Identifier from Identifier (return == 0 for OK)
Exception class for LAr Identifiers.
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
A Range describes the possible ranges for the field values of an ExpandedIdentifier.
std::string strformat(const char *fmt,...)
return a std::string according to a format fmt and varargs
Definition StrFormat.cxx:49
Definition dot.py:1
TFile * file