ATLAS Offline Software
Loading...
Searching...
No Matches
JTowerRhoSubtractionAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
10#include <memory>
11#include <numeric>
12#include <TFile.h>
13#include <TH1.h>
15#include "GaudiKernel/SystemOfUnits.h"
18
19namespace
20{
21 const static SG::AuxElement::ConstAccessor<float> accArea("area");
22 const static SG::AuxElement::Decorator<std::vector<float>> decRhos("rhoValues");
23 std::vector<std::size_t> createVectorFromRanges(const std::vector<std::pair<std::size_t, std::size_t>> &ranges)
24 {
25 // Work out the size
26 std::size_t total = 0;
27 for (const std::pair<std::size_t, std::size_t> &range : ranges)
28 total += (range.second - range.first);
29 std::vector<std::size_t> result(total);
30 auto startItr = result.begin();
31 auto endItr = result.begin();
32 for (const std::pair<std::size_t, std::size_t> &range : ranges)
33 {
34 startItr = endItr;
35 endItr = startItr + (range.second - range.first);
36 std::iota(startItr, endItr, range.first);
37 }
38 return result;
39 }
40
41 std::vector<std::size_t> findBinNumbers(
42 float eta, float phi,
43 const std::vector<std::pair<float, float>> &etaBins,
44 const std::vector<std::pair<float, float>> &phiBins,
45 float phiOffset)
46 {
47 std::vector<std::size_t> binNumbers;
48 std::size_t iBin = 0;
49 phi = TVector2::Phi_0_2pi(phi - phiOffset);
50 for (const std::pair<float, float> &etaBin : etaBins)
51 {
52 for (const std::pair<float, float> &phiBin : phiBins)
53 {
54 if (etaBin.first < eta && eta < etaBin.second)
55 {
56 if (phiBin.first < phi && phi < phiBin.second)
57 binNumbers.push_back(iBin);
58 }
59 ++iBin;
60 }
61 }
62 return binNumbers;
63 }
64} // namespace
65
66namespace LVL1
67{
68 JTowerRhoSubtractionAlg::JTowerRhoSubtractionAlg(const std::string &name, ISvcLocator *pSvcLocator)
69 : AthReentrantAlgorithm(name, pSvcLocator)
70 {
71 declareProperty("InputTowers", m_inputKey = "JTower");
72 declareProperty("OutputTowers", m_outputKey = "JTowerRhoSubtracted");
73 declareProperty("OutputRho", m_outputRhoKey = "JFEXRho");
74 declareProperty("MinTowerRho", m_minTowerRho = 0.0, "Minimum tower rho to enter the calculation of bin rho");
75 declareProperty("MaxTowerRho", m_maxTowerRho = 1.0 * Gaudi::Units::GeV, "Maximum tower rho to enter the calculation of bin rho");
76 declareProperty("MinOutputTowerRho", m_minOutputTowerRho = 100 * Gaudi::Units::MeV, "Minimum tower rho to be output (below this set 0)");
77 }
78
80
82 {
83 ATH_CHECK(m_inputKey.initialize());
84 ATH_CHECK(m_outputKey.initialize());
85 ATH_CHECK(m_outputRhoKey.initialize());
86 return StatusCode::SUCCESS;
87 }
88
91 {
93
94 // Create the bin lists as a list of tower indices
95 // eta bins
96 std::vector<std::pair<float, float>> etaBins{
97 {-1.6, 0.8},
98 {-0.8, 1.6},
99 {-2.4, 0.0},
100 {0.0, 2.4},
101 {-4.9, -0.8},
102 {0.8, 4.9}};
103 std::vector<std::pair<float, float>> etaBinsCore{
104 {-0.8, 0.0},
105 {0.0, 0.8},
106 {-1.6, -0.8},
107 {0.8, 1.6},
108 {-4.9, -1.6},
109 {1.6, 4.9}};
110 // phi bins (in multiples of pi)
111 std::vector<std::pair<float, float>> phiBins{
112 {0.0, TMath::Pi()}, {TMath::Pi(), 2 * TMath::Pi()}};
113 float phiOffset = 0.25 * TMath::Pi();
114
115 std::size_t nBins = etaBins.size() * phiBins.size();
116
117 std::vector<std::size_t> EMTowers = createVectorFromRanges(
118 {{1, 1696}, {3392, 5088}, {6784, 6816}, {6848, 6880}, {6912, 6976}});
119 std::vector<std::size_t> hadTowers = createVectorFromRanges(
120 {{1696, 3392}, {5088, 6784}, {6816, 6848}, {6880, 6912}});
121 std::vector<std::size_t> FCALTowers = createVectorFromRanges({{6976, 7744}});
122
123 // Split the hadronic calorimeter into 3 regions
124 std::vector<std::size_t> had1Towers;
125 std::vector<std::size_t> had2Towers;
126 std::vector<std::size_t> had3Towers;
127 for (std::size_t idx : hadTowers)
128 {
129 float eta = std::abs(towers->at(idx)->eta());
130 if (eta < 1.5)
131 had1Towers.push_back(idx);
132 else if (eta < 1.6)
133 had2Towers.push_back(idx);
134 else
135 had3Towers.push_back(idx);
136 }
137
138 // Create the necessary regions
139 std::vector<std::vector<std::size_t>> regions;
140 regions.reserve(5);
141 regions.push_back(std::move(had1Towers));
142 regions.push_back(std::move(had2Towers));
143 regions.push_back(std::move(had3Towers));
144 regions.push_back(std::move(EMTowers));
145 regions.push_back(std::move(FCALTowers));
146
147 bins.m_bins.resize(regions.size() * nBins);
148 bins.m_binsCore.resize(regions.size() * nBins);
149
150 for (std::size_t regionIdx = 0; regionIdx < regions.size(); ++regionIdx)
151 {
152 for (std::size_t towerIdx : regions.at(regionIdx))
153 {
154 const xAOD::JGTower &tower = *towers->at(towerIdx);
155 for (std::size_t binIdx : findBinNumbers(tower.eta(), tower.phi(), etaBins, phiBins, phiOffset))
156 bins.m_bins.at(binIdx + regionIdx * nBins).push_back(towerIdx);
157 for (std::size_t binIdx : findBinNumbers(tower.eta(), tower.phi(), etaBinsCore, phiBins, phiOffset))
158 bins.m_binsCore.at(binIdx + regionIdx * nBins).push_back(towerIdx);
159 }
160 }
161
162 // If any core bin is empty, also empty the corresponding larger bin
163 for (std::size_t binIdx = 0; binIdx < bins.m_bins.size(); ++binIdx)
164 if (bins.m_binsCore.at(binIdx).size() == 0)
165 bins.m_bins.at(binIdx).clear();
166
167 return bins;
168 }
169
170 StatusCode JTowerRhoSubtractionAlg::execute(const EventContext &ctx) const
171 {
172 auto inputTowers = SG::makeHandle(m_inputKey, ctx);
173 if (!inputTowers.isValid())
174 {
175 ATH_MSG_ERROR("Failed to retrieve " << m_inputKey.key());
176 return StatusCode::FAILURE;
177 }
178 auto shallowCopy = xAOD::shallowCopyContainer(*inputTowers);
179 std::unique_ptr<xAOD::JGTowerContainer> outputTowers(shallowCopy.first);
180 std::unique_ptr<xAOD::ShallowAuxContainer> outputTowersAux(shallowCopy.second);
181 xAOD::setOriginalObjectLink(*inputTowers, *outputTowers);
182
183 static const JFEXBins jFEXBins = buildFexBins (inputTowers.cptr());
184
185 // Iterate over the bins and calculate the average energy in the towers
186 std::vector<float> rhos;
187 rhos.reserve(jFEXBins.m_bins.size());
188 for (const std::vector<std::size_t> &binTowerIndices : jFEXBins.m_bins)
189 {
190 std::size_t count = 0;
191 float rhoSum = 0;
192 for (std::size_t towerIdx : binTowerIndices)
193 {
194 const xAOD::JGTower *tower = inputTowers->at(towerIdx);
195 float area = accArea(*tower);
196 float towerRho = tower->et() / area;
197 if (towerRho > m_minTowerRho && towerRho <= m_maxTowerRho)
198 {
199 ++count;
200 rhoSum += towerRho;
201 }
202 }
203 if (count == 0)
204 rhos.push_back(0);
205 else
206 rhos.push_back(rhoSum / count);
207 }
208
209 std::vector<float> subtractedTowerEnergies(inputTowers->size(), 0.0);
210 for (std::size_t binIdx = 0; binIdx < jFEXBins.m_binsCore.size(); ++binIdx)
211 {
212 for (std::size_t towerIdx : jFEXBins.m_binsCore.at(binIdx))
213 {
214 const xAOD::JGTower *tower = inputTowers->at(towerIdx);
215 float area = accArea(*tower);
216 float etSub = tower->et() - rhos.at(binIdx) * area;
217 if (etSub < area * m_minOutputTowerRho)
218 etSub = 0;
219 subtractedTowerEnergies.at(towerIdx) = etSub;
220 }
221 }
222 for (std::size_t idx = 0; idx < subtractedTowerEnergies.size(); ++idx)
223 outputTowers->at(idx)->setEt(subtractedTowerEnergies.at(idx));
224
225 auto outputHandle = SG::makeHandle(m_outputKey, ctx);
226
227 ATH_CHECK(outputHandle.record(std::move(outputTowers), std::move(outputTowersAux)));
228
229 // Create an EnergySumRoI container to store the rho values
230 auto rhoCont = std::make_unique<xAOD::EnergySumRoI>();
231 auto rhoContAux = std::make_unique<xAOD::EnergySumRoIAuxInfo>();
232 rhoCont->setStore(rhoContAux.get());
233 decRhos(*rhoCont) = std::move(rhos);
234 auto outputRhoHandle = SG::makeHandle(m_outputRhoKey, ctx);
235 ATH_CHECK(outputRhoHandle.record(std::move(rhoCont), std::move(rhoContAux)));
236 return StatusCode::SUCCESS;
237 }
238} // namespace LVL1
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
double area(double R)
static const std::vector< std::string > bins
static const std::vector< std::string > regions
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
An algorithm that can be simultaneously executed in multiple threads.
SG::ReadHandleKey< xAOD::JGTowerContainer > m_inputKey
JFEXBins buildFexBins(const xAOD::JGTowerContainer *towers) const
virtual StatusCode execute(const EventContext &ctx) const override
SG::WriteHandleKey< xAOD::EnergySumRoI > m_outputRhoKey
JTowerRhoSubtractionAlg(const std::string &name, ISvcLocator *pSvcLocator)
virtual StatusCode initialize() override
SG::WriteHandleKey< xAOD::JGTowerContainer > m_outputKey
SG::ConstAccessor< T, ALLOC > ConstAccessor
Definition AuxElement.h:569
SG::Decorator< T, ALLOC > Decorator
Definition AuxElement.h:575
virtual double phi() const final
The azimuthal angle ( ) of the particle.
virtual double et() const final
virtual double eta() const final
The pseudorapidity ( ) of the particle.
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146
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())
setSAddress setEtaMS setDirPhiMS setDirZMS setBarrelRadius setEndcapAlpha setEndcapRadius setPhiMap phiBin
setSAddress setEtaMS setDirPhiMS setDirZMS setBarrelRadius setEndcapAlpha setEndcapRadius setInterceptInner setEtaMap etaBin
std::pair< std::unique_ptr< T >, std::unique_ptr< ShallowAuxContainer > > shallowCopyContainer(const T &cont, const EventContext &ctx)
Function making a shallow copy of a constant container.
JGTower_v1 JGTower
Define the latest version of the JGTower class.
Definition JGTower.h:15
bool setOriginalObjectLink(const IParticle &original, IParticle &copy)
This function should be used by CP tools when they make a deep copy of an object in their correctedCo...
JGTowerContainer_v1 JGTowerContainer
Define the latest version of the JGTower container.
std::vector< std::vector< std::size_t > > m_binsCore
std::vector< std::vector< std::size_t > > m_bins