ATLAS Offline Software
Loading...
Searching...
No Matches
JGTowerMappingDataCondAlgBase.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
8#include "CaloDetDescr/CaloDetDescrElement.h"
9#include "TMath.h"
10#include "TVector2.h"
11#include <memory>
12#include <map>
13#include <tuple>
14#include <algorithm>
15
16namespace LVL1
17{
18 JGTowerMappingDataCondAlgBase::JGTowerMappingDataCondAlgBase(const std::string &name, ISvcLocator *pSvcLocator)
19 : AthCondAlgorithm(name, pSvcLocator)
20 {
21 }
22
24
26 {
27 ATH_CHECK(m_outputKey.initialize());
28 ATH_CHECK(m_caloSuperCellMgrKey.initialize());
29 ATH_CHECK(detStore()->retrieve(m_ccid));
30 ATH_CHECK(detStore()->retrieve(m_scid));
31 return StatusCode::SUCCESS;
32 }
33
34 StatusCode JGTowerMappingDataCondAlgBase::execute(const EventContext &ctx) const
35 {
37 if (outputHandle.isValid())
38 {
39 // In serial athena conditions algorithms are run on every event.
40 // Therefore return early if the output object already exists.
41 return StatusCode::SUCCESS;
42 }
43 const JGTowerBase_ID *jgTowerID = getJGTowerID();
45 const CaloSuperCellDetDescrManager *scDetMgr = *caloSuperCellMgrHandle;
46 // JGTowerMappingData is typedef of std::vector<JGTowerHelper>
47 auto data = std::make_unique<JGTowerMappingData>();
48
49 // Store the towers in a map by their location to identify ones which are in front/behind each other
50 // tuple elements: pos_neg, region, eta, phi
51 std::map<std::tuple<int, int, int, int>, std::vector<std::size_t>> towerGrid;
52 // For speed later, also store the max phi index and min/max eta indices per (int) region code
53 std::map<int, std::tuple<int, int, int>> regionParams;
54
55 for (std::size_t towerIdx = 0; towerIdx < jgTowerID->tower_hash_max(); ++towerIdx)
56 {
57 Identifier towerID = jgTowerID->tower_id(towerIdx);
58 Identifier regionID = jgTowerID->region_id(towerID);
59
60 int detSide = jgTowerID->pos_neg(towerID) < 0 ? -1 : +1;
61
62 // Get the phi and eta boundaries of the towers (only advisable for barrel)
63 float jDEta = jgTowerID->etaGranularity(regionID);
64 float jDPhi = jgTowerID->phiGranularity(regionID);
65 int nTowers = (int)std::ceil(TMath::Pi() / jDPhi);
66 jDPhi = TMath::Pi() / nTowers;
67
68 float jEta = detSide * ((jgTowerID->eta(towerID) + 0.5) * jDEta + jgTowerID->eta0(regionID));
69 float jPhi = TVector2::Phi_mpi_pi((jgTowerID->phi(towerID) + 0.5) * jDPhi + jgTowerID->phi0(regionID));
70
71 data->emplace_back(jEta, jDEta, jPhi, jDPhi);
72 JGTowerHelper &helper = data->back();
73 helper.SetSampling(jgTowerID->sampling(towerID));
74
75 std::vector<std::size_t> &gridLoc = towerGrid[std::make_tuple(
76 jgTowerID->pos_neg(towerID),
77 jgTowerID->region(towerID),
78 jgTowerID->eta(towerID),
79 jgTowerID->phi(towerID))];
80 regionParams[jgTowerID->region(towerID)] = std::make_tuple(
81 jgTowerID->phi_max(regionID),
82 jgTowerID->eta_min(regionID),
83 jgTowerID->eta_max(regionID));
84
85 // Now insert our index into this such that the vector remains sorted in ascending order of sampling
86 gridLoc.insert(std::lower_bound(
87 gridLoc.begin(), gridLoc.end(), towerIdx,
88 [&data](std::size_t lhs, std::size_t rhs) { return data->at(lhs).sampling() < data->at(rhs).sampling(); }),
89 towerIdx);
90
91 for (std::size_t scIdx = 0; scIdx < m_scid->calo_cell_hash_max(); ++scIdx)
92 {
93 Identifier scID = m_scid->cell_id(scIdx);
94 const CaloDetDescrElement *dde = scDetMgr->get_element(scID);
95 if (!dde)
96 {
97 ATH_MSG_ERROR("Error loading CaloDetDescrElement");
98 return StatusCode::FAILURE;
99 }
100 if (m_scid->is_tile(scID) && m_scid->sampling(scID) != 2)
101 {
102 if (!m_mapTileCells)
103 continue;
104 if (jgTowerID->sampling(towerID) != 0 && helper.inBox(dde->eta_raw(), dde->phi_raw()))
105 helper.SetTileIndices(scIdx);
106 }
107 else
108 {
109 float superCellEta = dde->eta_raw();
110 // Treat forward super cells separately
111 if (std::abs(superCellEta) > 3.2)
112 continue;
113 // Very special case being handle here. At the end of the barrel there is a constant-eta ring that has
114 // eta_raw=1.4 (which is the midpoint of the scell). These will be put into the g/jTower that starts at eta=1.4
115 if (std::abs(std::abs(superCellEta) - 1.4) < 0.001 &&
116 m_scid->region(scID) == 0 &&
117 m_scid->sampling(scID) == 2)
118 superCellEta += (superCellEta > 0 ? 0.05 : -0.05);
119 if (helper.inBox(superCellEta, dde->phi_raw()) &&
120 jgTowerID->pos_neg(towerID) * m_scid->pos_neg(scID) > 0 &&
121 ((m_scid->is_em(scID) && jgTowerID->sampling(towerID) == 0) ||
122 (!m_scid->is_em(scID) && jgTowerID->sampling(towerID) == 1)))
123 helper.SetSCIndices(scIdx);
124 }
125 } //> end loop over SC indices
126 } //> end loop over tower IDs
127
128 for (auto &gridLocPair : towerGrid)
129 {
130 std::vector<std::size_t> &towerIndices = gridLocPair.second;
131 // Figure out the relations to this square in the grid
132 int pos_neg = std::get<0>(gridLocPair.first);
133 int region = std::get<1>(gridLocPair.first);
134 int iEta = std::get<2>(gridLocPair.first);
135 int iPhi = std::get<3>(gridLocPair.first);
136 int phiMax = std::get<0>(regionParams[region]);
137 int etaMin = std::get<1>(regionParams[region]);
138 int etaMax = std::get<2>(regionParams[region]);
139 auto nextPhiItr = towerGrid.find(std::make_tuple(pos_neg, region, iEta, iPhi == phiMax ? 0 : iPhi + 1));
140 auto prevPhiItr = towerGrid.find(std::make_tuple(pos_neg, region, iEta, iPhi == 0 ? phiMax : iPhi - 1));
141 auto nextEtaItr = towerGrid.end();
142 auto prevEtaItr = towerGrid.end();
143 // We want 'next' and 'prev' to refer to increasing eta, not increasing |eta|
144 // Increasing 'region' increases |eta| so in what follows we correct for this by
145 // choosing whether we set nextEtaItr or prevEtaItr based on the sign of pos_neg
146 if (iEta == etaMax)
147 {
148 // Check if the next region a) exists and b) has the right phi granularity
149 auto itr = regionParams.find(region + 1);
150 if (itr != regionParams.end() && std::get<0>(itr->second) == phiMax)
151 // Set the next eta index to the next region and the eta_min index of that region (probably 0)
152 (pos_neg > 0 ? nextEtaItr : prevEtaItr) = towerGrid.find(std::make_tuple(pos_neg, region + 1, std::get<1>(itr->second), iPhi));
153 }
154 else
155 (pos_neg > 0 ? nextEtaItr : prevEtaItr) = towerGrid.find(std::make_tuple(pos_neg, region, iEta + 1, iPhi));
156 if (iEta == etaMin)
157 {
158 if (region == 0)
159 (pos_neg > 0 ? prevEtaItr : nextEtaItr) = towerGrid.find(std::make_tuple(pos_neg * -1, region, iEta, iPhi));
160 else
161 {
162 auto itr = regionParams.find(region - 1);
163 if (itr != regionParams.end() && std::get<0>(itr->second) == phiMax)
164 // Set the previous eta index to the previous region and the eta_max index of that region
165 (pos_neg > 0 ? prevEtaItr : nextEtaItr) = towerGrid.find(std::make_tuple(pos_neg, region - 1, std::get<2>(itr->second), iPhi));
166 }
167 }
168 else
169 (pos_neg > 0 ? prevEtaItr : nextEtaItr) = towerGrid.find(std::make_tuple(pos_neg, region, iEta - 1, iPhi));
170
171 std::vector<std::size_t> nextEtaTowers;
172 std::vector<std::size_t> prevEtaTowers;
173 std::vector<std::size_t> nextPhiTowers;
174 std::vector<std::size_t> prevPhiTowers;
175 if (nextEtaItr != towerGrid.end())
176 nextEtaTowers = nextEtaItr->second;
177 if (prevEtaItr != towerGrid.end())
178 prevEtaTowers = prevEtaItr->second;
179 if (nextPhiItr != towerGrid.end())
180 nextPhiTowers = nextPhiItr->second;
181 if (prevPhiItr != towerGrid.end())
182 prevPhiTowers = prevPhiItr->second;
183 nextEtaTowers.resize(towerIndices.size(), SIZE_MAX);
184 prevEtaTowers.resize(towerIndices.size(), SIZE_MAX);
185 nextPhiTowers.resize(towerIndices.size(), SIZE_MAX);
186 prevPhiTowers.resize(towerIndices.size(), SIZE_MAX);
187
188 std::size_t previousIdx = SIZE_MAX;
189 for (std::size_t iIdx = 0; iIdx < towerIndices.size(); ++iIdx)
190 {
191 // NB: iIdx here is an index of _indices_, i.e. the position in the towerIndex
192 // vector as well as the next/prev eta/phi towers vectors
193 std::size_t currentIdx = towerIndices.at(iIdx);
194 JGTowerHelper &helper = data->at(currentIdx);
195
196 helper.setNextEtaIndex(nextEtaTowers.at(iIdx));
197 helper.setPreviousEtaIndex(prevEtaTowers.at(iIdx));
198 helper.setNextPhiIndex(nextPhiTowers.at(iIdx));
199 helper.setPreviousPhiIndex(prevPhiTowers.at(iIdx));
200
201 helper.setIndexInFront(previousIdx);
202 if (previousIdx != SIZE_MAX)
203 data->at(previousIdx).setIndexBehind(currentIdx);
204 previousIdx = currentIdx;
205 }
206 }
207
210
211 // Set this object to be valid for every event
213 ATH_CHECK(outputHandle.record(std::move(data)));
214
215 return StatusCode::SUCCESS;
216 }
217} // namespace LVL1
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
const ServiceHandle< StoreGateSvc > & detStore() const
Base class for conditions algorithms.
This class groups all DetDescr information related to a CaloCell.
const CaloDetDescrElement * get_element(const Identifier &cellId) const
get element by its identifier
static EventIDRange infiniteRunLB()
Produces an EventIDRange that is infinite in RunLumi and invalid in Time.
int sampling(const Identifier id) const
return sampling according to :
float eta0(const Identifier regId) const
Return the minimum eta of region, or NOT_VALID.
int eta_max(const Identifier regId) const
max value of eta index (-999 == failure)
int region(const Identifier id) const
return region according to :
size_type tower_hash_max() const
tower hash table max size
int eta_min(const Identifier regId) const
min value of eta index (-999 == failure)
int pos_neg(const Identifier id) const
Test wether given tower or layer is part of the Tile Calorimeter.
float phiGranularity(const Identifier regId) const
Return the phi granularity of a region, or NOT_VALID.
int phi_max(const Identifier regId) const
min value of phi index (-999 == failure)
int phi(const Identifier id) const
return phi according to :
Identifier tower_id(int pos_neg, int sampling, int region, int eta, int phi) const
build a tower identifier
Identifier region_id(int pos_neg, int sampling, int region) const
build a region (of towers) identifier
float etaGranularity(const Identifier regId) const
Return the eta granularity of a region, or NOT_VALID.
float phi0(const Identifier regId) const
Return the minimum phi of region, or NOT_VALID.
int eta(const Identifier id) const
return eta according to :
virtual StatusCode buildForwardMapping(JGTowerMappingData &data, const CaloSuperCellDetDescrManager *mgr) const =0
SG::ReadCondHandleKey< CaloSuperCellDetDescrManager > m_caloSuperCellMgrKey
virtual const JGTowerBase_ID * getJGTowerID() const =0
JGTowerMappingDataCondAlgBase(const std::string &name, ISvcLocator *pSvcLocator)
SG::WriteCondHandleKey< JGTowerMappingData > m_outputKey
virtual StatusCode loadTowerAreas(JGTowerMappingData &data) const =0
virtual StatusCode execute(const EventContext &ctx) const final
void addDependency(const EventIDRange &range)
StatusCode record(const EventIDRange &range, T *t)
record handle, with explicit range DEPRECATED
eFexTowerBuilder creates xAOD::eFexTowerContainer from supercells (LATOME) and triggerTowers (TREX) i...