ATLAS Offline Software
Loading...
Searching...
No Matches
eFEXTOBEtTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5//***************************************************************************
6// eFEXTOBEtTool - description
7// -------------------
8// begin : 13 12 2022
9// email : Alan.Watson@CERN.CH
10// ***************************************************************************/
13#include "eFEXtauAlgo.h"
15#include <vector>
16
17namespace LVL1 {
18
19 // default constructor for persistency
20
21eFEXTOBEtTool::eFEXTOBEtTool(const std::string& type,const std::string& name,const IInterface* parent):
22 AthAlgTool(type,name,parent)
23{
24 declareInterface<eFEXTOBEtTool>(this);
25}
26
27
32
33//---------------- Initialisation -------------------------------------------------
34
36{
37
38 ATH_CHECK( m_eFEXegAlgoTool.retrieve() );
39 ATH_CHECK( m_eFEXtauAlgoTool.retrieve() );
40 ATH_CHECK(m_eTowerContainerKey.initialize());
41
42 return StatusCode::SUCCESS;
43}
44
45// The main user calls
46StatusCode eFEXTOBEtTool::getegSums(float etaTOB, float phiTOB, int seed, int UnD,
47 std::vector<unsigned int> &ClusterCellETs,
48 std::vector<unsigned int> &RetaSums,
49 std::vector<unsigned int> &RhadSums,
50 std::vector<unsigned int> &WstotSums)
51{
52
54 int tobtable[3][3];
55
56 for (int iphi = -1; iphi <= 1; ++iphi) {
57 float phiTable = phiTOB + iphi*m_dphiTower;
58 if (phiTable > M_PI) phiTable -= 2*M_PI;
59 if (phiTable < -M_PI) phiTable += 2*M_PI;
60
61 for (int ieta = -1; ieta <= 1; ++ieta) {
62 float etaTable = etaTOB + ieta*m_detaTower;
63
64 // Set the tower ID if within acceptance, else 0
65 if (std::abs(etaTable)<2.5) tobtable[iphi+1][ieta+1] = eTowerID(etaTable, phiTable);
66 else tobtable[iphi+1][ieta+1] = 0;
67
68 } // eta loop
69 } // phi loop
70
72 int eFEX, FPGA, fpgaEta;
73 location(etaTOB,phiTOB, eFEX, FPGA, fpgaEta);
74
75 // Set up e/g algorithm for this location
76 ATH_CHECK( m_eFEXegAlgoTool->safetyTest() );
77 m_eFEXegAlgoTool->setup(tobtable, eFEX, FPGA, fpgaEta);
78
79 // Get ETs of cells making up the ET clusters
80 m_eFEXegAlgoTool->getClusterCells(ClusterCellETs);
81
82 // Get sums from algorithm
83 // This will override the seed calculated by the algorithm with the one supplied here
84 m_eFEXegAlgoTool->getSums(seed, UnD, RetaSums, RhadSums, WstotSums);
85
86 // and we're done
87 return StatusCode::SUCCESS;
88
89}
90
91StatusCode eFEXTOBEtTool::getTOBCellEnergies(float etaTOB, float phiTOB, std::vector<unsigned int> &ClusterCellETs) const {
92
94 int tobtable[3][3];
95
96 for (int iphi = -1; iphi <= 1; ++iphi) {
97 float phiTable = phiTOB + iphi*m_dphiTower;
98 if (phiTable > M_PI) phiTable -= 2*M_PI;
99 if (phiTable < -M_PI) phiTable += 2*M_PI;
100
101 for (int ieta = -1; ieta <= 1; ++ieta) {
102 float etaTable = etaTOB + ieta*m_detaTower;
103
104 // Set the tower ID if within acceptance, else 0
105 if (std::abs(etaTable)<2.5) tobtable[iphi+1][ieta+1] = eTowerID(etaTable, phiTable);
106 else tobtable[iphi+1][ieta+1] = 0;
107
108 } // eta loop
109 } // phi loop
110
112 ClusterCellETs.reserve(99); // will have a total of 99 supercell values (they are in counts of 25 MeV)
113
114 for (unsigned int il = 0; il < 5; il++) { // layer loop
115 size_t nCells = (il==1 || il==2) ? 4 : 1;
116 for (unsigned int iphi = 0; iphi < 3; iphi++) { // tower phi loop
117 for (unsigned int ieta = 0; ieta < 3; ieta++) { // tower eta loop
118 if (tobtable[iphi][ieta]==0){
119 for(size_t c=0;c<nCells;c++) {
120 ClusterCellETs.push_back(0); // no energies for TOBs are the extreme eta values
121 }
122 } else {
123 const eTower * tower = eTowerContainer->findTower(tobtable[iphi][ieta]);
124 if (tower==nullptr) {
125 ATH_MSG_ERROR("No tower with id " << tobtable[iphi][ieta]);
126 return StatusCode::FAILURE;
127 }
128 for(size_t c=0;c<nCells;c++) {
129 // Note: energy counts can technically be negative (although noise cuts should usually prevent this)
130 // But algo developers wanted the energy count decoration to be a vector of unsigned int for historical reasons
131 // It is therefore possible for the unsigned int to be an overflow of int max
132 ClusterCellETs.push_back( tower->getET(il,c) );
133 }
134 }
135 }
136 }
137 }
138
139 /*----------- SuperCells eta, phi, layer coordinates ----------------------
140 0:{0, 0, 0}, 1:{1, 0, 0}, 2:{2, 0, 0},
141 3:{0, 1, 0}, 4:{1, 1, 0}, 5:{2, 1, 0},
142 6:{0, 2, 0}, 7:{1, 2, 0}, 8:{2, 2, 0},
143 9:{0, 0, 1}, 10:{1, 0, 1}, 11:{2, 0, 1}, 12:{3, 0, 1}, 13:{4, 0, 1}, 14:{5, 0, 1}, 15:{6, 0, 1}, 16:{7, 0, 1}, 17:{8, 0, 1}, 18:{9, 0, 1}, 19:{10, 0, 1}, 20:{11, 0, 1},
144 21:{0, 1, 1}, 22:{1, 1, 1}, 23:{2, 1, 1}, 24:{3, 1, 1}, 25:{4, 1, 1}, 26:{5, 1, 1}, 27:{6, 1, 1}, 28:{7, 1, 1}, 29:{8, 1, 1}, 30:{9, 1, 1}, 31:{10, 1, 1}, 32:{11, 1, 1},
145 33:{0, 2, 1}, 34:{1, 2, 1}, 35:{2, 2, 1}, 36:{3, 2, 1}, 37:{4, 2, 1}, 38:{5, 2, 1}, 39:{6, 2, 1}, 40:{7, 2, 1}, 41:{8, 2, 1}, 42:{9, 2, 1}, 43:{10, 2, 1}, 44:{11, 2, 1},
146 44:{0, 0, 2}, 45:{1, 0, 2}, 46:{2, 0, 2}, 47:{3, 0, 2}, 48:{4, 0, 2}, 49:{5, 0, 2}, 50:{6, 0, 2}, 51:{7, 0, 2}, 52:{8, 0, 2}, 53:{9, 0, 2}, 54:{10, 0, 2}, 55:{11, 0, 2},
147 56:{0, 1, 2}, 57:{1, 1, 2}, 58:{2, 1, 2}, 59:{3, 1, 2}, 60:{4, 1, 2}, 61:{5, 1, 2}, 62:{6, 1, 2}, 63:{7, 1, 2}, 64:{8, 1, 2}, 65:{9, 1, 2}, 66:{10, 1, 2}, 67:{11, 1, 2},
148 68:{0, 2, 2}, 69:{1, 2, 2}, 70:{2, 2, 2}, 71:{3, 2, 2}, 72:{4, 2, 2}, 73:{5, 2, 2}, 74:{6, 2, 2}, 75:{7, 2, 2}, 76:{8, 2, 2}, 77:{9, 2, 2}, 78:{10, 2, 2}, 79:{11, 2, 2},
149 81:{0, 0, 3}, 82:{1, 0, 3}, 83:{2, 0, 3},
150 84:{0, 1, 3}, 85:{1, 1, 3}, 86:{2, 1, 3},
151 87:{0, 2, 3}, 88:{1, 2, 3}, 89:{2, 2, 3},
152 90:{0, 0, 4}, 91:{1, 0, 4}, 92:{2, 0, 4},
153 93:{0, 1, 4}, 94:{1, 1, 4}, 95:{2, 1, 4},
154 96:{0, 2, 4}, 97:{1, 2, 4}, 98:{2, 2, 4}; */
155
156 return StatusCode::SUCCESS;
157}
158
159
160StatusCode eFEXTOBEtTool::gettauSums(float etaTOB, float phiTOB, int seed, int UnD,
161 std::vector<unsigned int> &RcoreSums,
162 std::vector<unsigned int> &RemSums)
163{
164
166 int tobtable[3][3];
167
168 for (int iphi = -1; iphi <= 1; ++iphi) {
169 float phiTable = phiTOB + iphi*m_dphiTower;
170 if (phiTable > M_PI) phiTable -= 2*M_PI;
171 if (phiTable < -M_PI) phiTable += 2*M_PI;
172
173 for (int ieta = -1; ieta <= 1; ++ieta) {
174 float etaTable = etaTOB + ieta*m_detaTower;
175
176 // Set the tower ID if within acceptance, else 0
177 if (std::abs(etaTable)<2.5) tobtable[iphi+1][ieta+1] = eTowerID(etaTable, phiTable);
178 else tobtable[iphi+1][ieta+1] = 0;
179
180 } // eta loop
181 } // phi loop
182
184 int eFEX, FPGA, fpgaEta;
185 location(etaTOB,phiTOB, eFEX, FPGA, fpgaEta);
186
187 // Set up e/g algorithm for this location
188 ATH_CHECK( m_eFEXtauAlgoTool->safetyTest() );
189 m_eFEXtauAlgoTool->setup(tobtable, eFEX, FPGA, fpgaEta);
190
191 // Get sums from algorithm
192 // This will override the seed calculated by the algorithm with the one supplied here
193 m_eFEXtauAlgoTool->getSums(seed, UnD, RcoreSums, RemSums);
194
195 // and we're done
196 return StatusCode::SUCCESS;
197
198}
199
200
201// Find eTower ID from a floating point coordinate pair
202unsigned int eFEXTOBEtTool::eTowerID(float eta, float phi) const
203{
204 // Calculate ID by hand from coordinate
205 int posneg = (eta >= 0 ? 1 : -1);
206 int towereta = std::abs(eta)/0.1;
207 if (phi < 0) phi += 2*M_PI;
208 int towerphi = int(32*phi/M_PI);
209 unsigned int tower_id = towerphi + 64*towereta;
210
211 if (towereta < 14) {
212 tower_id += (posneg > 0 ? 200000 : 100000);
213 }
214 else if (towereta == 14) {
215 tower_id += (posneg > 0 ? 400000 : 300000);
216 }
217 else {
218 tower_id += (posneg > 0 ? 600000 : 500000);
219 }
220
221 return tower_id;
222}
223
224
225// Find eFEX and FPGA numbers and eta index within FPGA
226void eFEXTOBEtTool::location(float etaTOB, float phiTOB, int& eFEX, int& FPGA, int& etaIndex) const
227{
228 // indices of central tower within a 0->49, 0->63 eta,phi map
229 int ieta = (etaTOB + 2.5)/m_detaTower;
230 float phiShifted = phiTOB + 2*m_dphiTower; // eFEX boundary does not line up with phi = 0
231 int iphi = (phiShifted > 0 ? phiShifted/m_dphiTower : (phiShifted + 2*M_PI)/m_dphiTower );
232
233 // Now we have global 0->N indices we can simply calculate which eFEX these come from
234 int eFEXPhi = iphi/8;
235 int eFEXeta = 0;
236 if (ieta > 16) eFEXeta = 1;
237 if (ieta > 32) eFEXeta = 2;
238
239 // eFEX number in range 0 -> 23
240 eFEX = eFEXeta + 3*eFEXPhi;
241
242 // Now which FPGA within the eFEX?
243 // This logic will give an index: 0 -> 16 for eFEX 0
244 // 1 -> 16 for eFEX 1
245 // 1 -> 17 for eFEX 2
246 // which puts FPGA boundaries at 4, 8, 12 in all cases
247 int eFEXIndex;
248 switch(eFEXeta) {
249 case 0: {
250 eFEXIndex = ieta;
251 break;
252 }
253 case 1: {
254 eFEXIndex = ieta -16;
255 break;
256 }
257 case 2: {
258 eFEXIndex = ieta -32;
259 break;
260 }
261 }
262
263 // Finally we can calculate the FPGA number
264 if (eFEXIndex <= 4) FPGA = 0;
265 else if (eFEXIndex <= 8) FPGA = 1;
266 else if (eFEXIndex <= 12) FPGA = 2;
267 else FPGA = 3;
268
269 // And eta index within the FPGA = 1-4 in most cases
270 // except for eFEX 0 FPGA 0 => 0-4 and eFEX 2 FPGA 3 => 1-5
271 etaIndex = eFEXIndex - 4*FPGA;
272
273 // And return the results by reference
274 return;
275}
276
277} // end of namespace bracket
#define M_PI
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)
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
virtual StatusCode getegSums(float etaTOB, float phiTOB, int seed, int UnD, std::vector< unsigned int > &ClusterCellETs, std::vector< unsigned int > &RetaSums, std::vector< unsigned int > &RhadSums, std::vector< unsigned int > &WstotSums)
Tool to calculate eEM discriminant sums.
SG::ReadHandleKey< LVL1::eTowerContainer > m_eTowerContainerKey
virtual StatusCode gettauSums(float etaTOB, float phiTOB, int seed, int UnD, std::vector< unsigned int > &RcoreSums, std::vector< unsigned int > &RemSums)
Tool to calculate eTaudiscriminant sums.
virtual StatusCode initialize()
standard Athena-Algorithm method
virtual void location(float etaTOB, float phiTOB, int &eFEX, int &FPGA, int &fpgaEta) const
Tool to find eFEX and FPGA numbers and eta index of a TOB within the FPGA.
const float m_dphiTower
Internal data.
virtual ~eFEXTOBEtTool()
Destructor.
ToolHandle< eFEXegAlgo > m_eFEXegAlgoTool
eFEXTOBEtTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructors.
virtual unsigned int eTowerID(float eta, float phi) const
Tool to find eTower identifier from an eta, phi coordinate pair.
ToolHandle< eFEXtauAlgoBase > m_eFEXtauAlgoTool
virtual StatusCode getTOBCellEnergies(float etaTOB, float phiTOB, std::vector< unsigned int > &ClusterCellETs) const
const float m_detaTower
const LVL1::eTower * findTower(int towerID) const
fast find method given identifier.
The eTower class is an interface object for eFEX trigger algorithms The purposes are twofold:
Definition eTower.h:38
int getET(unsigned int layer, int cell=0) const
Get ET of a specified cell in MeV.
Definition eTower.cxx:172
eFexTowerBuilder creates xAOD::eFexTowerContainer from supercells (LATOME) and triggerTowers (TREX) i...