ATLAS Offline Software
Loading...
Searching...
No Matches
EgammaReSamp2Fex.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5// ********************************************************************
6//
7// NAME: EgammaReSamp2Fex.cxx
8// PACKAGE: Trigger/TrigAlgorithms/TrigT2CaloEgamma
9//
10// AUTHOR: M.P. Casado, D.O. Damazio
11//
12//
13// ********************************************************************
14
15#include "EgammaReSamp2Fex.h"
16#include "CaloGeoHelpers/CaloSampling.h"
21
22EgammaReSamp2Fex::EgammaReSamp2Fex(const std::string& type, const std::string& name,
23 const IInterface* parent) :
24 IReAlgToolCalo(type, name, parent)
25{
26}
27
28StatusCode EgammaReSamp2Fex::execute(xAOD::TrigEMCluster& rtrigEmCluster, const IRoiDescriptor& roi,
29 const CaloDetDescrElement*& caloDDE,
30 const EventContext& context) const
31{
32 ATH_MSG_DEBUG("in execute(TrigEMCluster&)");
33
34 // Region Selector, sampling 2
35 int sampling = 2;
36
38 ATH_CHECK( m_dataSvc->loadCollections(context, roi, TTEM, sampling, sel) );
39
40 double energyEta = 0.;
41 double energyPhi = 0.;
42
43 // add these variables to take care of phi wrap-around
44 double energyNegPhi = 0.; // SRA
45 double energyNegPhiConv = 0.; // SRA
46 double energyPosPhi = 0.; // SRA
47
48 // 1. Find seed cell (highest Et in ROI .. layer 2)
49 // 2. Find Et weighted eta, phi in 3*7 cell (layer 2) (photon + e id)
50 // 3. Find Et in cells of sizes 3*3, 3*7, 7*7 (layer 2 + strips)
51 // (3*7 for photon + e id)
52 // 4. Find cluster width in 3*5 cell, layer 2 (photon id, needs
53 // parabolic parametrisation)
54 // 5. Find strip energies and eta (2*5 window)
55 // 6. Find frac73 (photon id), (E1-E2)/(E1+E2) (e + photon id)
56
57 double seedEnergy = 0.;
58 double seedPhi = 999.;
59 double seedEta = 999.;
60 double hotPhi = 999.;
61 double hotEta = 999.;
62 int ncells = 0;
63 // LVL1 positions
64 float etaL1 = rtrigEmCluster.eta();
65 float phiL1 = rtrigEmCluster.phi();
66
67 const LArEM_ID* emID = m_larMgr->getEM_ID();
68 const LArCell* seedCell = nullptr;
69 const LArCell* hotCell = nullptr;
70 for (const LArCell* larcell : sel) {
71 if (larcell->energy() > seedEnergy) { // Hottest cell seach
72 float deta = std::abs(etaL1 - larcell->eta());
73 if (deta < m_maxHotCellDeta) { // Eta check is faster. Do it First
74 float dphi = std::abs(phiL1 - larcell->phi());
75 dphi = std::abs(M_PI - dphi);
76 dphi = std::abs(M_PI - dphi);
77 if (dphi < m_maxHotCellDphi) {
78 seedEnergy = larcell->energy();
79 seedCell = larcell;
80 } // End of dphi check
81 } // End of deta check
82 } // End of if energy
83 ncells++;
84 }
85 if (seedCell != nullptr) {
86 seedEta = seedCell->eta();
87 seedPhi = seedCell->phi();
88 // For the S-shape correction, we store the caloDDE of the hottest cell
89 caloDDE = (seedCell->caloDDE());
90 hotCell = seedCell;
91 hotEta = hotCell->eta();
92 hotPhi = hotCell->phi();
93 }
94 else {
95 return StatusCode::SUCCESS;
96 }
97
98 std::map<const LArCell*, float> windows;
99 for (const LArCell* larcell : sel) {
100 float deta = std::abs(seedEta - larcell->eta());
101 if (deta < 0.025 + 0.002) { // Eta check is faster.
102 // Do it First 0.025 is cell, plus a little loose
103 float dphi = std::abs(seedPhi - larcell->phi());
104 dphi = std::abs(M_PI - dphi);
105 dphi = std::abs(M_PI - dphi);
106 if (dphi < 0.025 + 0.002) { // the same here (around 2*pi/64/4, but ok)
107 windows.emplace(larcell, 0.0);
108 } // End of dphi check
109 } // End of deta check
110 ncells++;
111 }
112
113 for (const LArCell* larcell : sel) {
114 double etaCell = larcell->eta();
115 double phiCell = larcell->phi();
116 double energyCell = larcell->et();
117
118 // Find position of current cell w.r.t. seed
119 float deta = std::abs(etaCell - seedEta);
120 if (deta > 0.05 + 0.002) continue; // find the energy weighted position with larger cluster
121 for (auto& [cell, energy] : windows) {
122 float deta1 = std::abs(etaCell - cell->eta());
123 float dphi = std::abs(phiCell - cell->phi());
124 if (dphi > M_PI) dphi = 2. * M_PI - dphi; // wrap (pi - 2pi)->(-pi - 0)
125
126 // Electromagnetic measurements, done by layer
127 // layer 2: Et weighted eta, phi, summed Et in 3*7,
128 // cluster width in 3*5 cell
129 // emEnergy in 3*7 cell is also calculated, all samplings
130
131 double cellSizeEta;
132 double cellSizePhi;
133 if (emID->is_em_barrel(larcell->ID())) {
134 cellSizeEta = etaSizeLArEMSamp2(etaCell, Calorimeter::EMBAR);
135 cellSizePhi = phiSizeLArEMSamp2(etaCell, Calorimeter::EMBAR);
136 }
137 else {
138 cellSizeEta = etaSizeLArEMSamp2(etaCell, Calorimeter::EMEND);
139 cellSizePhi = phiSizeLArEMSamp2(etaCell, Calorimeter::EMEND);
140 }
141
142 // 3. do the 3*5 stuff
143 int nCellsEta = 3;
144 int nCellsPhi = 5;
145 if (deta1 <= 0.5 * double(nCellsEta - 1) * cellSizeEta + 0.01 &&
146 dphi <= 0.5 * double(nCellsPhi - 1) * cellSizePhi + 0.01) {
147 energy += energyCell;
148 } // End of do the 3*5 stuff
149 } // End of windows map loop
150 } // end of the loop
151
152 float max = -999;
153 for (auto const& [cell, energy] : windows) {
154 if (energy > max) {
155 max = energy;
156 seedCell = cell;
157 }
158 }
159
160 if (seedCell != nullptr) {
161 seedEta = seedCell->eta();
162 seedPhi = seedCell->phi();
163 // For the S-shape correction, we store the caloDDE of the hottest cell
164 caloDDE = (seedCell->caloDDE());
165 }
166 else {
167 return StatusCode::SUCCESS;
168 }
169
170 bool cluster_in_barrel = true;
171 if (seedCell && seedCell->caloDDE()) cluster_in_barrel = seedCell->caloDDE()->is_lar_em_barrel();
172
173 // Build desired quantities using the values previously obtained.
174
175 double energy37Lay2 = 0.; // sum Et in 3*7 cell layer 2
176 double energy37Lay2NegPhi = 0.; // SRA for phi wrap-around
177 double energy37Lay2PosPhi = 0.; // SRA for phi wrap-around
178 double energy77Lay2 = 0.; // sum Et in 7*7 cell layer 2
179 double energy35Lay2 = 0.; // sum Et in 3*5 cell layer 2
180 double energy33Lay2 = 0.; // sum Et in 3*3 cell layer 2
181 double weightEta = 0.; // temporary variable for cluster width
182 double weightEta2 = 0.; // ditto
183 double clusterWidth35 = 0.; // cluster width in eta, 3*5 cell, layer 2
184 int nCellsEta = 0; // size of cell array in eta
185 int nCellsPhi = 0; // size of cell array in phi
186 double deta = 0.; // eta difference current cell - seed
187 double dphi = 0.; // phi difference current cell - seed
188
189 double totalEnergy = 0;
191
192 for (const LArCell* larcell : sel) {
193 double etaCell = larcell->eta();
194 double phiCell = larcell->phi();
195 double energyCell = larcell->energy();
196
197 // Find position of current cell w.r.t. seed
198 deta = std::abs(etaCell - seedEta);
199 dphi = std::abs(phiCell - seedPhi);
200 if (dphi > M_PI) dphi = 2. * M_PI - dphi; // wrap (pi - 2pi)->(-pi - 0)
201
202 double detaH = std::abs(etaCell - hotEta); // eta difference current cell - seed
203 double dphiH = std::abs(phiCell - hotPhi); // phi difference current cell - seed
204 if (dphiH > M_PI) dphiH = 2. * M_PI - dphiH; // wrap (pi - 2pi)->(-pi - 0)
205
206 // Electromagnetic measurements, done by layer
207 // layer 2: Et weighted eta, phi, summed Et in 3*7,
208 // cluster width in 3*5 cell
209 // emEnergy in 3*7 cell is also calculated, all samplings
210
211 double cellSizeEta;
212 double cellSizePhi;
213 if (emID->is_em_barrel(larcell->ID())) {
214 cellSizeEta = etaSizeLArEMSamp2(etaCell, Calorimeter::EMBAR);
215 cellSizePhi = phiSizeLArEMSamp2(etaCell, Calorimeter::EMBAR);
216 }
217 else {
218 cellSizeEta = etaSizeLArEMSamp2(etaCell, Calorimeter::EMEND);
219 cellSizePhi = phiSizeLArEMSamp2(etaCell, Calorimeter::EMEND);
220 }
221
222 // hot cell stuff first
223 // 1. do the 7*7 stuff
224 nCellsEta = 7;
225 nCellsPhi = 7;
226 if (detaH <= 0.5 * double(nCellsEta - 1) * cellSizeEta + 0.01 &&
227 dphiH <= 0.5 * double(nCellsPhi - 1) * cellSizePhi + 0.01) {
228 // 2. do the 3*7 stuff
229 nCellsEta = 3;
230 nCellsPhi = 7;
231 if (detaH <= 0.5 * double(nCellsEta - 1) * cellSizeEta + 0.01 &&
232 dphiH <= 0.5 * double(nCellsPhi - 1) * cellSizePhi + 0.01) {
233 energy37Lay2 += energyCell;
234 } // End of do the 3*7 stuff
235 energy77Lay2 += energyCell;
236 } // End of do the 7*7 stuff
237
238 // 1. do the 7*7 stuff
239 nCellsEta = 7;
240 nCellsPhi = 7;
241 if (deta <= 0.5 * double(nCellsEta - 1) * cellSizeEta + 0.005 &&
242 dphi <= 0.5 * double(nCellsPhi - 1) * cellSizePhi + 0.005) {
243 // 2. do the 3*7 stuff
244 nCellsEta = 3;
245 nCellsPhi = 7;
246 if (deta <= 0.5 * double(nCellsEta - 1) * cellSizeEta + 0.002 &&
247 dphi <= 0.5 * double(nCellsPhi - 1) * cellSizePhi + 0.002) {
248 energyEta += energyCell * etaCell;
249 // energy37Lay2 += energyCell;
250
251
252
253 if (phiCell > 0.) { // SRA phi wrap-around
254 energyPosPhi += double(energyCell) * phiCell;
255 energy37Lay2PosPhi += energyCell;
256 }
257 else {
258 energyNegPhi += double(energyCell) * phiCell;
259 energyNegPhiConv += double(energyCell) * (phiCell + 2.0 * M_PI);
260 energy37Lay2NegPhi += energyCell;
261 }
262 // 3. do the 3*5 stuff
263 nCellsEta = 3;
264 nCellsPhi = 5;
265 if (deta <= 0.5 * double(nCellsEta - 1) * cellSizeEta + 0.01 &&
266 dphi <= 0.5 * double(nCellsPhi - 1) * cellSizePhi + 0.01) {
267 weightEta += energyCell * etaCell;
268 weightEta2 += energyCell * etaCell * etaCell;
269 energy35Lay2 += energyCell;
270 // 3a. do the 3*3 stuff
271 // nCellsEta = 3;
272 nCellsPhi = 3;
273 if (deta <= 0.5 * double(nCellsEta - 1) * cellSizeEta + 0.01 &&
274 dphi <= 0.5 * double(nCellsPhi - 1) * cellSizePhi + 0.01) {
275 energy33Lay2 += energyCell;
276 } // End of do the 3*3 stuff
277 } // End of do the 3*5 stuff
278
279 } // End of do the 3x7 stuff
280
281
282 } // End of do the 7*7 stuff
283
284 } // end of loop over sampling 2
285
286 // Normalise energy weighted angles and calculate values
287
288 if ((energy37Lay2PosPhi + energy37Lay2NegPhi) > 0.) { // dont divide by zero
289 // SRA phi wrap-around
290 double AvgNegPhi = 0.;
291 double AvgPosPhi = 0.;
292
293 energyEta /= (energy37Lay2PosPhi + energy37Lay2NegPhi);
294
295 if (energy37Lay2NegPhi > 0.) {
296 AvgNegPhi = energyNegPhi / energy37Lay2NegPhi;
297 }
298 else {
299 AvgNegPhi = -999.0;
300 }
301
302 if (energy37Lay2PosPhi > 0.) {
303 AvgPosPhi = energyPosPhi / energy37Lay2PosPhi;
304 }
305 else {
306 AvgPosPhi = -999.0;
307 }
308
309 if (AvgPosPhi == -999.0) {
310 if (AvgNegPhi != -999.0) {
311 energyPhi = AvgNegPhi;
312 }
313 }
314
315 if (AvgNegPhi == -999.0) {
316 if (AvgPosPhi != -999.0) {
317 energyPhi = AvgPosPhi;
318 }
319 }
320
321 if (AvgNegPhi != -999.0 && AvgPosPhi != -999.0) {
322 if ((AvgNegPhi > (-M_PI / 2.0)) && (AvgPosPhi < (M_PI / 2.0))) {
323 energyPhi = (energyNegPhi + energyPosPhi) / (energy37Lay2NegPhi + energy37Lay2PosPhi);
324 }
325 else {
326 if ((AvgNegPhi < (-M_PI / 2.0)) && (AvgPosPhi > (M_PI / 2.0))) {
327 energyPhi = (energyNegPhiConv + energyPosPhi) / (energy37Lay2NegPhi + energy37Lay2PosPhi);
328 if (energyPhi > M_PI) {
329 energyPhi = energyPhi - 2 * M_PI;
330 }
331 }
332 }
333 }
334 }
335 else {
336 energyEta = 99.;
337 energyPhi = 0.;
338 }
339
340 for (const LArCell* larcell : sel) {
341 double etaCell = larcell->eta();
342 double phiCell = larcell->phi();
343 double energyCell = larcell->energy();
344
345 // Find position of current cell w.r.t. seed
346 deta = std::abs(etaCell - energyEta);
347 dphi = std::abs(phiCell - energyPhi);
348 if (dphi > M_PI) dphi = 2. * M_PI - dphi; // wrap (pi - 2pi)->(-pi - 0)
349
350 double cellSizeEta;
351 double cellSizePhi;
352 if (emID->is_em_barrel(larcell->ID())) {
353 cellSizeEta = etaSizeLArEMSamp2(etaCell, Calorimeter::EMBAR);
354 cellSizePhi = phiSizeLArEMSamp2(etaCell, Calorimeter::EMBAR);
355 }
356 else {
357 cellSizeEta = etaSizeLArEMSamp2(etaCell, Calorimeter::EMEND);
358 cellSizePhi = phiSizeLArEMSamp2(etaCell, Calorimeter::EMEND);
359 }
360
361 nCellsEta = 3;
362 nCellsPhi = 7;
363 if ((deta <= 0.5 * double(nCellsEta - 1) * cellSizeEta + 0.01) &&
364 (dphi <= 0.5 * double(nCellsPhi - 1) * cellSizePhi + 0.01)) {
365
366 if (cluster_in_barrel) {
367 totalEnergy += energyCell;
368 // samp = CaloSampling::getSampling(*larcell);
369 samp = larcell->caloDDE()->getSampling();
370 rtrigEmCluster.setEnergy(samp, rtrigEmCluster.energy(samp) + energyCell);
371 rtrigEmCluster.setRawEnergy(samp, rtrigEmCluster.rawEnergy(samp) + energyCell);
372 }
373 } // End of do the 3x7 stuff
374
375 nCellsEta = 5;
376 nCellsPhi = 5;
377 if ((!cluster_in_barrel) && (deta <= 0.5 * double(nCellsEta - 1) * cellSizeEta + 0.01) &&
378 (dphi <= 0.5 * double(nCellsPhi - 1) * cellSizePhi + 0.01)) {
379 totalEnergy += energyCell;
380 // samp = CaloSampling::getSampling(*larcell);
381 samp = larcell->caloDDE()->getSampling();
382 rtrigEmCluster.setEnergy(samp, rtrigEmCluster.energy(samp) + energyCell);
383 rtrigEmCluster.setRawEnergy(samp, rtrigEmCluster.rawEnergy(samp) + energyCell);
384 } // End of do the 5*5 stuff
385
386 } // end of loop over sampling 2
387
388 // calculate cluster width
389
390 if (energy35Lay2 > 0.) {
391 const double inv_energy35Lay2 = 1. / energy35Lay2;
392 clusterWidth35 = (weightEta2 * inv_energy35Lay2) -
393 (weightEta * inv_energy35Lay2) * (weightEta * inv_energy35Lay2);
394 clusterWidth35 > 0. ? clusterWidth35 = sqrt(clusterWidth35) : clusterWidth35 = 99.;
395 }
396 else {
397 clusterWidth35 = 99.;
398 }
399
400 // Update cluster Variables
401
402 // update stored variables
403 rtrigEmCluster.setE233(energy33Lay2);
404 rtrigEmCluster.setE237(energy37Lay2);
405 rtrigEmCluster.setE277(energy77Lay2);
406 rtrigEmCluster.setWeta2(clusterWidth35);
407 rtrigEmCluster.setRawEnergy(rtrigEmCluster.rawEnergy() + totalEnergy);
408 rtrigEmCluster.setEta(energyEta);
409 rtrigEmCluster.setPhi(energyPhi);
410 rtrigEmCluster.setRawEta(energyEta);
411 rtrigEmCluster.setRawPhi(energyPhi);
412 rtrigEmCluster.setNCells(ncells);
413
414 return StatusCode::SUCCESS;
415}
#define M_PI
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x)
@ TTEM
Definition RegSelEnums.h:28
#define max(a, b)
Definition cfImp.cxx:41
virtual double phi() const override final
get phi (through CaloDetDescrElement)
Definition CaloCell.h:375
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
Definition CaloCell.h:321
virtual double eta() const override final
get eta (through CaloDetDescrElement)
Definition CaloCell.h:382
This class groups all DetDescr information related to a CaloCell.
bool is_lar_em_barrel() const
cell belongs to EM barrel
Gaudi::Property< float > m_maxHotCellDphi
double phiSizeLArEMSamp2(const double eta, const int calo) const
EgammaReSamp2Fex(const std::string &type, const std::string &name, const IInterface *parent)
Gaudi::Property< float > m_maxHotCellDeta
double etaSizeLArEMSamp2(const double eta, const int calo) const
virtual StatusCode execute(xAOD::TrigEMCluster &rtrigEmCluster, const IRoiDescriptor &roi, const CaloDetDescrElement *&caloDDE, const EventContext &context) const override
execute feature extraction for the EM Calorimeter second layer
IReAlgToolCalo(const std::string &type, const std::string &name, const IInterface *parent)
Constructor.
ServiceHandle< ITrigCaloDataAccessSvc > m_dataSvc
const CaloIdManager * m_larMgr
Calorimeter Id Manager for calorimeter part determination (Barrel versus EndCap).
Describes the API of the Region of Ineterest geometry.
Data object for LAr calorimeter readout cell.
Definition LArCell.h:53
bool is_em_barrel(const Identifier id) const
test if the id belongs to the EM barrel
Helper class for LArEM offline identifiers.
Definition LArEM_ID.h:111
void setNCells(int)
set number of cells used from RoI
float rawEnergy() const
get Raw Energy (no calibration)
void setRawPhi(float)
set Raw Phi (no calibration)
void setRawEnergy(float)
set Raw Energy (no calibration)
void setRawEta(float)
set Raw Eta (no calibration)
void setPhi(float)
set Phi (calibrated)
void setEta(float)
set Eta (calibrated)
float eta() const
get Eta (calibrated)
void setWeta2(float)
set cluster width (based on a 3x5 cluster - 2nd layer)
void setEnergy(float energy)
set Energy (calibrated)
float phi() const
get Phi (calibrated)
void setE237(float)
set Energy in a 3x7 cluster (no calibration) around hottest cell
void setE277(float)
set Energy in a 7x7 cluster (no calibration) around hottest cell
float energy() const
get Energy (calibrated)
void setE233(float)
set Energy in a 3x3 cluster (no calibration) around hottest cell
TrigEMCluster_v1 TrigEMCluster
Define the latest version of the trigger EM cluster class.
int windows(float distance, float eta_pivot, int thr, int sector)
Definition windows.cxx:14