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