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