ATLAS Offline Software
Loading...
Searching...
No Matches
CaloCellCollector.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <tuple>
8
19
21{
22 // For EM, set explicit window per layer, for rest use input dR
23 m_dEtadPhi.resize(CaloSampling::Unknown);
24 m_dEtadPhi[CaloSampling::PreSamplerB] =
25 std::pair<float, float>(0.0375, 0.15); // Ncells eta/phi: 3/3
26 m_dEtadPhi[CaloSampling::PreSamplerE] =
27 std::pair<float, float>(0.0375, 0.15); // Ncells eta/phi: 3/3
28 m_dEtadPhi[CaloSampling::EMB1] =
29 std::pair<float, float>(0.011, 0.15); // Ncells eta/phi: 7/3
30 m_dEtadPhi[CaloSampling::EME1] =
31 std::pair<float, float>(0.011, 0.15); // Ncells eta/phi: 7/3
32 m_dEtadPhi[CaloSampling::EMB2] =
33 std::pair<float, float>(0.0625, 0.0625); // Ncells eta/phi: 5/5
34 m_dEtadPhi[CaloSampling::EME2] =
35 std::pair<float, float>(0.0625, 0.0625); // Ncells eta/phi: 5/5
36 m_dEtadPhi[CaloSampling::EMB3] =
37 std::pair<float, float>(0.075, 0.0375); // Ncells eta/phi: 3/3
38 m_dEtadPhi[CaloSampling::EME3] =
39 std::pair<float, float>(0.075, 0.0375); // Ncells eta/phi: 3/3
40 m_dEtadPhi[CaloSampling::TileBar0] =
41 std::pair<float, float>(0.154, 0.151); // Ncells eta/phi: 3/3
42 m_dEtadPhi[CaloSampling::TileBar1] =
43 std::pair<float, float>(0.154, 0.151); // Ncells eta/phi: 3/3
44 m_dEtadPhi[CaloSampling::TileBar2] =
45 std::pair<float, float>(0.308, 0.151); // Ncells eta/phi: 3/3
46 m_dEtadPhi[CaloSampling::TileExt0] =
47 std::pair<float, float>(0.154, 0.151); // Ncells eta/phi: 3/3
48 m_dEtadPhi[CaloSampling::TileExt1] =
49 std::pair<float, float>(0.154, 0.151); // Ncells eta/phi: 3/3
50 m_dEtadPhi[CaloSampling::TileExt2] =
51 std::pair<float, float>(0.308, 0.151); // Ncells eta/phi: 3/3
52 m_dEtadPhi[CaloSampling::TileGap1] =
53 std::pair<float, float>(0.154, 0.151); // Ncells eta/phi: 3/3
54 m_dEtadPhi[CaloSampling::TileGap2] =
55 std::pair<float, float>(0.308, 0.151); // Ncells eta/phi: 3/3
56 m_dEtadPhi[CaloSampling::TileGap3] =
57 std::pair<float, float>(0.308, 0.151); // Ncells eta/phi: 3/3
58
59 // EM explicit window samples
60 m_samples.reserve(8);
61 m_samples.push_back(CaloSampling::PreSamplerB);
62 m_samples.push_back(CaloSampling::PreSamplerE);
63 m_samples.push_back(CaloSampling::EMB1);
64 m_samples.push_back(CaloSampling::EME1);
65 m_samples.push_back(CaloSampling::EMB2);
66 m_samples.push_back(CaloSampling::EME2);
67 m_samples.push_back(CaloSampling::EMB3);
68 m_samples.push_back(CaloSampling::EME3);
69 m_samples.push_back(CaloSampling::TileBar0);
70 m_samples.push_back(CaloSampling::TileBar1);
71 m_samples.push_back(CaloSampling::TileBar2);
72 m_samples.push_back(CaloSampling::TileExt0);
73 m_samples.push_back(CaloSampling::TileExt1);
74 m_samples.push_back(CaloSampling::TileExt2);
75 m_samples.push_back(CaloSampling::TileGap1);
76 m_samples.push_back(CaloSampling::TileGap2);
77 m_samples.push_back(CaloSampling::TileGap3);
78 // samples with dR
79 m_samplesForDR.reserve(4);
80 m_samplesForDR.push_back(CaloSampling::HEC0);
81 m_samplesForDR.push_back(CaloSampling::HEC1);
82 m_samplesForDR.push_back(CaloSampling::HEC2);
83 m_samplesForDR.push_back(CaloSampling::HEC3);
84
85 // From Bruno:
86 // PS: 0.025x0.06 (rectangle)
87 // EM1: 0.03x0.07 (rectangle)
88 // EM2: 0.05 (cone)
89 // EM3: 0.03 (cone)
90 // Tile1: 0.08x0.06 (rectangle)
91 // Tile2: 2x1 (number of cells in eta X phi)
92 // Tile3: 0.15x0.06 (rectangle)
93 // HEC0-3: 0.07 (cone)
94
95 // set parameters for EtCore
96 m_dEtadPhiCore.resize(CaloSampling::Unknown, std::pair<float, float>(0, 0));
97 m_dEtadPhiCore[CaloSampling::PreSamplerB] =
98 std::pair<float, float>(0.025, 0.06); // PS: 0.025x0.06
99 m_dEtadPhiCore[CaloSampling::PreSamplerE] =
100 std::pair<float, float>(0.025, 0.06); // PS: 0.025x0.06
101 m_dEtadPhiCore[CaloSampling::EMB1] =
102 std::pair<float, float>(0.03, 0.07); // EM1: 0.03x0.07
103 m_dEtadPhiCore[CaloSampling::EME1] =
104 std::pair<float, float>(0.03, 0.07); // EM1: 0.03x0.07
105 m_dEtadPhiCore[CaloSampling::TileBar0] =
106 std::pair<float, float>(0.08, 0.06); // Tile1: 0.08x0.06
107 m_dEtadPhiCore[CaloSampling::TileBar1] =
108 std::pair<float, float>(0.102, 0.101); // Tile2: 2x1
109 m_dEtadPhiCore[CaloSampling::TileBar2] =
110 std::pair<float, float>(0.15, 0.06); // Tile3: 0.15x0.06
111 m_dEtadPhiCore[CaloSampling::TileExt0] =
112 std::pair<float, float>(0.08, 0.06); // Tile1: 0.08x0.06
113 m_dEtadPhiCore[CaloSampling::TileExt1] =
114 std::pair<float, float>(0.102, 0.101); // Tile2: 2x1
115 m_dEtadPhiCore[CaloSampling::TileExt2] =
116 std::pair<float, float>(0.15, 0.06); // Tile3: 0.15x0.06
117 m_dEtadPhiDRCore.resize(CaloSampling::Unknown, 0);
118 m_dEtadPhiDRCore[CaloSampling::EMB2] = 0.05 * 0.05;
119 m_dEtadPhiDRCore[CaloSampling::EME2] = 0.05 * 0.05;
120 m_dEtadPhiDRCore[CaloSampling::EMB3] = 0.03 * 0.03;
121 m_dEtadPhiDRCore[CaloSampling::EME3] = 0.03 * 0.03;
122 m_dEtadPhiDRCore[CaloSampling::HEC0] = 0.07 * 0.07;
123 m_dEtadPhiDRCore[CaloSampling::HEC1] = 0.07 * 0.07;
124 m_dEtadPhiDRCore[CaloSampling::HEC2] = 0.07 * 0.07;
125 m_dEtadPhiDRCore[CaloSampling::HEC3] = 0.07 * 0.07;
126 m_selectEtCoreByEtadPhi.resize(CaloSampling::Unknown, false);
127 m_selectEtCoreByEtadPhi[CaloSampling::PreSamplerB] = true;
128 m_selectEtCoreByEtadPhi[CaloSampling::PreSamplerE] = true;
129 m_selectEtCoreByEtadPhi[CaloSampling::EMB1] = true;
130 m_selectEtCoreByEtadPhi[CaloSampling::EME1] = true;
131 m_selectEtCoreByEtadPhi[CaloSampling::TileBar0] = true;
132 m_selectEtCoreByEtadPhi[CaloSampling::TileBar1] = true;
133 m_selectEtCoreByEtadPhi[CaloSampling::TileBar2] = true;
134 m_selectEtCoreByEtadPhi[CaloSampling::TileExt0] = true;
135 m_selectEtCoreByEtadPhi[CaloSampling::TileExt1] = true;
136 m_selectEtCoreByEtadPhi[CaloSampling::TileExt2] = true;
137}
138
139void
141 const std::vector<std::pair<float, float>>& dEtadPhiCore,
142 const std::vector<float>& dEtadPhiDRCore,
143 const std::vector<bool>& selectEtCoreByEtadPhi)
144{
145 m_dEtadPhiCore = dEtadPhiCore;
146 m_dEtadPhiDRCore = dEtadPhiDRCore;
147 m_selectEtCoreByEtadPhi = selectEtCoreByEtadPhi;
148}
149
152 const Trk::CaloExtension& extension,
153 const CaloDetDescrManager* caloMgr,
154 const CaloCellContainer& cellContainer,
155 xAOD::CaloClusterContainer& clusterContainer) const
156{
157 // Collect cells in explicit window sizes
158
159 std::vector<const CaloCell*> cells;
160
162 CaloExtensionHelpers::entryExitLayerMap(extension, entryExitLayerMap);
163
164 cells.reserve(100);
165 CaloCellList myList(caloMgr, &cellContainer);
166 // Save sampling midpoints in map
167 using SampData = std::tuple<float, float, float>;
168 using SampDataPair = std::pair<CaloSample, SampData>;
169 std::map<CaloSample, SampData> sampleEtaPhiMap;
170 float etot = 0;
171 unsigned int samplingPattern = 0;
172 Amg::Vector3D clusVec(0, 0, 0);
173
174 // loop over samples using explicit sample window sizes
175
176 for (auto samp : m_samples) {
177 auto pos = entryExitLayerMap.find(samp);
178 if (pos != entryExitLayerMap.end()) {
179 samplingPattern |= CaloSampling::getSamplingPattern(
180 samp); // add in sampling to pattern for cluster
181 auto midPoint = 0.5 * (pos->second.first + pos->second.second);
182 clusVec = clusVec + midPoint;
183 myList.select(midPoint.eta(),
184 midPoint.phi(),
185 m_dEtadPhi[samp].first,
186 m_dEtadPhi[samp].second,
187 samp);
188 cells.insert(cells.end(), myList.begin(), myList.end());
189 float e = 0;
190 for (const auto* cell : myList)
191 e += cell->energy();
192 etot += e;
193 sampleEtaPhiMap.insert(
194 SampDataPair(samp, std::make_tuple(e, midPoint.eta(), midPoint.phi())));
195 }
196 }
197
198 // loop over samples using fabs(dR) for window
199
200 for (auto samp : m_samplesForDR) {
201 auto pos = entryExitLayerMap.find(samp);
202 if (pos != entryExitLayerMap.end()) {
203 samplingPattern |= CaloSampling::getSamplingPattern(
204 samp); // add in sampling to pattern for cluster
205 auto midPoint = 0.5 * (pos->second.first + pos->second.second);
206 clusVec = clusVec + midPoint;
207 myList.select(midPoint.eta(), midPoint.phi(), 0.1, samp);
208 cells.insert(cells.end(), myList.begin(), myList.end());
209 float e = 0;
210 for (const auto* cell : myList)
211 e += cell->energy();
212 etot += e;
213 sampleEtaPhiMap.insert(
214 SampDataPair(samp, std::make_tuple(e, midPoint.eta(), midPoint.phi())));
215 }
216 }
217
218 if (etot == 0) {
219 return nullptr;
220 }
221 float clusVecEta, clusVecPhi;
222 clusVecEta = clusVec.eta();
223 clusVecPhi = clusVec.phi();
224
225 // create cluster
226 xAOD::CaloCluster* cluster =
227 CaloClusterStoreHelper::makeCluster(&clusterContainer, &cellContainer);
228 if (!cluster) {
229 return nullptr;
230 }
231
232 // allocate the space for the sampling information
233 cluster->setSamplingPattern(samplingPattern);
234
235 // add cells to cluster
236 cluster->setE(etot);
237 for (const auto* cell : cells) {
238 if (!cell || !cell->caloDDE())
239 continue;
240 int index = cellContainer.findIndex(cell->caloDDE()->calo_hash());
241 if (index == -1)
242 continue;
243 cluster->addCell(index, 1.);
244 }
245 // Add energy and midpoints as the cluster eta/phi sampling positions
246 for (auto entry : sampleEtaPhiMap) {
247 cluster->setEnergy(entry.first, std::get<0>(entry.second));
248 cluster->setEta(entry.first, std::get<1>(entry.second));
249 cluster->setPhi(entry.first, std::get<2>(entry.second));
250 }
251
252 cluster->setEta(clusVecEta);
253 cluster->setPhi(clusVecPhi);
254
255 return cluster;
256}
257
258void
260 std::vector<float>& etcore,
261 const CaloNoise* caloNoise,
262 float sigmaNoiseCut) const
263{
264 // Collect the cells in the core for a muon
265
266 // Collect etCore for the different samples
267 float etCore = 0;
268 float etCoreEM = 0;
269 float etCoreTile = 0;
270 float etCoreHEC = 0;
271 std::vector<float> sampEt(CaloSampling::Unknown, 0);
272
273 for (const auto* cell : clus) {
274 CaloSample samp = cell->caloDDE()->getSampling();
275 float clusEta = clus.etaSample(samp);
276 float clusPhi = clus.phiSample(samp);
277 float deta = clusEta - cell->eta();
278 float dphi = CaloPhiRange::diff(clusPhi, cell->phi());
279 bool addCell = false;
280
281 if (m_selectEtCoreByEtadPhi[samp]) {
282 if (fabs(deta) < m_dEtadPhiCore[samp].first &&
283 fabs(dphi) < m_dEtadPhiCore[samp].second) {
284 addCell = true;
285 }
286 } else {
287 if ((deta * deta + dphi * dphi) < m_dEtadPhiDRCore[samp]) {
288 addCell = true;
289 }
290 }
291 // Check if cell passes the noise threshold of 3.4sigma
292 if (caloNoise && addCell &&
293 cell->energy() <
294 sigmaNoiseCut * caloNoise->getNoise(cell->ID(), cell->gain())) {
295 addCell = false;
296 }
297 // sum of et, defined by cell E, and muon track eta
298 if (addCell) {
299 sampEt[samp] += cell->energy() / cosh(clusEta);
300 }
301 }
302 // Set the core ET
303 etCoreEM += sampEt[CaloSampling::PreSamplerB];
304 etCoreEM += sampEt[CaloSampling::PreSamplerE];
305 etCoreEM += sampEt[CaloSampling::EMB1];
306 etCoreEM += sampEt[CaloSampling::EME1];
307 etCoreEM += sampEt[CaloSampling::EMB2];
308 etCoreEM += sampEt[CaloSampling::EME2];
309 etCoreEM += sampEt[CaloSampling::EMB3];
310 etCoreEM += sampEt[CaloSampling::EME3];
311 etCoreTile += sampEt[CaloSampling::TileBar0];
312 etCoreTile += sampEt[CaloSampling::TileBar1];
313 etCoreTile += sampEt[CaloSampling::TileBar2];
314 etCoreTile += sampEt[CaloSampling::TileExt0];
315 etCoreTile += sampEt[CaloSampling::TileExt1];
316 etCoreTile += sampEt[CaloSampling::TileExt2];
317 etCoreHEC += sampEt[CaloSampling::HEC0];
318 etCoreHEC += sampEt[CaloSampling::HEC1];
319 etCoreHEC += sampEt[CaloSampling::HEC2];
320 etCoreHEC += sampEt[CaloSampling::HEC3];
321 etCore = etCoreEM + etCoreTile + etCoreHEC;
322
323 etcore[Rec::CaloCellCollector::ET_Core] = etCore;
324 etcore[Rec::CaloCellCollector::ET_EMCore] = etCoreEM;
325 etcore[Rec::CaloCellCollector::ET_TileCore] = etCoreTile;
326 etcore[Rec::CaloCellCollector::ET_HECCore] = etCoreHEC;
327}
CaloCell_ID::CaloSample CaloSample
Definition of CaloDetDescrManager.
CaloPhiRange class declaration.
Container class for CaloCell.
int findIndex(const IdentifierHash theHash) const
Return index of the cell with a given hash.
list_iterator end() const
void select(double eta, double phi, double deta, double dphi)
list_iterator begin() const
CaloSampling::CaloSample CaloSample
Definition CaloCell_ID.h:53
static std::unique_ptr< xAOD::CaloCluster > makeCluster(const CaloCellContainer *cellCont)
Creates a valid CaloCluster with a private Aux-Store and CellLink container.
This class provides the client interface for accessing the detector description information common to...
float getNoise(const IdentifierHash h, const int gain) const
Accessor by IdentifierHash and gain.
Definition CaloNoise.h:34
static double diff(double phi1, double phi2)
simple phi1 - phi2 calculation, but result is fixed to respect range.
static unsigned int getSamplingPattern(const CaloSample s)
Get a unsigned with one bit set.
void collectEtCore(const xAOD::CaloCluster &cluster, std::vector< float > &et_core, const CaloNoise *caloNoise, float sigmaNoiseCut=3.4) const
std::vector< bool > m_selectEtCoreByEtadPhi
std::vector< std::pair< float, float > > m_dEtadPhi
void resetCoreParameters(const std::vector< std::pair< float, float > > &dEtadPhiCore, const std::vector< float > &dEtadPhiDRCore, const std::vector< bool > &selectEtCoreByEtadPhi)
std::vector< CaloSampling::CaloSample > m_samples
xAOD::CaloCluster * collectCells(const Trk::CaloExtension &extension, const CaloDetDescrManager *caloMgr, const CaloCellContainer &cellContainer, xAOD::CaloClusterContainer &clusterContainer) const
std::vector< CaloSampling::CaloSample > m_samplesForDR
std::vector< std::pair< float, float > > m_dEtadPhiCore
std::vector< float > m_dEtadPhiDRCore
Tracking class to hold the extrapolation through calorimeter Layers Both the caloEntryLayerIntersecti...
bool setPhi(const CaloSample sampling, const float phi)
Set in a given sampling. Returns false if the sample isn't part of the cluster.
float phiSample(const CaloSample sampling) const
Retrieve barycenter in a given sample.
bool setEta(const CaloSample sampling, const float eta)
Set in a given sampling. Returns false if the sample isn't part of the cluster.
bool setEnergy(const CaloSample sampling, const float e)
Set energy for a given sampling. Returns false if the sample isn't part of the cluster.
void setSamplingPattern(const unsigned sp, const bool clearSamplingVars=false)
Set sampling pattern (one bit per sampling.
float etaSample(const CaloSample sampling) const
Retrieve barycenter in a given sample.
bool addCell(const unsigned index, const double weight)
Method to add a cell to the cluster (Beware: Kinematics not updated!)
Eigen::Matrix< double, 3, 1 > Vector3D
void entryExitLayerMap(const Trk::CaloExtension &extension, EntryExitLayerMap &result, const LayersToSelect *selection=nullptr)
std::map< CaloSampling::CaloSample, std::pair< Amg::Vector3D, Amg::Vector3D > > EntryExitLayerMap
Definition index.py:1
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
CaloClusterContainer_v1 CaloClusterContainer
Define the latest version of the calorimeter cluster container.