ATLAS Offline Software
Loading...
Searching...
No Matches
LArEM_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*/
10
11#include <cmath>
12
15#include "IdDict/IdDictField.h"
16#include "IdDict/IdDictGroup.h"
17#include "IdDict/IdDictMgr.h"
18#include "IdDict/IdDictRegion.h"
19#include "LArEM_region.h"
20#include "CxxUtils/StrFormat.h"
22
24
25
27 const std::string& group,
28 bool supercell)
30 m_slar (supercell ? 1 : 0)
31{
32}
33
34
36{
37 std::vector<LArEM_region*>::iterator first = m_vecOfRegions.begin();
38 std::vector<LArEM_region*>::iterator last = m_vecOfRegions.end();
39 for (; first != last; ++first) delete (*first);
40}
41
43{
44 return(m_slar_impl.unpack(id)) != 0;
45}
46
47
48int LArEM_Base_ID::eta_min(const Identifier regId) const
49{
51 IdContext context = region_context();
52 if(!get_expanded_id(regId, expId, &context)) {
53 int result = -999;
54 for (unsigned int i = 0; i < m_full_em_range.size(); ++i) {
55 const Range& range = m_full_em_range[i];
56 if (range.match(expId)) {
57 const Range::field& eta_field = range[m_ETA_INDEX];
58 if (not eta_field.empty()) {
59 int etamin = eta_field.get_minimum();
60 if (-999 == result) {
61 result = etamin;
62 }
63 else {
64 if (etamin < result) result = etamin;
65 }
66 }
67 }
68 }
69 return (result);
70 }
71 return (-999);
72}
73
74int LArEM_Base_ID::eta_max(const Identifier regId) const
75{
77 IdContext context = region_context();
78 if(!get_expanded_id(regId, expId, &context)) {
79 int result = -999;
80 for (unsigned int i = 0; i < m_full_em_range.size(); ++i) {
81 const Range& range = m_full_em_range[i];
82 if (range.match(expId)) {
83 const Range::field& eta_field = range[m_ETA_INDEX];
84 if (not eta_field.empty()) {
85 int etamax = eta_field.get_maximum();
86 if (result < etamax) result = etamax;
87 }
88 }
89 }
90 return (result);
91 }
92 return (-999); // default
93}
94
96{
98 IdContext region_cntxt = region_context();
99 if(!get_expanded_id(regId, expId, &region_cntxt)) {
100 int result = -999;
101 for (unsigned int i = 0; i < m_full_em_range.size(); ++i) {
102 const Range& range = m_full_em_range[i];
103 if (range.match(expId)) {
104 const Range::field& phi_field = range[m_PHI_INDEX];
105 if (not phi_field.empty()) {
106 int phimin = phi_field.get_minimum();
107 if (-999 == result) {
108 result = phimin;
109 }
110 else {
111 if (phimin < result) result = phimin;
112 }
113 }
114 }
115 }
116 return (result);
117 }
118 return (-999); // default
119}
120
121int LArEM_Base_ID::phi_max(const Identifier regId) const
122{
123 ExpandedIdentifier expId;
124 IdContext context = region_context();
125 if(!get_expanded_id(regId, expId, &context)) {
126 int result = -999;
127 for (unsigned int i = 0; i < m_full_em_range.size(); ++i) {
128 const Range& range = m_full_em_range[i];
129 if (range.match(expId)) {
130 const Range::field& phi_field = range[m_PHI_INDEX];
131 if (not phi_field.empty()) {
132 int phimax = phi_field.get_maximum();
133 if (result < phimax) result = phimax;
134 }
135 }
136 }
137 return (result);
138 }
139 return (-999); // default
140}
141
143{
144 // Check that id is within allowed range
145
146 // Fill expanded id
148 expId << barrel_ec << sampling << region ;
149
150 if (!m_full_region_range.match(expId)) {
151 std::string errorMessage = "LArEM_Base_ID::region_id_checks() result is not OK: ID, range = "
152 + std::string(expId) + " , " + (std::string)m_full_region_range;
153 throw LArID_Exception(errorMessage , 5);
154 }
155}
156
157
159 int eta, int phi ) const
160{
161 // Check that id is within allowed range
162
163 // Fill expanded id
165 expId << barrel_ec << sampling << region << eta << phi << m_slar ;
166
167 if (!m_full_em_range.match(expId)) {
168 std::string errorMessage = "LArEM_Base_ID::channel_id_checks() result is not OK: ID, range = "
169 + std::string(expId) + " , " + (std::string)m_full_em_range;
170 throw LArID_Exception(errorMessage , 6);
171 }
172}
173
175 int eta, int phi ) const
176{
177 // Check that id is within allowed range
178
179 // Fill expanded id
180 ExpandedIdentifier expId;
181
182 IdContext context = region_context();
183 if (get_expanded_id(regionId, expId, &context)) {
184 std::string errorMessage = "LArEM_Base_ID::channel_id_checks(regId) result is not OK: ID = "
185 + show_to_string(regionId) ;
186 throw LArID_Exception(errorMessage , 6);
187 }
188
189 expId << eta << phi << m_slar;
190
191 if (!m_full_em_range.match(expId)) {
192 std::string errorMessage = "LArEM_Base_ID::channel_id_checks(regId) result is not OK: ID, range = "
193 + std::string(expId) + " , " + (std::string)m_full_em_range;
194 throw LArID_Exception(errorMessage , 6);
195 }
196}
197
198
199
200
201int LArEM_Base_ID::get_expanded_id (const Identifier& id, ExpandedIdentifier& exp_id, const IdContext* context) const
202{
203 // We assume that the context is >= region
204 exp_id.clear();
205 exp_id << lar_field_value()
207 << barrel_ec(id)
208 << sampling(id)
209 << region(id);
210 if(context && context->end_index() >= m_ETA_INDEX) {
211 exp_id << eta(id);
212 if(context->end_index() >= m_PHI_INDEX) {
213 exp_id << phi(id);
214 if ( context->end_index() >= m_SLAR_INDEX) {
215 exp_id << (unsigned)is_supercell(id);
216 }
217 }
218 }
219 return (0);
220}
221
222int LArEM_Base_ID::initLevelsFromDict (const std::string& group_name)
223{
224 if(!dict()) {
225 ATH_MSG_ERROR("initLevelsFromDict - dictionary NOT initialized");
226 return (1);
227 }
228
229 // Find out which identifier field corresponds to each level.
230
231 m_LAR_INDEX = 999 ;
232 m_EM_INDEX = 999 ;
233 m_BEC_INDEX = 999 ;
234 m_SAMPLING_INDEX = 999 ;
235 m_REGION_INDEX = 999 ;
236 m_ETA_INDEX = 999 ;
237 m_PHI_INDEX = 999 ;
238 m_SLAR_INDEX = 999 ;
239
240 // Find a EM region
241 const IdDictField* field = dict()->find_field("subdet") ;
242 if (field) {
243 m_LAR_INDEX = field->index();
244 }
245 else {
246 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'subdet' field");
247 return (1);
248 }
249
250 field = dict()->find_field("part") ;
251 if (field) {
252 m_EM_INDEX = field->index();
253 }
254 else {
255 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'part' field");
256 return (1);
257 }
258
259 field = dict()->find_field("barrel-endcap") ;
260 if (field) {
261 m_BEC_INDEX = field->index();
262 }
263 else {
264 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'barrel-endcap' field");
265 return (1);
266 }
267
268 field = dict()->find_field("sampling") ;
269 if (field) {
270 m_SAMPLING_INDEX = field->index();
271 }
272 else {
273 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'sampling' field");
274 return (1);
275 }
276
277 field = dict()->find_field("region") ;
278 if (field) {
279 m_REGION_INDEX = field->index();
280 }
281 else {
282 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'region' field");
283 return (1);
284 }
285
286 field = dict()->find_field("eta") ;
287 if (field) {
288 m_ETA_INDEX = field->index();
289 }
290 else {
291 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'eta' field");
292 return (1);
293 }
294
295 field = dict()->find_field("phi") ;
296 if (field) {
297 m_PHI_INDEX = field->index();
298 }
299 else {
300 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'phi' field");
301 return (1);
302 }
303
304 field = dict()->find_field("is-slar") ;
305 if (field) {
306 m_SLAR_INDEX = field->index();
307 }
308 else {
309 ATH_MSG_ERROR("initLevelsFromDict - unable to find 'is-slar' field");
310 return (1);
311 }
312
313 // Set the field implementations
314
315 const IdDictGroup* group = dict()->find_group(group_name);
316 if ( !group ){
317 ATH_MSG_ERROR("initLevelsFromDict - cannot find " << group_name << " group' field ");
318 }
319 else {
320 m_em_region_index = group->region(0).index();
321 }
323
324 m_lar_impl = region.implementation(m_LAR_INDEX);
325 m_em_impl = region.implementation(m_EM_INDEX);
326 m_bec_impl = region.implementation(m_BEC_INDEX);
327 m_sampling_impl = region.implementation(m_SAMPLING_INDEX);
328 m_region_impl = region.implementation(m_REGION_INDEX);
329 m_eta_impl = region.implementation(m_ETA_INDEX);
330 m_phi_impl = region.implementation(m_PHI_INDEX);
331 m_slar_impl = region.implementation(m_SLAR_INDEX);
332
333 ATH_MSG_DEBUG("decode index and bit fields for each level: ");
334 ATH_MSG_DEBUG("lar " << m_lar_impl.show_to_string());
335 ATH_MSG_DEBUG("em " << m_em_impl.show_to_string());
336 ATH_MSG_DEBUG("bec " << m_bec_impl.show_to_string());
337 ATH_MSG_DEBUG("samp " << m_sampling_impl.show_to_string());
338 ATH_MSG_DEBUG("reg " << m_region_impl.show_to_string());
339 ATH_MSG_DEBUG("eta " << m_eta_impl.show_to_string());
340 ATH_MSG_DEBUG("phi " << m_phi_impl.show_to_string());
341 ATH_MSG_DEBUG("is-slar " << m_slar_impl.show_to_string());
342
343 return(0) ;
344}
345
346
348{
349 if (channels().init (*this, "channels",
352 return 1;
353 if (regions().init (*this, "regions",
356 return 1;
357
358 return (0);
359}
360
361
362int
364 const std::string& group_name)
365/*=================================================================*/
366{
367 ATH_MSG_DEBUG("initialize_base_from_dictionary");
368
369 // Check whether this helper should be reinitialized
370 if (!reinitialize(dict_mgr)) {
371 ATH_MSG_DEBUG("Request to reinitialize not satisfied - tags have not changed");
372 return (0);
373 }
374 else {
375 ATH_MSG_DEBUG("(Re)initialize");
376 }
377
378 // init base object
380 "LArCalorimeter"))
381 return (1);
382
383 // initialize dictionary version
384 AtlasDetectorID::setDictVersion(dict_mgr, "LArCalorimeter");
385
386 // Initialize the field indices
387 if (initLevelsFromDict(group_name)) return (1);
388
389 // Find value for the field LAr Calorimeter
390 const IdDictDictionary* atlasDict = dict_mgr.find_dictionary ("ATLAS");
391 int larField = -1;
392 if (atlasDict->get_label_value("subdet", "LArCalorimeter", larField)) {
393 ATH_MSG_ERROR("Could not get value for label 'LArCalorimeter' of field 'subdet' in dictionary "
394 << atlasDict->name());
395 return (1);
396 }
397
398 // Find value for the field LArEM
399 int larEmField = -1;
400 if (dict()->get_label_value("part", "LArEM", larEmField)) {
401 ATH_MSG_ERROR("Could not get value for label 'LArEM' of field 'part' in dictionary "
402 << dict()->name());
403 return (1);
404 }
405
406 // Set up id for region and range prefix
407 ExpandedIdentifier reg_id;
408 reg_id.add(larField);
409 reg_id.add(larEmField);
410 Range prefix;
411
412 m_full_em_range = dict()->build_multirange(reg_id, group_name, prefix);
413 m_full_region_range = dict()->build_multirange(reg_id, group_name, prefix, "region");
414
415 ATH_MSG_DEBUG(" initialize_from_dict : ");
416 ATH_MSG_DEBUG(" region range -> " << (std::string)m_full_region_range);
417 ATH_MSG_DEBUG(" channel range -> " << (std::string)m_full_em_range);
418
419 // initialize m_two_sym_sides
420 m_two_sym_sides = ( dictionaryVersion() == "fullAtlas" );
421
422
423 // Setup the hash tables
424 if(init_hashes()) return (1);
425
426 // initialize dictionary regions
427 if (fill_vec_of_dict_regions (group_name)) return 1;
428
429 m_vecOfPhiMin.resize(regions().hash_max());
430 for (unsigned int i = 0; i < regions().hash_max(); ++i) {
431 Identifier regId = region_id(i);
432 m_vecOfPhiMin[i] = phi_min_init(regId);
433 }
434
435
436 // Setup for hash calculation
437
438 // We use the structure of the region definitions in the
439 // dictionary to optimize. Specifically, each dict region
440 // corresponds to two regions of uniform eta/phi granularity (+/-
441 // in barrel/endcap). The lookup table only needs to contain the
442 // hash offset for each region and the number of phi cells.
443
444 // The implementation requires:
445
446 // 1) a lookup table for each region containing hash offset and
447 // nphi
448 // 2) a decoder to access the "index" corresponding to the
449 // bec/samp/reg fields. These fields use 8 bits, so the
450 // vector has a length of 256 for only 36 regions.
451
452
453 // Create decoder for fields bec to region
455 m_bec_impl.bits() +
456 m_sampling_impl.bits() +
457 m_region_impl.bits();
458 IdDictFieldImplementation::size_type bits_offset = m_bec_impl.bits_offset();
459 m_bec_reg_impl.set_bits(bits, bits_offset);
460
461 // Set up vector as lookup table for hash calculation.
462 m_hash_calcs.resize(256);
463 for (unsigned int i = 0; i < m_full_em_range.size(); ++i) {
464 const Range* range = &m_full_em_range[i];
465 ExpandedIdentifier exp_id = range->minimum ();
466 HashCalc hc;
467
469 exp_id[m_SAMPLING_INDEX],
470 exp_id[m_REGION_INDEX],
471 exp_id[m_ETA_INDEX],
472 exp_id[m_PHI_INDEX]);
474 hc.m_hash = min_neg;
475 Identifier minReg = region_id(min) ;
476 hc.m_etamin = eta_min(minReg);
477 hc.m_phimin = phi_min(minReg);
478 hc.m_nphi = (*range)[m_PHI_INDEX].get_indices();
479 m_hash_calcs[m_bec_reg_impl.unpack(min)] = hc;
480
481 // Flip sign for bec if 2 symmetric sides (ATLAS case, not TB)
482 if(m_two_sym_sides) {
483 Identifier min1 = channel_id (-exp_id[m_BEC_INDEX],
484 exp_id[m_SAMPLING_INDEX],
485 exp_id[m_REGION_INDEX],
486 exp_id[m_ETA_INDEX],
487 exp_id[m_PHI_INDEX]);
489 hc.m_hash = min_pos;
490 m_hash_calcs[m_bec_reg_impl.unpack(min1)] = hc;
491 }
492
493
494 if (m_bec_reg_impl.unpack(min) > 255) {
495 ATH_MSG_WARNING("min > 255 " << i << " " << show_to_string(min) << " " << m_bec_reg_impl.unpack(min) << " ");
496 }
497 }
498
499// Some detailed printout
500// ExpandedIdentifier exp_id = range->maximum ();
501// Identifier max = channel_id (exp_id[m_BEC_INDEX],
502// exp_id[m_SAMPLING_INDEX],
503// exp_id[m_REGION_INDEX],
504// exp_id[m_ETA_INDEX],
505// exp_id[m_PHI_INDEX]);
506// Identifier max0 = channel_id (-exp_id[m_BEC_INDEX],
507// exp_id[m_SAMPLING_INDEX],
508// exp_id[m_REGION_INDEX],
509// exp_id[m_ETA_INDEX],
510// exp_id[m_PHI_INDEX]);
511// std::cout << "channel ranges, id, hash "
512// << i << " "
513// << show_to_string(min) << " "
514// << show_to_string(max0) << " "
515// << show_to_string(min1) << " "
516// << show_to_string(max) << " "
517// << channel_hash_binary_search(min) << " "
518// << channel_hash_binary_search(min1) << " "
519// << min_pos << " "
520// << range->cardinality() << " "
521// << std::endl;
522// }
523
524 // Check hash calculation
525 for (unsigned int i = 0; i < channels().hash_max(); ++i) {
526 Identifier id = channel_id(i);
527 if (channel_hash(id) != i) {
528 ATH_MSG_ERROR("channel ranges, id, hash " << show_to_string(id) << " " << channel_hash(id) << " " << i);
529 }
530 }
531
532 // Setup hash tables for finding neighbors (at the end of initialisation,
533 // to benefit from optimization
534 if(m_do_neighbours) {
535 if(init_neighbors()) return (1);
536 }
537
538 return 0;
539}
540
541
543 std::vector<IdentifierHash>& neighbourList) const
544{
545 int result = 1;
546
547 neighbourList.clear();
548
549 if(!m_do_neighbours) {
550 ATH_MSG_WARNING("neighbours not initialized !!! returning empty list");
551 return result;
552 }
553
554 if(id >= channel_hash_max()) {
555 ATH_MSG_WARNING("neighbours requested for non-existing channel -- id/max " << id << "/" << channel_hash_max());
556 return result;
557 }
558
559 const short int maxNeighb=22;
560 IdentifierHash neighbList[maxNeighb];
561 int neighbourIndex = 0;
562
563 // cell index
564 unsigned int index=id;
565
566 //
567 // .... find in which region is the cell
568 //
569 auto itr = std::upper_bound(m_cells.begin(), m_cells.end(), index);
570 unsigned short int regionN = (itr - m_cells.begin()) - 1;
571 assert (regionN < m_vecOfRegions.size());
572 // get pointer to this region
573 LArEM_region* emRegion = m_vecOfRegions[regionN];
574 // retrieve characteristic numbers for this region
575 short int nPhi = emRegion->phiN();
576 float gPhi = emRegion->phiGranularity();
577 unsigned int minHash = emRegion->hashMin();
578 unsigned int maxHash = emRegion->hashMax();
579
580 bool corners2DOnly = ( (option & LArNeighbours::all2D)
582 //
583 // .... previous neighbour in phi
584 //
585 IdentifierHash prevNeighbInPhi=NOT_VALID_HASH;
586 if( (option & LArNeighbours::prevInPhi)
587 || corners2DOnly ){
588 if(!get_prevInPhi(emRegion, index, nPhi, minHash, neighbourIndex, neighbList)){
589 // always 1 and only 1 neighbour in phi in ATLAS, but 0 or 1 neighbour in phi in TB
590 prevNeighbInPhi=neighbList[neighbourIndex-1];
591 if( corners2DOnly ){
592 neighbourIndex--;
593 }
594 }
595 }
596
597 //
598 // ....next neighbour in phi
599 //
600 IdentifierHash nextNeighbInPhi=NOT_VALID_HASH;
601 if( (option & LArNeighbours::nextInPhi)
602 || corners2DOnly ){
603 if(!get_nextInPhi(emRegion, index, nPhi, minHash, neighbourIndex, neighbList)){
604 // always 1 and only 1 neighbour in phi in ATLAS, but 0 or 1 neighbour in phi in TB
605 nextNeighbInPhi=neighbList[neighbourIndex-1];
606 if( corners2DOnly ){
607 neighbourIndex--;
608 }
609 }
610 }
611
612 //
613 // ....previous neighbours in eta
614 //
615 unsigned int nPrevBiggerCell=NOT_VALID_HASH;
616 if( (option & LArNeighbours::prevInEta) ){
617 get_prevInEta(emRegion, index, nPhi, gPhi, minHash, neighbourIndex, neighbList, nPrevBiggerCell);
618 }
619
620 //
621 // ....next neighbours in eta
622 //
623 unsigned int nNextBiggerCell=NOT_VALID_HASH;
624 if( (option & LArNeighbours::nextInEta) ){
625 get_nextInEta(emRegion, index, nPhi, gPhi, maxHash, neighbourIndex, neighbList, nNextBiggerCell);
626 }
627
628 //
629 // ....corners in the same sampling
630 //
631 if( (option & LArNeighbours::corners2D) ){
632 if(prevNeighbInPhi != NOT_VALID_HASH){
633 unsigned int index1=prevNeighbInPhi;
634 int oldNeighbourIndex = neighbourIndex;
635 // allow only 1 corner cell in order to avoid the problem of
636 // non-mutual neighbourness
637 // since the cells come ordered in phi it should be the last cell for
638 // prevNeighbInPhi as starting points
639 get_prevInEta(emRegion, index1, nPhi, gPhi, minHash, neighbourIndex, neighbList, nPrevBiggerCell);
640 if ( neighbourIndex > oldNeighbourIndex+1 ) {
641 neighbList[oldNeighbourIndex] = neighbList[neighbourIndex-1];
642 neighbourIndex = oldNeighbourIndex+1;
643 }
644 oldNeighbourIndex = neighbourIndex;
645 get_nextInEta(emRegion, index1, nPhi, gPhi, maxHash, neighbourIndex, neighbList, nNextBiggerCell);
646 if ( neighbourIndex > oldNeighbourIndex+1 ) {
647 neighbList[oldNeighbourIndex] = neighbList[neighbourIndex-1];
648 neighbourIndex = oldNeighbourIndex+1;
649 }
650 }
651
652 if(nextNeighbInPhi != NOT_VALID_HASH){
653 unsigned int index2=nextNeighbInPhi;
654 int oldNeighbourIndex = neighbourIndex;
655 // allow only 1 corner cell in order to avoid the problem of
656 // non-mutual neighbourness
657 // since the cells come ordered in phi it should be the 1st cell for
658 // nextNeighbInPhi
659 get_prevInEta(emRegion, index2, nPhi, gPhi, minHash, neighbourIndex, neighbList, nPrevBiggerCell);
660 if ( neighbourIndex > oldNeighbourIndex+1 ) {
661 neighbourIndex = oldNeighbourIndex+1;
662 }
663 oldNeighbourIndex = neighbourIndex;
664 get_nextInEta(emRegion, index2, nPhi, gPhi, maxHash, neighbourIndex, neighbList, nNextBiggerCell);
665 if ( neighbourIndex > oldNeighbourIndex+1 ) {
666 neighbourIndex = oldNeighbourIndex+1;
667 }
668 }
669 }
670
671 //
672 // .... neighbours in sampling (common code)
673 // EM caracteristics = granularity changes in both eta and phi + partial overlap of samplings
674 //
675 if( (option & LArNeighbours::upAndDown) ) {
676 // granularity of the initial region
677 double gEta = (double)(emRegion->etaGranularity());
678 // initial eta
679 int nEta = int( (index-minHash) / nPhi);
680 double absEta = (double)(emRegion->etaMin()) + (double)(nEta * gEta);
681
682 // previous neighbours in sampling
683 if( (option & LArNeighbours::prevInSamp) ){
684 get_prevInSamp(emRegion, index, nPhi, minHash, gEta, gPhi, absEta, neighbourIndex, neighbList);
685 }
686
687 // next neighbours in sampling
688 if( (option & LArNeighbours::nextInSamp) ){
689 get_nextInSamp(emRegion, index, nPhi, minHash, gEta, gPhi, absEta, neighbourIndex, neighbList);
690 }
691 }
692
693 //
694 // .... neighbours across subdet
695 //
697 // granularity of the initial region
698 double gEta = (double)(emRegion->etaGranularity());
699 // initial eta
700 int nEta = int( (index-minHash) / nPhi);
701 double absEta = (double)(emRegion->etaMin()) + (double)(nEta * gEta);
702
703 // prev neighbours in subdet
704 if( (option & LArNeighbours::prevSubDet) ){
705 get_prevInSubdet(emRegion, index, nPhi, minHash, gEta, gPhi, absEta, neighbourIndex, neighbList);
706 }
707 // next neighbours in subdet
708 if( (option & LArNeighbours::nextSubDet) ){
709 get_nextInSubdet(emRegion, index, nPhi, minHash, gEta, gPhi, absEta, neighbourIndex, neighbList);
710 }
711 }
712
713
714 neighbourList.resize(neighbourIndex);
715 if (neighbourIndex > 0) {
716 if (neighbourIndex <= maxNeighb) {
717 std::copy (&neighbList[0], &neighbList[neighbourIndex], neighbourList.begin());
718 result = 0 ;
719 } else {
720 ATH_MSG_WARNING(" more than 22 neighbours for this cell, NONE will be retained");
721 }
722 }
723
724 return result;
725}
726
727
728int LArEM_Base_ID::get_prevInPhi(const LArEM_region* emRegion, const unsigned int& index, const short int& nPhi, const unsigned int& minHash,
729 int& neighbourIndex, IdentifierHash* neighbList)
730{
731 int result = 1;
732 unsigned int nIndex = index-1;
733 if(!emRegion->isPhiMin(index)) {
734 if( ((index-minHash)%(nPhi)) == 0 ) nIndex=index+nPhi-1;
735 IdentifierHash nHash = nIndex;
736 neighbList[neighbourIndex] = nHash;
737 neighbourIndex++;
738 result = 0;
739 }
740 return result;
741}
742
743int LArEM_Base_ID::get_nextInPhi(const LArEM_region* emRegion, const unsigned int& index, const short int& nPhi, const unsigned int& minHash,
744 int& neighbourIndex, IdentifierHash* neighbList)
745{
746 int result = 1;
747 if(!emRegion->isPhiMax(index)) {
748 unsigned int nIndex = index+1;
749 if( ((index-minHash+1)%(nPhi)) == 0 ) nIndex=index-nPhi+1;
750 IdentifierHash nHash = nIndex;
751 neighbList[neighbourIndex] = nHash;
752 neighbourIndex++;
753 result = 0;
754 }
755 return result;
756}
757
758int LArEM_Base_ID::get_prevInEta(const LArEM_region* emRegion, const unsigned int& index, const short int& nPhi, const float& gPhi,
759 const unsigned int& minHash,
760 int& neighbourIndex, IdentifierHash* neighbList, unsigned int& nBiggerCell) const
761{
762 int result = 1;
763
764 unsigned int nIndex = 0;
765 IdentifierHash nHash = 0;
766
767 if( emRegion->isEtaMin(index)){
768 // eta == etaMin -> go to previous region in eta
769 short int nPrevEtaRegion = emRegion->prevEtaRegion();
770 // no neighbour if no previous region in eta
771 if( nPrevEtaRegion != NOT_VALID_REGION ) {
772 LArEM_region* prevEmRegion = m_vecOfRegions[nPrevEtaRegion];
773 if(emRegion->isFirstBarrelRegion()) {
774 // special case: barrel middle
775 unsigned int minHashMinus = prevEmRegion->hashMin();
776 nIndex = minHashMinus + index-minHash ;
777 nHash = nIndex;
778 neighbList[neighbourIndex] = nHash;
779 neighbourIndex++;
780 result = 0;
781 }
782 else {
783 // Tell clang to optimize assuming that FP exceptions can trap.
784 // Otherwise, it can vectorize the division, which can lead to
785 // spurious division-by-zero traps from unused vector lanes.
787 short int nPhiMinus = prevEmRegion->phiN();
788 float gPhiMinus= prevEmRegion->phiGranularity();
789 unsigned int maxHashMinus = prevEmRegion->hashMax();
790 float phiMargin = 0.25*std::min(gPhi,gPhiMinus);
791 float rPhi = (index-minHash)*gPhi+emRegion->phiMin();
792 int nPhiMinusFirst = int(std::floor((rPhi -prevEmRegion->phiMin())
793 /gPhiMinus+phiMargin))
794 +maxHashMinus-nPhiMinus;
795 int nPhiMinusNext = int(std::floor((rPhi+gPhi-prevEmRegion->phiMin())
796 /gPhiMinus+phiMargin))
797 +maxHashMinus-nPhiMinus;
798 if ( nPhiMinusNext == nPhiMinusFirst ) nPhiMinusNext++;
799
800 for(int i=nPhiMinusFirst; i<nPhiMinusNext; i++){
801 nIndex = i ;
802 if(nIndex != nBiggerCell) {
803 nHash = nIndex;
804 neighbList[neighbourIndex] = nHash;
805 neighbourIndex++;
806 result = 0;
807 }
808 // to avoid duplicated cells in corners
809 if(gPhi < gPhiMinus && nBiggerCell == NOT_VALID_HASH) nBiggerCell=nIndex;
810 }
811 }
812 }
813 }
814 else {
815 // stay in same region (1 neighbour)
816 nIndex = index - nPhi;
817 nHash = nIndex;
818 neighbList[neighbourIndex] = nHash;
819 neighbourIndex++;
820 result = 0;
821 }
822 return result;
823}
824
825int LArEM_Base_ID::get_nextInEta(const LArEM_region* emRegion, const unsigned int& index, const short int& nPhi, const float& gPhi,
826 const unsigned int& maxHash,
827 int& neighbourIndex, IdentifierHash* neighbList, unsigned int& nBiggerCell) const
828{
829 int result = 1;
830
831 unsigned int nIndex = 0;
832 IdentifierHash nHash = 0;
833
834 if( emRegion->isEtaMax(index)){
835 // eta == etaMax -> go to next region in eta
836 short int nNextEtaRegion = emRegion->nextEtaRegion();
837 // no neighbour if no next region in eta
838 if( nNextEtaRegion != NOT_VALID_REGION ) {
839 // Tell clang to optimize assuming that FP exceptions can trap.
840 // Otherwise, it can vectorize the division, which can lead to
841 // spurious division-by-zero traps from unused vector lanes.
843 LArEM_region* nextEmRegion = m_vecOfRegions[nNextEtaRegion];
844 float gPhiPlus= nextEmRegion->phiGranularity();
845 unsigned int minHashPlus = nextEmRegion->hashMin();
846 float phiMargin = 0.25*std::min(gPhi,gPhiPlus);
847 float rPhi = (index+nPhi-maxHash)*gPhi+emRegion->phiMin();
848 int nPhiPlusFirst = int(std::floor((rPhi -nextEmRegion->phiMin())
849 /gPhiPlus+phiMargin))+minHashPlus;
850 int nPhiPlusNext = int(std::floor((rPhi+gPhi-nextEmRegion->phiMin())
851 /gPhiPlus+phiMargin))+minHashPlus;
852 if ( nPhiPlusNext == nPhiPlusFirst ) nPhiPlusNext++;
853
854 for(int i=nPhiPlusFirst; i<nPhiPlusNext; i++){
855 nIndex = i ;
856 if(nIndex != nBiggerCell) {
857 nHash = nIndex;
858 neighbList[neighbourIndex] = nHash;
859 neighbourIndex++;
860 result = 0;
861 }
862 // to avoid duplicated cells in corners
863 if(gPhi < gPhiPlus && nBiggerCell == NOT_VALID_HASH) nBiggerCell=nIndex;
864 }
865 }
866 }
867 else {
868 // stay in same region (1 neighbour)
869 nIndex = index + nPhi;
870 nHash = nIndex;
871 neighbList[neighbourIndex] = nHash;
872 neighbourIndex++;
873 result = 0;
874 }
875 return result;
876}
877
878int LArEM_Base_ID::get_prevInSamp(const LArEM_region* emRegion, const unsigned int& index, const short int& nPhi, const unsigned int& minHash,
879 const double& gEta, const float& gPhi, const double& absEta,
880 int& neighbourIndex, IdentifierHash* neighbList) const
881{
882 int result = 1;
883
884 // neighbours' indices
885 unsigned int nIndex=0;
886 // neighbours' hash
887 IdentifierHash nHash=0;
888
889 // previous region in sampling
890 const std::vector<short int>& prevSampRegion= emRegion->prevSamplingRegion();
891 int nPrevSampReg = prevSampRegion.size();
892 if(nPrevSampReg > 0) {
893 for(int ireg=0; ireg<nPrevSampReg; ireg++) {
894 LArEM_region* prevEmRegion = m_vecOfRegions[prevSampRegion[ireg]];
895 // eta granularity of previous region in sampling
896 double gEtaMinus= (double)(prevEmRegion->etaGranularity());
897 // starting eta of prev region
898 double minEtaMinus = (double)(prevEmRegion->etaMin());
899 double maxEtaMinus = (double)(prevEmRegion->etaMax());
900 double margin = 0.25*std::min(gEta,gEtaMinus);
901 if((minEtaMinus < absEta+gEta-margin) && (absEta+margin < maxEtaMinus)) {
902 // Tell clang to optimize assuming that FP exceptions can trap.
903 // Otherwise, it can vectorize the division, which can lead to
904 // spurious division-by-zero traps from unused vector lanes.
906
907 // phi granularity of previous region in sampling
908 float gPhiMinus= prevEmRegion->phiGranularity();
909 // max phi of previous region in sampling
910 short int nPhiMinus = prevEmRegion->phiN();
911 // first hash of previous region in sampling
912 unsigned int minHashMinus = prevEmRegion->hashMin();
913 float phiMargin = 0.25*std::min(gPhi,gPhiMinus);
914 // phi 'coordinate' in initial region
915 float rPhi = ((index-minHash)%nPhi)*gPhi+emRegion->phiMin();
916 int nPhiMinusFirst = int(std::floor((rPhi -prevEmRegion->phiMin())
917 /gPhiMinus+phiMargin));
918 int nPhiMinusNext = int(std::floor((rPhi+gPhi-prevEmRegion->phiMin())
919 /gPhiMinus+phiMargin));
920 if ( nPhiMinusNext == nPhiMinusFirst ) nPhiMinusNext++;
921
922 // eta 'coordinate' in initial region
923 double fEtaMinus = (absEta-minEtaMinus) / gEtaMinus + margin ;
924 // eta 'coordinate' in initial region + 1
925 double fEtaMaxMinus = (absEta+gEta-minEtaMinus) / gEtaMinus + margin ;
926 int nEtaMinus = int(fEtaMinus);
927 int nEtaMaxMinus = int(fEtaMaxMinus);
928 if ( nEtaMaxMinus == nEtaMinus ) nEtaMaxMinus++;
929 for(int i=nEtaMinus; i<nEtaMaxMinus; i++) {
930 for (int j=nPhiMinusFirst; j<nPhiMinusNext;j++) {
931 nIndex = minHashMinus + i * nPhiMinus + j;
932 if( (nIndex >= prevEmRegion->hashMin()) && (nIndex < prevEmRegion->hashMax()) ) {
933 nHash = nIndex;
934 neighbList[neighbourIndex] = nHash;
935 neighbourIndex++;
936 result = 0;
937 }
938 }
939 }
940 } // end eta condition
941 } // loop on ireg
942 }
943 return result;
944}
945
946int LArEM_Base_ID::get_nextInSamp(const LArEM_region* emRegion, const unsigned int& index, const short int& nPhi, const unsigned int& minHash,
947 const double& gEta, const float& gPhi, const double& absEta,
948 int& neighbourIndex, IdentifierHash* neighbList) const
949{
950 int result = 1;
951
952 // neighbours' indices
953 unsigned int nIndex=0;
954 // neighbours' hash
955 IdentifierHash nHash=0;
956
957 const std::vector<short int>& nextSampRegion= emRegion->nextSamplingRegion();
958 int nNextSampReg = nextSampRegion.size();
959 if(nNextSampReg > 0) {
960 for(int ireg=0; ireg<nNextSampReg; ireg++) {
961 LArEM_region* nextEmRegion = m_vecOfRegions[nextSampRegion[ireg]];
962 double gEtaPlus = (double)(nextEmRegion->etaGranularity());
963 float gPhiPlus= nextEmRegion->phiGranularity();
964 double minEtaPlus = (double)(nextEmRegion->etaMin());
965 double maxEtaPlus = (double)(nextEmRegion->etaMax());
966 double margin = 0.25*std::min(gEta,gEtaPlus);
967 if((minEtaPlus < absEta+gEta-margin) && (absEta+margin < maxEtaPlus)) {
968 // Tell clang to optimize assuming that FP exceptions can trap.
969 // Otherwise, it can vectorize the division, which can lead to
970 // spurious division-by-zero traps from unused vector lanes.
972
973 short int nPhiPlus = nextEmRegion->phiN();
974 unsigned int minHashPlus = nextEmRegion->hashMin();
975 float phiMargin = 0.25*std::min(gPhi,gPhiPlus);
976 // phi 'coordinate' in initial region
977 float rPhi = ((index-minHash)%nPhi)*gPhi+emRegion->phiMin();
978 int nPhiPlusFirst = int(std::floor((rPhi -nextEmRegion->phiMin())
979 /gPhiPlus+phiMargin));
980 int nPhiPlusNext = int(std::floor((rPhi+gPhi-nextEmRegion->phiMin())
981 /gPhiPlus+phiMargin));
982 if ( nPhiPlusNext == nPhiPlusFirst ) nPhiPlusNext++;
983
984 double fEtaPlus = (absEta-minEtaPlus) / gEtaPlus + margin ;
985 // eta 'coordinate' in initial region + 1
986 double fEtaMaxPlus = (absEta+gEta-minEtaPlus) / gEtaPlus + margin ;
987 int nEtaPlus = int(fEtaPlus) ;
988 int nEtaMaxPlus = int(fEtaMaxPlus) ;
989 if (nEtaMaxPlus == nEtaPlus) nEtaMaxPlus++;
990
991 for(int i=nEtaPlus; i<nEtaMaxPlus; i++){
992 for(int j=nPhiPlusFirst; j<nPhiPlusNext; j++){
993 nIndex = minHashPlus + i * nPhiPlus + j;
994 if( (nIndex >= nextEmRegion->hashMin()) && (nIndex < nextEmRegion->hashMax()) ) {
995 nHash = nIndex;
996 neighbList[neighbourIndex] = nHash;
997 neighbourIndex++;
998 result = 0;
999 }
1000 }
1001 }
1002 } // end eta condition
1003 } // end loop on regions
1004 }
1005 return result;
1006}
1007
1008
1009int LArEM_Base_ID::get_prevInSubdet(const LArEM_region* emRegion, const unsigned int& index, const short int& nPhi, const unsigned int& minHash,
1010 const double& gEta, const float& gPhi, const double& absEta,
1011 int& neighbourIndex, IdentifierHash* neighbList) const
1012{
1013 int result = 1;
1014
1015 // neighbours' indices
1016 unsigned int nIndex=0;
1017 // neighbours' hash
1018 IdentifierHash nHash=0;
1019
1020 // previous region in sampling
1021 const std::vector<short int>& prevSubdetRegion= emRegion->prevSubdetRegion();
1022 int nPrevSubdetReg = prevSubdetRegion.size();
1023 if(nPrevSubdetReg > 0) {
1024 for(int ireg=0; ireg<nPrevSubdetReg; ireg++) {
1025 LArEM_region* prevEmRegion = m_vecOfRegions[prevSubdetRegion[ireg]];
1026 // eta granularity of previous region in sampling
1027 double gEtaMinus= (double)(prevEmRegion->etaGranularity());
1028 // starting eta of prev region
1029 double minEtaMinus = (double)(prevEmRegion->etaMin());
1030 double maxEtaMinus = (double)(prevEmRegion->etaMax());
1031 double margin = 0.25*std::min(gEta,gEtaMinus);
1032 if((minEtaMinus < absEta+gEta-margin) && (absEta+margin < maxEtaMinus)) {
1033 // Tell clang to optimize assuming that FP exceptions can trap.
1034 // Otherwise, it can vectorize the division, which can lead to
1035 // spurious division-by-zero traps from unused vector lanes.
1037
1038 // phi granularity of previous region in sampling
1039 float gPhiMinus= prevEmRegion->phiGranularity();
1040 // max phi of previous region in sampling
1041 short int nPhiMinus = prevEmRegion->phiN();
1042 // first hash of previous region in sampling
1043 unsigned int minHashMinus = prevEmRegion->hashMin();
1044 float phiMargin = 0.25*std::min(gPhi,gPhiMinus);
1045 // phi 'coordinate' in initial region
1046 float rPhi = ((index-minHash)%nPhi)*gPhi+emRegion->phiMin();
1047 int nPhiMinusFirst = int(std::floor((rPhi -prevEmRegion->phiMin())
1048 /gPhiMinus+phiMargin));
1049 int nPhiMinusNext = int(std::floor((rPhi+gPhi-prevEmRegion->phiMin())
1050 /gPhiMinus+phiMargin));
1051 if ( nPhiMinusNext == nPhiMinusFirst ) nPhiMinusNext++;
1052 // eta 'coordinate' in initial region
1053 double fEtaMinus = (absEta-minEtaMinus) / gEtaMinus + margin ;
1054 // eta 'coordinate' in initial region + 1
1055 double fEtaMaxMinus = (absEta+gEta-minEtaMinus) / gEtaMinus + margin ;
1056 int nEtaMinus = int(fEtaMinus);
1057 int nEtaMaxMinus = int(fEtaMaxMinus);
1058 if ( nEtaMaxMinus == nEtaMinus ) nEtaMaxMinus++;
1059
1060 for(int i=nEtaMinus; i<nEtaMaxMinus; i++) {
1061 for (int j=nPhiMinusFirst; j<nPhiMinusNext;j++) {
1062 nIndex = minHashMinus + i * nPhiMinus + j;
1063 if( (nIndex >= prevEmRegion->hashMin()) && (nIndex < prevEmRegion->hashMax()) ) {
1064 nHash = nIndex;
1065 neighbList[neighbourIndex] = nHash;
1066 neighbourIndex++;
1067 result = 0;
1068 }
1069 }
1070 }
1071 } // end eta condition
1072 } // loop on ireg
1073 }
1074 return result;
1075}
1076
1077int LArEM_Base_ID::get_nextInSubdet(const LArEM_region* emRegion, const unsigned int& index, const short int& nPhi, const unsigned int& minHash,
1078 const double& gEta, const float& gPhi, const double& absEta,
1079 int& neighbourIndex, IdentifierHash* neighbList) const
1080{
1081 int result = 1;
1082
1083 // neighbours' indices
1084 unsigned int nIndex=0;
1085 // neighbours' hash
1086 IdentifierHash nHash=0;
1087
1088 const std::vector<short int>& nextSubdetRegion= emRegion->nextSubdetRegion();
1089 int nNextSubdetReg = nextSubdetRegion.size();
1090 if(nNextSubdetReg > 0) {
1091 for(int ireg=0; ireg<nNextSubdetReg; ireg++) {
1092 LArEM_region* nextEmRegion = m_vecOfRegions[nextSubdetRegion[ireg]];
1093 double gEtaPlus = (double)(nextEmRegion->etaGranularity());
1094 float gPhiPlus= nextEmRegion->phiGranularity();
1095 double minEtaPlus = (double)(nextEmRegion->etaMin());
1096 double maxEtaPlus = (double)(nextEmRegion->etaMax());
1097 double margin = 0.25*std::min(gEta,gEtaPlus);
1098 if((minEtaPlus < absEta+gEta-margin) && (absEta+margin < maxEtaPlus)) {
1099 // Tell clang to optimize assuming that FP exceptions can trap.
1100 // Otherwise, it can vectorize the division, which can lead to
1101 // spurious division-by-zero traps from unused vector lanes.
1103
1104 short int nPhiPlus = nextEmRegion->phiN();
1105 unsigned int minHashPlus = nextEmRegion->hashMin();
1106 float phiMargin = 0.25*std::min(gPhi,gPhiPlus);
1107 // phi 'coordinate' in initial region
1108 float rPhi = ((index-minHash)%nPhi)*gPhi+emRegion->phiMin();
1109 int nPhiPlusFirst = int(std::floor((rPhi -nextEmRegion->phiMin())
1110 /gPhiPlus+phiMargin));
1111 int nPhiPlusNext = int(std::floor((rPhi+gPhi-nextEmRegion->phiMin())
1112 /gPhiPlus+phiMargin));
1113 if ( nPhiPlusNext == nPhiPlusFirst ) nPhiPlusNext++;
1114
1115 double fEtaPlus = (absEta-minEtaPlus) / gEtaPlus + margin ;
1116 // eta 'coordinate' in initial region + 1
1117 double fEtaMaxPlus = (absEta+gEta-minEtaPlus) / gEtaPlus + margin ;
1118 int nEtaPlus = int(fEtaPlus) ;
1119 int nEtaMaxPlus = int(fEtaMaxPlus) ;
1120 if (nEtaMaxPlus == nEtaPlus) nEtaMaxPlus++;
1121
1122 for(int i=nEtaPlus; i<nEtaMaxPlus; i++) {
1123 for(int j=nPhiPlusFirst; j<nPhiPlusNext; j++) {
1124 nIndex = minHashPlus + i * nPhiPlus + j;
1125 if( (nIndex >= nextEmRegion->hashMin()) && (nIndex < nextEmRegion->hashMax()) ) {
1126 nHash = nIndex;
1127 neighbList[neighbourIndex] = nHash;
1128 neighbourIndex++;
1129 result = 0;
1130 }
1131 }
1132 }
1133 } // end eta condition
1134 } // end loop on regions
1135 }
1136 return result;
1137}
1138
1139
1141{
1142 ATH_MSG_DEBUG("init_neighbors");
1143
1144 const std::vector<const IdDictRegion*>& vecOfDictRegions = dictRegions();
1145
1146 //
1147 // ..... loop on regions -> store vector of LArEM_region*
1148 //
1150 short int reg=0;
1151 std::vector<Identifier>::const_iterator debut=reg_begin() ;
1152 std::vector<Identifier>::const_iterator fin =reg_end() ;
1153 for (; debut != fin; ++debut) {
1154 const Identifier& regId = (*debut);
1155
1156 bool phiWrapAround = (dictionaryVersion() == "fullAtlas" );
1157 bool isBarrelMiddle = false;
1158
1159 //
1160 // ..... translate regId to chanId and get hash
1161 //
1162
1163 Identifier id ;
1164 unsigned int index0 = NOT_VALID_HASH;
1165 int etaMin = eta_min(regId);
1166 int phiMin = phi_min(regId);
1167 if(etaMin >= 0 && phiMin >= 0) {
1168 try{
1169 id = channel_id (regId, eta_min(regId), phi_min(regId) );
1170 }
1171 catch(LArID_Exception & except){
1172 ATH_MSG_ERROR("LArId exception " << (std::string)except);
1173 }
1174 IdentifierHash hashId = channel_hash (id) ;
1175 index0=hashId;
1176 }
1177 else {
1178 ATH_MSG_WARNING("could not find non negative etaMin and phiMin for region " << show_to_string(regId));
1179 index0 = 0;
1180 }
1181
1182 short int deltaEta = eta_max(regId) - eta_min(regId) + 1 ;
1183 short int nPhi = phi_max(regId) - phi_min(regId) + 1 ;
1184 // starting eta
1185 float eta0 = this->eta0(reg);
1186 // eta granularity
1187 float deta = etaGranularity(reg);
1188 // starting phi
1189 float phi0 = this->phi0(reg);
1190 // phi granularity
1191 float dphi = phiGranularity(reg);
1192
1193 // full range of regions
1194 unsigned int ireg0=0;
1195 unsigned int ireg1=region_hash_max();
1196 // if 2 symetric sides, in which side is the current reg.
1197 if(twoSymSides()) {
1198 if(reg < (short int)region_hash_max()/2) {
1199 ireg0=0;
1200 ireg1=region_hash_max()/2;
1201 } else {
1202 ireg0=region_hash_max()/2;
1203 ireg1=region_hash_max();
1204 }
1205 }
1206
1207 //
1208 // .... compute prev/next regions in eta
1209 //
1210 short int regForPrevEta=NOT_VALID_REGION;
1211 const IdDictRegion* prevEtaDicReg = vecOfDictRegions[reg]->prev_abs_eta();
1212 short int regForNextEta=NOT_VALID_REGION;
1213 const IdDictRegion* nextEtaDicReg = vecOfDictRegions[reg]->next_abs_eta();
1214 for(unsigned int ireg=ireg0;ireg<ireg1;ireg++){
1215 if(vecOfDictRegions[ireg] == prevEtaDicReg) regForPrevEta = ireg;
1216 if(vecOfDictRegions[ireg] == nextEtaDicReg) regForNextEta = ireg;
1217 }
1218 // .... special case of barrel middle
1219 if(twoSymSides()) {
1220 if(eta0 < 0.1 ) {
1221 isBarrelMiddle = true;
1222 if(barrel_ec(regId) < 0) {
1223 regForPrevEta = reg+6;
1224 } else {
1225 regForPrevEta = reg-6;
1226 }
1227 }
1228 }
1229
1230 //
1231 // .... compute prev/next regions in sampling
1232 //
1233 std::vector<short int> regForPrevSamp;
1234 for (const IdDictRegion* dictreg : vecOfDictRegions[reg]->prev_samp()) {
1235 for(unsigned int ireg=ireg0;ireg<ireg1;ireg++){
1236 if(vecOfDictRegions[ireg] == dictreg) regForPrevSamp.push_back(ireg);
1237 }
1238 }
1239
1240 std::vector<short int> regForNextSamp;
1241 for (const IdDictRegion* dictreg : vecOfDictRegions[reg]->next_samp()) {
1242 for(unsigned int ireg=ireg0;ireg<ireg1;ireg++){
1243 if(vecOfDictRegions[ireg] == dictreg) regForNextSamp.push_back(ireg);
1244 }
1245 }
1246
1247 //
1248 // .... compute prev/next regions in subdet
1249 //
1250 std::vector<short int> regForPrevSubdet;
1251 for (const IdDictRegion* dictreg : vecOfDictRegions[reg]->prev_subdet()) {
1252 for(unsigned int ireg=ireg0;ireg<ireg1;ireg++){
1253 if(vecOfDictRegions[ireg] == dictreg) regForPrevSubdet.push_back(ireg);
1254 }
1255 }
1256
1257 std::vector<short int> regForNextSubdet;
1258 for (const IdDictRegion* dictreg : vecOfDictRegions[reg]->next_subdet()) {
1259 for(unsigned int ireg=ireg0;ireg<ireg1;ireg++){
1260 if(vecOfDictRegions[ireg] == dictreg) regForNextSubdet.push_back(ireg);
1261 }
1262 }
1263
1264 //
1265 // ....now ready to build region object
1266 //
1267
1268 LArEM_region * emRegion = new LArEM_region(index0,deltaEta,nPhi,eta0,deta,phi0,dphi,phiWrapAround,isBarrelMiddle,
1269 regForPrevEta,regForNextEta,
1270 regForPrevSamp,regForNextSamp,
1271 regForPrevSubdet,regForNextSubdet);
1272 // save in a vector for further use in get_neighbours method
1273 // optimized nov 2005
1274 // m_vecOfRegions.push_back(emRegion);
1275 m_vecOfRegions[reg]=emRegion;
1276 reg++;
1277 } // end of loop on regions
1278
1279 //
1280 // ..... loop on channels
1281 //
1282 // optimized nov 2005
1283 m_cells.reserve(64);
1284 unsigned int i=0;
1285 reg=0;
1286 Identifier lastRegId;
1287 for (Identifier chanId : em_range()) {
1288 const Identifier& regId = region_id(chanId);
1289 if(regId != lastRegId) {
1290 m_cells.push_back(i);
1291 reg++;
1292 }
1293 ++i;
1294
1295 if(m_do_checks) {
1296 // for cross check only
1297 IdentifierHash hashReg = region_hash (regId) ;
1298 if ((short int)hashReg != reg) {
1299 ATH_MSG_ERROR("init_neighbors: problem reg, hashReg = " << reg << " " << hashReg);
1300 }
1301 }
1302
1303 lastRegId=regId;
1304 }
1305
1306 return (0);
1307}
1308
1309
1310
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)
Factor out code common between LArEM_ID and LArEM_SuperCell_ID.
@ NOT_VALID_REGION
Provide helper functions to create formatted strings.
#define min(a, b)
Definition cfImp.cxx:40
virtual std::string dictionaryVersion(void) const override
bool m_do_checks
Flag for subclasses to know whether or not to perform checks.
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.
ExpandedIdentifier lar_em_exp(void) const
LAr.
virtual void setDictVersion(const IdDictMgr &dict_mgr, const std::string &name) override
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.
int lar_em_field_value() const
size_type hash_max() const
Return one more than the largest hash code.
float phi0(const IdentifierHash regHash) const
Return the minimum phi of region, or NOT_VALID.
const HashGroup & regions() const
Return the HashGroup for regions.
float eta0(const IdentifierHash regHash) const
Return the minimum eta of region, or NOT_VALID.
const std::vector< const IdDictRegion * > & dictRegions() const
Return the vector of IdDictRegion, accessed via region hash.
float etaGranularity(const IdentifierHash regHash) const
Return the eta granularity of a region, or NOT_VALID.
size_type region_hash_max() const
One more than the largest region hash code.
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.
int fill_vec_of_dict_regions(const std::string &group_name="")
Initialize the list of detector regions.
float phiGranularity(const IdentifierHash regHash) const
Return the phi granularity of a region, or NOT_VALID.
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 add(element_type value)
Append a value into a new field.
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
IdDictGroup * find_group(const std::string &group_name)
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.
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.
small class holding the starting hash value, the min eta and the number of phi bins of each region
int get_prevInEta(const LArEM_region *emRegion, const unsigned int &index, const short int &nPhi, const float &gPhi, const unsigned int &minHash, int &neighbourIndex, IdentifierHash *neighbList, unsigned int &nBiggerCell) const
IdentifierHash region_hash(Identifier regionId) const
Convert a connected region Identifier to a hash code.
size_type m_REGION_INDEX
int region(const Identifier id) const
return region according to :
IdentifierHash channel_hash_binary_search(Identifier channelId) const
create hash id from channel id – method NOT optimised, please use channel_hash() above
std::vector< unsigned > m_cells
int eta(const Identifier id) const
return eta according to :
int eta_max(const Identifier regId) const
max value of eta index (-999 == failure)
size_type m_PHI_INDEX
Identifier region_id(const ExpandedIdentifier &exp_id) const
Build a cell identifier from an expanded identifier.
size_type m_SAMPLING_INDEX
int phi_max(const Identifier regId) const
max value of phi index (-999 == failure)
int eta_min(const Identifier regId) const
min value of eta index (-999 == failure)
id_range em_range() const
Range over full set of EM Identifiers.
void region_id_checks(int barrel_ec, int sampling, int region) const
bool is_supercell(const Identifier id) const
Test if the identifier represents a supercell.
IdDictFieldImplementation m_em_impl
int get_nextInSamp(const LArEM_region *emRegion, const unsigned int &index, const short int &nPhi, const unsigned int &minHash, const double &gEta, const float &gPhi, const double &absEta, int &neighbourIndex, IdentifierHash *neighbList) const
IdDictFieldImplementation m_phi_impl
size_type m_EM_INDEX
size_type m_LAR_INDEX
IdDictFieldImplementation m_sampling_impl
IdDictFieldImplementation m_region_impl
int get_prevInSamp(const LArEM_region *emRegion, const unsigned int &index, const short int &nPhi, const unsigned int &minHash, const double &gEta, const float &gPhi, const double &absEta, int &neighbourIndex, IdentifierHash *neighbList) const
size_type m_em_region_index
int initialize_base_from_dictionary(const IdDictMgr &dict_mgr, const std::string &group_name)
initialization from the identifier dictionary
std::vector< LArEM_region * > m_vecOfRegions
static int get_nextInPhi(const LArEM_region *emRegion, const unsigned int &index, const short int &nPhi, const unsigned int &minHash, int &neighbourIndex, IdentifierHash *neighbList)
int get_nextInEta(const LArEM_region *emRegion, const unsigned int &index, const short int &nPhi, const float &gPhi, const unsigned int &maxHash, int &neighbourIndex, IdentifierHash *neighbList, unsigned int &nBiggerCell) const
int get_prevInSubdet(const LArEM_region *emRegion, const unsigned int &index, const short int &nPhi, const unsigned int &minHash, const double &gEta, const float &gPhi, const double &absEta, int &neighbourIndex, IdentifierHash *neighbList) const
int phi(const Identifier id) const
return phi according to :
IdDictFieldImplementation m_lar_impl
virtual int get_expanded_id(const Identifier &id, ExpandedIdentifier &exp_id, const IdContext *context) const
create expanded Identifier from Identifier (return == 0 for OK)
int phi_min_init(const Identifier regId) const
size_type m_ETA_INDEX
int phi_min(const Identifier regId) const
min value of phi index (-999 == failure)
MultiRange m_full_em_range
static int get_prevInPhi(const LArEM_region *emRegion, const unsigned int &index, const short int &nPhi, const unsigned int &minHash, int &neighbourIndex, IdentifierHash *neighbList)
IdDictFieldImplementation m_bec_impl
size_type m_SLAR_INDEX
MultiRange m_full_region_range
Identifier channel_id(const ExpandedIdentifier &exp_id) const
Build a cell identifier from an expanded identifier.
size_type m_BEC_INDEX
std::vector< int > m_vecOfPhiMin
std::vector< HashCalc > m_hash_calcs
IdDictFieldImplementation m_slar_impl
void channel_id_checks(int barrel_ec, int sampling, int region, int eta, int phi) const
id_iterator reg_end() const
end iterator over set of Region Identifiers
IdDictFieldImplementation m_bec_reg_impl
bool twoSymSides() const
True if the + and - sides of the calorimeter are identical (true layout).
IdDictFieldImplementation m_eta_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 = prevInPhi,...
int barrel_ec(const Identifier id) const
return barrel_ec according to :
int sampling(const Identifier id) const
return sampling according to :
int get_nextInSubdet(const LArEM_region *emRegion, const unsigned int &index, const short int &nPhi, const unsigned int &minHash, const double &gEta, const float &gPhi, const double &absEta, int &neighbourIndex, IdentifierHash *neighbList) const
id_iterator reg_begin() const
begin iterator over set of Region Identifiers
IdentifierHash channel_hash(Identifier channelId) const
create hash id from channel id
int initLevelsFromDict(const std::string &group_name)
LArEM_Base_ID(const std::string &name, const std::string &group, bool supercell)
Constructor.
This class provides an interface to deal with regions in the neighbours finding.
float phiGranularity() const
phi granularity
const std::vector< short int > & prevSamplingRegion() const
region number of the prev region in sampling
const std::vector< short int > & nextSubdetRegion() const
region number of the next region in subdet
short int nextEtaRegion() const
region number of the next region in eta
bool isEtaMax(unsigned int index) const
is the considered cell in the last eta bin of the region ?
unsigned int hashMax() const
hash Id of the last cell of the region +1
short int prevEtaRegion() const
region number of the previous region in eta
float etaGranularity() const
eta granularity
float etaMax() const
end eta
const std::vector< short int > & nextSamplingRegion() const
region number of the next region in sampling
unsigned int hashMin() const
hash Id of the first cell of the region
const std::vector< short int > & prevSubdetRegion() const
region number of the prev region in subdet
bool isFirstBarrelRegion() const
true if region close to barrel middle
float etaMin() const
starting eta
float phiMin() const
starting phi
bool isPhiMin(unsigned int index) const
is the considered cell in the first phi bin of the region ?
short int phiN() const
number of phi bins
bool isEtaMin(unsigned int index) const
is the considered cell in the first eta bin of the region ?
bool isPhiMax(unsigned int index) const
is the considered cell in the last phi bin of the region ?
Exception class for LAr Identifiers.
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 index.py:1
Tell the compiler to optimize assuming that FP may trap.
#define CXXUTILS_TRAPPING_FP
Definition trapping_fp.h:24