ATLAS Offline Software
Loading...
Searching...
No Matches
LArMiniFCAL_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
9#include "IdDict/IdDictMgr.h"
10#include "IdDict/IdDictRegion.h"
14
15#include <cmath>
16#include <fstream>
17#include <iostream>
18#include <set>
19#include <sstream>
20#include <stdexcept>
21#include <string>
22
23
25 :
26 CaloIDHelper ("LArMiniFCAL_ID", "lar_mini_fcal"),
27 m_is_initialized(false),
29 m_LAR_INDEX(999),
31 m_POSNEG_INDEX(999),
32 m_MODULE_INDEX(999),
33 m_DEPTH_INDEX(999),
34 m_ETA_INDEX(999),
35 m_PHI_INDEX(999),
37{}
38
40
41int LArMiniFCAL_ID::eta_min(const Identifier modId) const
42{
44 IdContext module_cntxt = module_context();
45 if(!get_expanded_id(modId, expId, &module_cntxt)) {
46 int result = -999;
47 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
48 const Range& range = m_full_channel_range[i];
49 if (range.match(expId)) {
50 const Range::field& eta_field = range[m_ETA_INDEX];
51 if (not eta_field.empty()) {
52 int etamin = eta_field.get_minimum();
53 if (-999 == result) {
54 result = etamin;
55 }
56 else {
57 if (etamin < result) result = etamin;
58 }
59 }
60 }
61 }
62 return (result);
63 }
64 return (-999);
65}
66
67int LArMiniFCAL_ID::eta_max(const Identifier modId) const
68{
70 IdContext module_cntxt = module_context();
71 if(!get_expanded_id(modId, expId, &module_cntxt)) {
72 int result = -999;
73 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
74 const Range& range = m_full_channel_range[i];
75 if (range.match(expId)) {
76 const Range::field& eta_field = range[m_ETA_INDEX];
77 if (not eta_field.empty()) {
78 int etamax = eta_field.get_maximum();
79 if (result < etamax) result = etamax;
80 }
81 }
82 }
83 return (result);
84 }
85 return (-999); // default
86}
87
89{
91 IdContext module_cntxt = module_context();
92 if(!get_expanded_id(modId, expId, &module_cntxt)) {
93 int result = -999;
94 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
95 const Range& range = m_full_channel_range[i];
96 if (range.match(expId)) {
97 const Range::field& phi_field = range[m_PHI_INDEX];
98 if (not phi_field.empty()) {
99 int phimin = phi_field.get_minimum();
100 if (-999 == result) {
101 result = phimin;
102 }
103 else {
104 if (phimin < result) result = phimin;
105 }
106 }
107 }
108 }
109 return (result);
110 }
111 return (-999); // default
112}
113
115{
116 ExpandedIdentifier expId;
117 IdContext module_cntxt = module_context();
118 if(!get_expanded_id(modId, expId, &module_cntxt)) {
119 int result = -999;
120 for (unsigned int i = 0; i < m_full_channel_range.size(); ++i) {
121 const Range& range = m_full_channel_range[i];
122 if (range.match(expId)) {
123 const Range::field& phi_field = range[m_PHI_INDEX];
124 if (not phi_field.empty()) {
125 int phimax = phi_field.get_maximum();
126 if (result < phimax) result = phimax;
127 }
128 }
129 }
130 return (result);
131 }
132 return (-999); // default
133}
134
135int LArMiniFCAL_ID::get_neighbours(const IdentifierHash id, const LArNeighbours::neighbourOption& option, std::vector<IdentifierHash>& neighbourList) const
136{
137 int result = 1;
138
139 neighbourList.clear();
140
141 if(!m_do_neighbours) {
142 ATH_MSG_WARNING("neighbours not initialized !!! returning empty list");
143 return result;
144 }
145
146 if(id>=channels().hash_max()) {
147 ATH_MSG_WARNING("neighbours requested for non-existing channel -- id/max " << id << "/"
148 << channel_hash_max());
149 return result;
150 }
151
152 if( dictionaryVersion() == "fullAtlas" ) {
153
154 if ( (option & LArNeighbours::all2D) == LArNeighbours::all2D ){
155 if ( !m_neighbors_2d_vec[(unsigned int)id].empty() ) {
156 neighbourList.insert(neighbourList.end(),
157 m_neighbors_2d_vec[(unsigned int)id].begin(),
158 m_neighbors_2d_vec[(unsigned int)id].end());
159 }
160 }
161
162 if ( (option & LArNeighbours::prevInSamp) ){
163 if ( !m_neighbors_3d_prev_vec[(unsigned int)id].empty() ) {
164 neighbourList.insert(neighbourList.end(),
165 m_neighbors_3d_prev_vec[(unsigned int)id].begin(),
166 m_neighbors_3d_prev_vec[(unsigned int)id].end());
167 }
168 }
169
170 if ( (option & LArNeighbours::nextInSamp) ){
171 if ( !m_neighbors_3d_next_vec[(unsigned int)id].empty() ) {
172 neighbourList.insert(neighbourList.end(),
173 m_neighbors_3d_next_vec[(unsigned int)id].begin(),
174 m_neighbors_3d_next_vec[(unsigned int)id].end());
175 }
176 }
177
178 } else {
179 ATH_MSG_WARNING(" NO MiniFCAL neighbours (yet) in the context of " << dictionaryVersion());
180 }
181 return result;
182}
183
186{
187 return region_context();
188}
189
191/*=================================================================*/
192{
193 ATH_MSG_DEBUG("initialize_from_dictionary");
194
195 // Check whether this helper should be reinitialized
196 if (!reinitialize(dict_mgr)) {
197 ATH_MSG_DEBUG("Request to reinitialize not satisfied - tags have not changed");
198 return (0);
199 }
200 else {
201 ATH_MSG_DEBUG("(Re)initialize");
202 }
203
204 // init base object
205 if(CaloIDHelper::initialize_base_from_dictionary(dict_mgr,
206 "LArCalorimeter"))
207 return (1);
208
209 // initialize dictionary version
210 AtlasDetectorID::setDictVersion(dict_mgr, "LArCalorimeter");
211
212 // Check whether dictionary has miniFCAL
213 if (!dict()->find_group("lar_mini_fcal")) {
214 ATH_MSG_INFO("initialize_from_dict - LArCalorimeter dictionary does NOT contain miniFCAL description. Unable to initialize LArMiniFCAL_ID.");
215 return 0; // return OK
216 }
217
218
219 // Initialize the field indices
220 if(initLevelsFromDict()) {
221 ATH_MSG_WARNING("initialize_from_dict - cannot initialize MiniFCAL part of LArCalorimeter dictionary");
222 return (1);
223 }
224 else {
225
226 // Find value for the field LAr Calorimeter
227 const IdDictDictionary* atlasDict = dict_mgr.find_dictionary ("ATLAS");
228 int larField = -1;
229 if (atlasDict->get_label_value("subdet", "LArCalorimeter", larField)) {
230 ATH_MSG_ERROR("Could not get value for label 'LArCalorimeter' of field 'subdet' in dictionary " << atlasDict->name());
231 return (1);
232 }
233
234
235 // Find value for the field LArMiniFCAL - here the "part" has to be LArFCAL
236 int larFcalField = -1;
237 if (dict()->get_label_value("part", "LArFCAL", larFcalField)) {
238 ATH_MSG_ERROR("Could not get value for label 'LArMiniFCAL' of field 'part' in dictionary " << atlasDict->name());
239 return (1);
240 }
241
242 // Set up id for region and range prefix
243
244 // RDS: need to find the range for MiniFCAL module 0, which includes
245 // both pos/neg endcaps
247 region_id.add(larField);
248 region_id.add(larFcalField);
249 Range prefix;
250 std::string str = "lar_mini_fcal";
251 m_full_channel_range = dict()->build_multirange(region_id, str, prefix);
252 m_full_module_range = dict()->build_multirange(region_id, str, prefix, "module");
253 m_full_depth_range = dict()->build_multirange(region_id, str, prefix, "depth-mfcal");
254
255 ATH_MSG_DEBUG("initialize_from_dict : ");
256 ATH_MSG_DEBUG(" channel range -> " << (std::string)m_full_channel_range);
257 ATH_MSG_DEBUG(" module range -> " << (std::string)m_full_module_range);
258 ATH_MSG_DEBUG(" depth range -> " << (std::string)m_full_depth_range);
259
260 // Setup the hash tables
261 if(init_hashes()) return (1);
262
263 // initilize m_two_sym_sides
264 m_two_sym_sides = ( dictionaryVersion() == "fullAtlas" );
265
266 // collect the regions to later access deta/dphi etc.
267 if (fill_vec_of_dict_regions()) return 1;
268
269 m_vecOfPhiMin.resize(regions().hash_max());
270 for (unsigned int i = 1; i < regions().hash_max(); ++i) {
271 Identifier modId = module_id(i);
272 m_vecOfPhiMin[i] = phi_min_init(modId);
273 }
274
275 // Setup hash tables for finding neighbors
276 if(m_do_neighbours) {
277 if(init_neighbors(dict_mgr)) return (1);
278 }
279
280 }
281
282 m_is_initialized = true;
283 return 0;
284
285}
286
287void LArMiniFCAL_ID::module_id_checks ( int pos_neg, int /*module*/ ) const
288{
289
290 // Check that id is within allowed range
291 // Fill expanded id
293 //expId << pos_neg << module;
294 expId << pos_neg << 0;
295
296 if (!m_full_module_range.match(expId)) {
297 std::string errorMessage = "LArMiniFCAL_ID::module_id() result is not OK: ID, range = "
298 + std::string(expId) + " , " + (std::string)m_full_module_range;
299 throw LArID_Exception(errorMessage , 6);
300 }
301}
302
303void LArMiniFCAL_ID::channel_id_checks ( int pos_neg, int /*module*/, int depth, int eta, int phi) const
304{
305
306 // Check that id is within allowed range
307 // Fill expanded id
309 //expId << pos_neg << module << depth << eta << phi ;
310 expId << pos_neg << 0 << depth << eta << phi ;
311
312 if (!m_full_channel_range.match(expId)) {
313 std::string errorMessage = "LArMiniFCAL_ID::channel_id() result is not OK: ID, range = "
314 + std::string(expId) + " , " + (std::string)m_full_channel_range;
315 throw LArID_Exception(errorMessage , 10);
316 }
317}
318
320 int eta, int phi) const
321{
322 // Check that id is within allowed range
323 // Fill expanded id
324 ExpandedIdentifier expId;
325
326 IdContext context = module_context();
327 if (get_expanded_id(moduleId, expId, &context)) {
328 std::string errorMessage = "LArMiniFCAL_ID::channel_id(modId) result is not OK: ID = "
329 + show_to_string(moduleId) ;
330 throw LArID_Exception(errorMessage , 10);
331 }
332
333 expId << depth << eta << phi ;
334
335 if (!m_full_channel_range.match(expId)) {
336 std::string errorMessage = "LArMiniFCAL_ID::channel_id(modId) result is not OK: ID, range = "
337 + std::string(expId) + " , " + (std::string)m_full_channel_range;
338 throw LArID_Exception(errorMessage , 10);
339 }
340}
341
342int LArMiniFCAL_ID::get_expanded_id (const Identifier& id, ExpandedIdentifier& exp_id, const IdContext* context) const
343{
344 // We assume that the context is >= region
345 exp_id.clear();
346 exp_id << lar_field_value()
348 << pos_neg(id)
349 << module(id);
350 if (context && context->end_index() >= m_DEPTH_INDEX) {
351 exp_id << depth(id);
352 if (context->end_index() >= m_ETA_INDEX) {
353 exp_id << eta(id);
354 if (context->end_index() >= m_PHI_INDEX) {
355 exp_id << phi(id);
356 }
357 }
358 }
359 return 0;
360}
361
363{
364 if(!dict()) {
365 ATH_MSG_ERROR("initLevelsFromDict - dictionary NOT initialized");
366 return (1);
367 }
368
369 // Find out which identifier field corresponds to each level.
370
371 m_fcal_region_index = 999 ;
372 m_LAR_INDEX = 999 ;
373 m_MiniFCAL_INDEX = 999 ;
374 m_POSNEG_INDEX = 999 ;
375 m_MODULE_INDEX = 999 ;
376 m_DEPTH_INDEX = 999 ;
377 m_ETA_INDEX = 999 ;
378 m_PHI_INDEX = 999 ;
379
380 const IdDictField* field = dict()->find_field("subdet") ;
381 if (field) {
382 m_LAR_INDEX = field->index();
383 }
384 else {
385 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'subdet' field");
386 return (1);
387 }
388
389 field = dict()->find_field("part") ;
390 if (field) {
391 m_MiniFCAL_INDEX = field->index();
392 }
393 else {
394 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'part' field");
395 return (1);
396 }
397
398 field = dict()->find_field("barrel-endcap") ;
399 if (field) {
400 m_POSNEG_INDEX = field->index();
401 }
402 else {
403 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'barrel-endcap' field");
404 return (1);
405 }
406
407 field = dict()->find_field("module") ;
408 if (field) {
409 m_MODULE_INDEX = field->index();
410 }
411 else {
412 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'module' field");
413 return (1);
414 }
415
416
417 field = dict()->find_field("depth-mfcal") ;
418 if (field) {
419 m_DEPTH_INDEX = field->index();
420 }
421 else {
422 ATH_MSG_WARNING("initLevelsFromDict - unable to find 'depth' field");
423 return (1);
424 }
425
426
427 field = dict()->find_field("eta-mfcal") ;
428 if (field) {
429 m_ETA_INDEX = field->index();
430 }
431 else {
432 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'eta' field");
433 return (1);
434 }
435
436 field = dict()->find_field("phi-mfcal") ;
437 if (field) {
438 m_PHI_INDEX = field->index();
439 }
440 else {
441 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'phi' field");
442 return (1);
443 }
444
445 // Save index to a MiniFCAL region for unpacking
446
447 // Fill expanded identifier with id for module 0 of the MiniFCAL,
448 // i.e. add on module == 0 to the id below
449
451 if (dict()->find_region(id,m_fcal_region_index)){
452 ATH_MSG_ERROR("initLevelsFromDict - unable to find fcal region index: id, reg " << id << " " << m_fcal_region_index);
453 return (1);
454 }
455
456 // Set the field implementations
457
458
459 const IdDictRegion& region = *dict()->find_region ("", "lar_mini_fcal");
460
468
469 ATH_MSG_DEBUG("decode index and bit fields for each level: ");
470 ATH_MSG_DEBUG("lar " << m_lar_impl);
471 ATH_MSG_DEBUG("fcal " << m_fcal_impl);
472 ATH_MSG_DEBUG("pn " << m_pn_impl);
473 ATH_MSG_DEBUG("mod " << m_module_impl);
474 ATH_MSG_DEBUG("depth " << m_depth_impl);
475 ATH_MSG_DEBUG("eta " << m_eta_impl);
476 ATH_MSG_DEBUG("phi " << m_phi_impl);
477
478 return(0) ;
479}
480
482{
483 if (channels().init (*this, "channels",
487 return 1;
488 if (regions().init (*this, "regions",
492 return 1;
493
494 return (0);
495}
496
497
498int LArMiniFCAL_ID::init_neighbors_from_file(const std::string& filename, std::vector<std::set<IdentifierHash> > & vec)
499{
500 ATH_MSG_DEBUG("init_neighbors_from_file");
501 // Find the full path to filename:
502 std::string file = PathResolver::find_file (filename, "DATAPATH");
503 ATH_MSG_INFO("Reading file " << file);
504
505 std::ifstream fin;
506 if (!file.empty()) {
507 fin.open(file.c_str());
508 }
509 else {
510 ATH_MSG_ERROR("Could not find input file " << filename);
511 return 1;
512 }
513 if (fin.bad()) {
514 ATH_MSG_ERROR("Could not open file " << file);
515 return 1;
516 }
517
518 //
519 // Parse the input file
520 //
521
522 vec.resize(channels().hash_max());
523
524 char aLine[1024];
525 std::string sLine;
526 bool isComment = true;
527 char AorC,dot;
528 int isamp,idepth, iphi,ieta;
529
530 while( isComment ) {
531 sLine.resize( 0 );
532 do {
533 fin.getline(aLine,sizeof(aLine)-1);
534 sLine = std::string(aLine);
535 } while (sLine.empty() && !fin.eof());
536 isComment = ( sLine.find('#') != std::string::npos );
537 }
538 do {
539 while ( sLine.empty() && !fin.eof()) {
540 fin.getline(aLine,sizeof(aLine)-1);
541 sLine = std::string(aLine);
542 }
543 std::istringstream es( sLine.c_str() );
544
545 if ( es >> AorC >> isamp >> dot >> idepth >> dot >> iphi >> dot >> ieta ) {
546 Identifier thisCell = channel_id((AorC=='A'?2:-2),isamp,idepth,ieta,iphi);
547 IdentifierHash ic = channel_hash(thisCell);
548 while ( es >> AorC >> isamp >> dot >> idepth >> dot >> iphi >> dot >> ieta ) {
549 if (!ic.is_valid()) continue;
550 Identifier nextCell = channel_id((AorC=='A'?2:-2),isamp,idepth,ieta,iphi);
551 IdentifierHash inext = channel_hash(nextCell);
552 vec[ic].insert(vec[ic].end(),inext);
553 }
554 sLine.resize(0);
555 }
556 }while (!fin.eof()) ;
557 fin.close();
558
559 return 0;
560}
561
563{
564 ATH_MSG_DEBUG("init_neighbors");
565
566 int status;
567 std::string f2d,f3dnext,f3dprev;
568
569 f2d = dict_mgr.find_metadata("FCAL2DNEIGHBORS");
570 f3dnext = dict_mgr.find_metadata("FCAL3DNEIGHBORSNEXT");
571 f3dprev = dict_mgr.find_metadata("FCAL3DNEIGHBORSPREV");
572 if (f2d.empty() || f3dnext.empty() || f3dprev.empty()) {
573 ATH_MSG_ERROR("init_neighbours: cannot find neighbours files: "
574 << " f2d: " << f2d << " f3dnext: " << f3dnext << " f3dprev: " << f3dprev);
575 throw std::runtime_error("LArMiniFCAL_ID::init_neighbours: Cannot find the FCAL Neighbour file names");
576 }
577
578 status = init_neighbors_2d(f2d);
579 if ( status == 0 )
580 status = init_neighbors_3d_next(f3dnext);
581 if ( status == 0 )
582 status = init_neighbors_3d_prev(f3dprev);
583
584 if ( status == 0 )
585 return (0);
586 else
587 return (1);
588}
589
590
591
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 ATH_MSG_INFO(x,...)
This class provides an interface to generate or decode an identifier for the upper levels of the dete...
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
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 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.
Exception class for LAr Identifiers.
virtual int initialize_from_dictionary(const IdDictMgr &dict_mgr)
initialization from the identifier dictionary
size_type m_ETA_INDEX
IdDictFieldImplementation m_depth_impl
void module_id_checks(int pos_neg, int module) const
int eta_max(const Identifier regId) const
max value of eta index (-999 == failure)
int init_neighbors_from_file(const std::string &filename, std::vector< std::set< IdentifierHash > > &vec)
IdDictFieldImplementation m_phi_impl
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,...
int phi_max(const Identifier regId) const
max value of phi index (-999 == failure)
IdDictFieldImplementation m_module_impl
MultiRange m_full_depth_range
int depth(const Identifier id) const
depth [0,3]
MultiRange m_full_module_range
IdDictFieldImplementation m_pn_impl
int pos_neg(const Identifier id) const
pos_neg : +/- 2 (A/C side)
size_type m_POSNEG_INDEX
int eta_min(const Identifier regId) const
min value of eta index (-999 == failure)
IdentifierHash channel_hash(Identifier channelId) const
Convert a connected channel (cell) Identifier to a hash code.
size_type m_PHI_INDEX
IdDictFieldImplementation m_lar_impl
std::vector< short int > m_vecOfPhiMin
int init_neighbors_3d_next(const std::string &filename)
MultiRange m_full_channel_range
size_type m_MiniFCAL_INDEX
int eta(const Identifier id) const
eta [0,63] module 1 ; [0,31] module 2 ; [0,15] module 3
IdContext module_context() const
context for modules – method kept for backward compatibility.
size_type m_LAR_INDEX
virtual int get_expanded_id(const Identifier &id, ExpandedIdentifier &exp_id, const IdContext *context) const
create expanded Identifier from Identifier (return == 0 for OK)
size_type m_fcal_region_index
IdDictFieldImplementation m_fcal_impl
IdDictFieldImplementation m_eta_impl
int phi_min_init(const Identifier regId) const
void channel_id_checks(int pos_neg, int module, int depth, int eta, int phi) const
std::vector< std::set< IdentifierHash > > m_neighbors_2d_vec
Identifier channel_id(const ExpandedIdentifier &exp_id) const
cell identifier for a channel from ExpandedIdentifier
int phi(const Identifier id) const
phi [0,15]
size_type m_DEPTH_INDEX
size_type m_MODULE_INDEX
int init_neighbors(const IdDictMgr &dict_mgr)
Identifier module_id(const ExpandedIdentifier &exp_id) const
module identifier for a channel from ExpandedIdentifier
int init_neighbors_3d_prev(const std::string &filename)
int init_neighbors_2d(const std::string &filename)
std::vector< std::set< IdentifierHash > > m_neighbors_3d_next_vec
std::vector< std::set< IdentifierHash > > m_neighbors_3d_prev_vec
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 depth
tag string for intendation
Definition fastadd.cxx:46
Definition dot.py:1
TFile * file