ATLAS Offline Software
Loading...
Searching...
No Matches
GTowersFromGCaloTowers.cxx
Go to the documentation of this file.
1
4
9#include <memory>
10#include <cmath>
11
12namespace
13{
14 const static SG::AuxElement::ConstAccessor<float> accArea("area");
15 const static SG::AuxElement::Decorator<float> decArea("area");
16 const static SG::AuxElement::ConstAccessor<std::size_t> accNextEtaIndex("nextEtaIndex");
17 const static SG::AuxElement::ConstAccessor<std::size_t> accPreviousEtaIndex("previousEtaIndex");
18 const static SG::AuxElement::ConstAccessor<std::size_t> accNextPhiIndex("nextPhiIndex");
19 const static SG::AuxElement::ConstAccessor<std::size_t> accPreviousPhiIndex("previousPhiIndex");
20 const static SG::AuxElement::ConstAccessor<std::size_t> accIndexInFront("indexInFront");
21 const static SG::AuxElement::ConstAccessor<std::size_t> accIndexBehind("indexBehind");
22 const static SG::AuxElement::Decorator<std::size_t> decNextEtaIndex("nextEtaIndex");
23 const static SG::AuxElement::Decorator<std::size_t> decPreviousEtaIndex("previousEtaIndex");
24 const static SG::AuxElement::Decorator<std::size_t> decNextPhiIndex("nextPhiIndex");
25 const static SG::AuxElement::Decorator<std::size_t> decPreviousPhiIndex("previousPhiIndex");
26 const static SG::AuxElement::Decorator<std::size_t> decIndexInFront("indexInFront");
27 const static SG::AuxElement::Decorator<std::size_t> decIndexBehind("indexBehind");
28 const static SG::AuxElement::Decorator<std::vector<std::size_t>> decMergedIndices("mergedIndices");
29
30 std::size_t getRemappedIndex(const std::map<std::size_t, std::size_t> &remap, std::size_t originalIdx)
31 {
32 auto itr = remap.find(originalIdx);
33 return itr == remap.end() ? SIZE_MAX : itr->second;
34 }
35} // namespace
36
37namespace LVL1
38{
39 GTowersFromGCaloTowers::GTowersFromGCaloTowers(const std::string &name, ISvcLocator *pSvcLocator)
40 : AthReentrantAlgorithm(name, pSvcLocator)
41 {
42 declareProperty("InputTowers", m_inputKey = "GTower");
43 declareProperty("OutputTowers", m_outputKey = "GCaloTower");
44 declareProperty("MergeEdgeTowers", m_mergeEdgeTowers = true);
45 }
46
48
50 {
51 ATH_CHECK(m_inputKey.initialize());
52 ATH_CHECK(m_outputKey.initialize());
53 ATH_CHECK(m_mappingKey.initialize());
54 ATH_CHECK(detStore()->retrieve(m_gTowerID));
55 return StatusCode::SUCCESS;
56 }
57
58 StatusCode GTowersFromGCaloTowers::execute(const EventContext &ctx) const
59 {
60 auto inputTowers = SG::makeHandle(m_inputKey, ctx);
61 if (!inputTowers.isValid())
62 {
63 ATH_MSG_ERROR("Failed to retrieve input towers " << m_inputKey.key());
64 return StatusCode::FAILURE;
65 }
66
67 auto outputTowers = std::make_unique<xAOD::JGTowerContainer>();
68 auto outputTowersAux = std::make_unique<xAOD::JGTowerAuxContainer>();
69 outputTowers->setStore(outputTowersAux.get());
70
71 // Get the helpers
73 if (!mapping.isValid())
74 {
75 ATH_MSG_ERROR("Failed to retrieve mapping " << m_mappingKey);
76 return StatusCode::FAILURE;
77 }
78 const std::vector<JGTowerHelper> &helpers = **mapping;
79
80 std::map<std::size_t, std::size_t> indexRemap;
81
82 for (const xAOD::JGTower *tower : *inputTowers)
83 {
84 const JGTowerHelper &helper = helpers.at(tower->Id());
85 if (!helper.isFrontTower())
86 // Avoid double counting by only taking the front tower in any given eta/phi slice
87 continue;
88 Identifier towerID = m_gTowerID->tower_id(tower->Id());
89 // The forward towers don't have valid tower IDs so we can't trust this
90 // information for those towers. This becomes obvious as the hash of the
91 // ID is wrong
92 bool isForward = m_gTowerID->tower_hash(towerID) != std::size_t(tower->Id());
93 int iRegion = m_gTowerID->region(towerID);
94 if (m_mergeEdgeTowers && iRegion == 1 && !isForward)
95 // region 1 is the 2.4-2.5 region
96 // There used to be a region 3, but we have just absorbed this into the FCAL towers
97 continue;
98 indexRemap[tower->index()] = outputTowers->size();
99 std::vector<int> SCIndex = tower->SCIndex();
100 std::vector<int> tileIndex = tower->TileIndex();
101 float totalEt = tower->et();
102 std::size_t nextTowerIdx = accIndexBehind(*tower);
103 float area = accArea(*tower);
104 float eta = tower->eta();
105 std::size_t nextEtaIndex = accNextEtaIndex(*tower);
106 std::size_t previousEtaIndex = accPreviousEtaIndex(*tower);
107 std::vector<std::size_t> mergedIndices{tower->index()};
108 while (nextTowerIdx != SIZE_MAX)
109 {
110 const xAOD::JGTower *nextTower = inputTowers->at(nextTowerIdx);
111 totalEt += nextTower->et();
112 SCIndex.insert(SCIndex.end(), nextTower->SCIndex().begin(), nextTower->SCIndex().end());
113 tileIndex.insert(tileIndex.end(), nextTower->TileIndex().begin(), nextTower->TileIndex().end());
114 mergedIndices.push_back(nextTowerIdx);
115 nextTowerIdx = helpers.at(nextTower->Id()).indexBehind();
116 }
118 {
119 Identifier regionID = m_gTowerID->region_id(towerID);
120 if (!isForward && m_gTowerID->region(towerID) == 0 && m_gTowerID->eta(towerID) == m_gTowerID->eta_max(regionID))
121 {
122 if (tower->eta() > 0)
123 {
124 nextTowerIdx = nextEtaIndex;
125 const xAOD::JGTower *nextTower = inputTowers->at(nextTowerIdx);
126 // Now we need to correct the eta index that we will write out
127 nextEtaIndex = accNextEtaIndex(*nextTower);
128 }
129 else
130 {
131 nextTowerIdx = previousEtaIndex;
132 const xAOD::JGTower *nextTower = inputTowers->at(nextTowerIdx);
133 // Now we need to correct the eta index that we will write out
134 previousEtaIndex = accPreviousEtaIndex(*nextTower);
135 }
136 indexRemap[nextTowerIdx] = outputTowers->size();
137 while (nextTowerIdx != SIZE_MAX)
138 {
139 const xAOD::JGTower *nextTower = inputTowers->at(nextTowerIdx);
140 if (helpers.at(nextTowerIdx).isFrontTower())
141 {
142 area += accArea(*nextTower);
143 eta += std::copysign(nextTower->deta() / 2, eta);
144 }
145 totalEt += nextTower->et();
146 SCIndex.insert(SCIndex.end(), nextTower->SCIndex().begin(), nextTower->SCIndex().end());
147 tileIndex.insert(tileIndex.end(), nextTower->TileIndex().begin(), nextTower->TileIndex().end());
148 mergedIndices.push_back(nextTowerIdx);
149 nextTowerIdx = helpers.at(nextTower->Id()).indexBehind();
150 }
151 }
152 }
153 // Now create the new tower
154 xAOD::JGTower *newTower = new xAOD::JGTower();
155 outputTowers->push_back(newTower);
156 // Copy auxdata from the old tower to this one
157 *newTower = *tower;
158 decArea(*newTower) = area;
159 // override the et and indices.
160 newTower->setEt(totalEt);
161 newTower->setEta(eta);
162 // NB - in the old code these indices get set to the fairly meaningless [0, 0].
163 // I've decied to set this to the union of the indices of the towers forming the gCaloTowers
164 newTower->setSCIndex(SCIndex);
165 newTower->setTileIndex(tileIndex);
166 // Now no towers in front or behind
167 decIndexInFront(*newTower) = SIZE_MAX;
168 decIndexBehind(*newTower) = SIZE_MAX;
169 decNextEtaIndex(*newTower) = nextEtaIndex;
170 decPreviousEtaIndex(*newTower) = previousEtaIndex;
171 decMergedIndices(*newTower) = std::move(mergedIndices);
172 }
173
174 // Remap the relational indices
175 for (xAOD::JGTower *tower : *outputTowers)
176 {
177 decNextEtaIndex(*tower) = getRemappedIndex(indexRemap, accNextEtaIndex(*tower));
178 decPreviousEtaIndex(*tower) = getRemappedIndex(indexRemap, accPreviousEtaIndex(*tower));
179 decNextPhiIndex(*tower) = getRemappedIndex(indexRemap, accNextPhiIndex(*tower));
180 decPreviousPhiIndex(*tower) = getRemappedIndex(indexRemap, accPreviousPhiIndex(*tower));
181 }
182
183 auto outputHandle = SG::makeHandle(m_outputKey, ctx);
184 ATH_CHECK(outputHandle.record(std::move(outputTowers), std::move(outputTowersAux)));
185 return StatusCode::SUCCESS;
186 }
187} // namespace LVL1
Scalar eta() const
pseudorapidity method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
double area(double R)
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ServiceHandle< StoreGateSvc > & detStore() const
An algorithm that can be simultaneously executed in multiple threads.
virtual StatusCode initialize() override
SG::WriteHandleKey< xAOD::JGTowerContainer > m_outputKey
GTowersFromGCaloTowers(const std::string &name, ISvcLocator *pSvcLocator)
SG::ReadHandleKey< xAOD::JGTowerContainer > m_inputKey
SG::ReadCondHandleKey< JGTowerMappingData > m_mappingKey
virtual StatusCode execute(const EventContext &ctx) const override
SG::ConstAccessor< T, ALLOC > ConstAccessor
Definition AuxElement.h:569
SG::Decorator< T, ALLOC > Decorator
Definition AuxElement.h:575
const std::vector< int > & SCIndex() const
get SCIndex
virtual double et() const final
void setSCIndex(const std::vector< int > &)
set SCIndex
void setEt(float)
void setTileIndex(const std::vector< int > &)
set TileIndex
virtual double deta() const final
The pseudorapidity ( ) of the particle.
void setEta(float)
virtual int Id() const final
get coolId
const std::vector< int > & TileIndex() const
get TileIndex
std::map< std::string, std::string > remap
list of directories to be explicitly remapped
Definition hcg.cxx:95
eFexTowerBuilder creates xAOD::eFexTowerContainer from supercells (LATOME) and triggerTowers (TREX) i...
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
JGTower_v1 JGTower
Define the latest version of the JGTower class.
Definition JGTower.h:15