ATLAS Offline Software
Loading...
Searching...
No Matches
gFEXFPGA.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4//***************************************************************************
5// gFEXFPGA - Defines FPGA tools
6// -------------------
7// begin : 01 04 2021
8// email : cecilia.tosciri@cern.ch
9//***************************************************************************
10
11#include "gFEXFPGA.h"
15#include <algorithm>
16
17namespace LVL1
18{
19
20 // default constructor for persistency
21
22 gFEXFPGA::gFEXFPGA(const std::string &type, const std::string &name, const IInterface *parent) : AthAlgTool(type, name, parent)
23 {
24 declareInterface<IgFEXFPGA>(this);
25 }
26
31
32 //---------------- Initialisation -------------------------------------------------
33
35 {
36
39 ATH_CHECK(m_DBToolKey.initialize());
40
41 return StatusCode::SUCCESS;
42 }
43
44 void gFEXFPGA::FillgTowerEDMCentral( const EventContext& ctx,
45 SG::WriteHandle<xAOD::gFexTowerContainer> &gTowersContainer, // output
46 int fpgaId, // input fpga (A=0, B=1)
47 const gTowersCentral &gTowersIDs_central, // input, IDs
48 gTowersType &output_gTower_energies, // output, 200 MeV
49 gTowersType &output_gTower50_energies, // output, 50 MeV
50 gTowersType &output_saturation) const
51 { // output, saturation
53 if (!myDBTool.isValid())
54 {
55 ATH_MSG_ERROR("Could not retrieve DB tool " << m_DBToolKey);
56 }
57
58 gTowersType offsetsDefaultA = {{{0}}};
59 gTowersType noiseCutsDefaultA = {{{0}}};
60 gTowersType slopesDefaultA = {{{0}}};
61 gTowersType offsetsDefaultB = {{{0}}};
62 gTowersType noiseCutsDefaultB= {{{0}}};
63 gTowersType slopesDefaultB = {{{0}}};
64 gFEXFPGA::calExpand(offsetsDefaultA, noiseCutsDefaultA, slopesDefaultA, 48, myDBTool->get_AnoiseCuts(), myDBTool->get_Aslopes());
65 gFEXFPGA::calExpand(offsetsDefaultB, noiseCutsDefaultB, slopesDefaultB, 48, myDBTool->get_BnoiseCuts(), myDBTool->get_Bslopes());
66
67 float Eta = 99;
68 float Phi = 99;
69 int TowerEt = -99;
70 char IsSaturated = 0;
71
72 float etaSum = 0;
73
74 SG::ReadHandle<gTowerContainer> gFEXFPGA_gTowerContainer(m_gFEXFPGA_gTowerContainerKey, ctx); // 200 MeV
75 SG::ReadHandle<gTowerContainer> gFEXFPGA_gTower50Container(m_gFEXFPGA_gTower50ContainerKey, ctx); // 50 MeV
76
77 bool is_mc = false;
78 if (!gFEXFPGA_gTower50Container.isValid())
79 {
80 is_mc = true;
81 }
82
83 int rows = gTowersIDs_central.size();
84 int cols = gTowersIDs_central[0].size();
85
86 for (int myrow = 0; myrow < rows; myrow++)
87 {
88 for (int mycol = 0; mycol < cols; mycol++)
89 {
90
91 output_gTower_energies[myrow][mycol] = 0;
92 output_gTower50_energies[myrow][mycol] = 0;
93 output_saturation[myrow][mycol] = 0;
94
95 int towerID = gTowersIDs_central[myrow][mycol];
96 if (towerID == 0)
97 continue;
98
99 const LVL1::gTower *tmpTower = gFEXFPGA_gTowerContainer->findTower(towerID);
100 const LVL1::gTower *tmpTower50 = tmpTower;
101 if (!is_mc)
102 {
103 tmpTower50 = gFEXFPGA_gTower50Container->findTower(towerID);
104 }
105
106 if (tmpTower == nullptr)
107 continue;
108
109 TowerEt = tmpTower->getET();
110 Eta = tmpTower->eta();
111 Phi = tmpTower->phi();
112
113 etaSum += Eta;
114
115 int iPhiFW, iEtaFW;
116 uint32_t gFEXtowerID = tmpTower->getFWID(iPhiFW, iEtaFW);
117 IsSaturated = tmpTower->isSaturated();
118 std::unique_ptr<xAOD::gFexTower> gTowerEDM(new xAOD::gFexTower());
119 gTowersContainer->push_back(std::move(gTowerEDM));
120 gTowersContainer->back()->initialize(iEtaFW, iPhiFW, Eta, Phi, TowerEt, fpgaId, IsSaturated, gFEXtowerID);
121
122 output_gTower_energies[myrow][mycol] = tmpTower->getET();
123 output_gTower50_energies[myrow][mycol] = is_mc ? tmpTower50->getET() * 4. : tmpTower50->getET();
124 output_saturation[myrow][mycol] = tmpTower->isSaturated();
125 }
126 }
127
128 // apply defualt slopes set in initialization.
129 // In the future these values will be read from the online COOL data base
130 // Note the unfortunate hack used to figure out if we are in FPGA A or B.
131 //
132
133 if (etaSum < 0)
134 {
135 // FPGA A
136 gFEXFPGA::gtCalib(output_gTower_energies, offsetsDefaultA, noiseCutsDefaultA, slopesDefaultA);
137 }
138 else
139 {
140 // FPGA B
141 gFEXFPGA::gtCalib(output_gTower_energies, offsetsDefaultB, noiseCutsDefaultB, slopesDefaultB);
142 }
143 }
144
145 void gFEXFPGA::FillgTowerEDMForward( const EventContext& ctx,
147 int fpgaId,
148 const gTowersForward &gTowersIDs_forward_n,
149 const gTowersForward &gTowersIDs_forward_p,
150 gTowersType &output_gTower_energies,
151 gTowersType &output_gTower50_energies,
152 gTowersType &output_saturation) const
153 {
155 if (!myDBTool.isValid())
156 {
157 ATH_MSG_ERROR("Could not retrieve DB tool " << m_DBToolKey);
158 }
159
160 gTowersType offsetsDefaultC = {{{0}}};
161 gTowersType noiseCutsDefaultC = {{{0}}};
162 gTowersType slopesDefaultC = {{{0}}};
163
164 gFEXFPGA::calExpand(offsetsDefaultC, noiseCutsDefaultC, slopesDefaultC, 48, myDBTool->get_CnoiseCuts(), myDBTool->get_Cslopes());
165
166 char IsSaturated = 0;
167
170
171 bool is_mc = false;
172 if (!gFEXFPGA_gTower50Container.isValid())
173 {
174 is_mc = true;
175 }
176
177 //
178 // C-N
179 //
180 int rows = gTowersIDs_forward_n.size();
181 int cols = gTowersIDs_forward_n[0].size();
182
183 for (int myrow = 0; myrow < rows; myrow++)
184 {
185 for (int mycol = 0; mycol < cols; mycol++)
186 {
187
188 int towerID = gTowersIDs_forward_n[myrow][mycol];
189 if (towerID == 0)
190 continue;
191
192 const LVL1::gTower *tmpTower = gFEXFPGA_gTowerContainer->findTower(towerID);
193 const LVL1::gTower *tmpTower50 = tmpTower;
194 if (!is_mc)
195 {
196 tmpTower50 = gFEXFPGA_gTower50Container->findTower(towerID);
197 }
198
199 if (tmpTower == nullptr)
200 continue;
201
202 int TowerEt = tmpTower->getET();
203 float Eta = tmpTower->eta();
204 float Phi = tmpTower->phi();
205 int iPhiFW, iEtaFW;
206 uint32_t gFEXtowerID = tmpTower->getFWID(iPhiFW, iEtaFW);
207 IsSaturated = tmpTower->isSaturated();
208 std::unique_ptr<xAOD::gFexTower> gTowerEDM(new xAOD::gFexTower());
209 gTowersContainer->push_back(std::move(gTowerEDM));
210 gTowersContainer->back()->initialize(iEtaFW, iPhiFW, Eta, Phi, TowerEt, fpgaId, IsSaturated, gFEXtowerID);
211
212 output_gTower_energies[iPhiFW][iEtaFW - 2] = tmpTower->getET();
213 output_gTower50_energies[iPhiFW][iEtaFW - 2] = is_mc ? tmpTower50->getET() * 4. : tmpTower50->getET();
214 output_saturation[iPhiFW][iEtaFW - 2] = tmpTower->isSaturated();
215 }
216 }
217
218 //
219 // C-P
220 //
221 rows = gTowersIDs_forward_p.size();
222 cols = gTowersIDs_forward_p[0].size();
223
224 for (int myrow = 0; myrow < rows; myrow++)
225 {
226 for (int mycol = 0; mycol < cols; mycol++)
227 {
228
229 int towerID = gTowersIDs_forward_p[myrow][mycol];
230 if (towerID == 0)
231 continue;
232
233 const LVL1::gTower *tmpTower = gFEXFPGA_gTowerContainer->findTower(towerID);
234 const LVL1::gTower *tmpTower50 = tmpTower;
235 if (!is_mc)
236 {
237 tmpTower50 = gFEXFPGA_gTower50Container->findTower(towerID);
238 }
239
240 if (tmpTower == nullptr)
241 continue;
242
243 int TowerEt = tmpTower->getET();
244 float Eta = tmpTower->eta();
245 float Phi = tmpTower->phi();
246 int iPhiFW, iEtaFW;
247 uint32_t gFEXtowerID = tmpTower->getFWID(iPhiFW, iEtaFW);
248 IsSaturated = tmpTower->isSaturated();
249 std::unique_ptr<xAOD::gFexTower> gTowerEDM(new xAOD::gFexTower());
250 gTowersContainer->push_back(std::move(gTowerEDM));
251 gTowersContainer->back()->initialize(iEtaFW, iPhiFW, Eta, Phi, TowerEt, fpgaId, IsSaturated, gFEXtowerID);
252
253 output_gTower_energies[iPhiFW][iEtaFW - 32 + 6] = tmpTower->getET();
254 output_gTower50_energies[iPhiFW][iEtaFW - 32 + 6] = is_mc ? tmpTower50->getET() * 4. : tmpTower50->getET();
255 output_saturation[iPhiFW][iEtaFW - 32 + 6] = tmpTower->isSaturated();
256 }
257 }
258
259 // apply default slopes set in initialization.
260 // In the future these values will be read from the online COOL data base
261
262 gFEXFPGA::gtCalib(output_gTower_energies, offsetsDefaultC, noiseCutsDefaultC, slopesDefaultC);
263 }
264
265 void gFEXFPGA::gtCalib(gTowersType &twrs, const gTowersType &offsets, const gTowersType &noiseCuts, const gTowersType &slopes) const
266 {
267 int rows = twrs.size();
268 int cols = twrs[0].size();
269 for (int irow = 0; irow < rows; irow++)
270 {
271 for (int jcolumn = 0; jcolumn < cols; jcolumn++)
272 {
273 twrs[irow][jcolumn] = twrs[irow][jcolumn] + offsets[irow][jcolumn];
274 calLookup(&twrs[irow][jcolumn], offsets[irow][jcolumn], noiseCuts[irow][jcolumn], slopes[irow][jcolumn]);
275 }
276 }
277 }
278
279 void gFEXFPGA::calLookup(int *tower, const int offset, const int noiseCut, const int calib) const
280 {
281 int address = *tower;
282
283 if (address < 0)
284 {
285 ATH_MSG_DEBUG("gTower lookup address out of range " << address);
286 address = 0;
287 }
288 if (address > 2047)
289 {
290 ATH_MSG_DEBUG("gTower lookup address out of range " << address);
291 address = 2047;
292 }
293
294 // noise cut is made before calibraiton
295 if ((address - offset) < noiseCut)
296 address = offset;
297
298 int calTower = ((calib * address + 511) >> 10) - ((calib * offset + 511) >> 10);
299
300 if (calTower < -2048)
301 calTower = -2048;
302 if (calTower > 2047)
303 calTower = 2047;
304 if (address == 2047) calTower = 2047;
305
306 *tower = calTower;
307 }
308
309 void gFEXFPGA::calExpand(gTowersType &offsets, gTowersType &noiseCuts, gTowersType &slopes, const int offset, const std::array<int, 12>& columnNoiseCuts, const std::array<int, 12>& columnSlopes) const
310 {
311
312 int rows = offsets.size();
313 int cols = offsets[0].size();
314 for (int irow = 0; irow < rows; irow++)
315 {
316 for (int jcolumn = 0; jcolumn < cols; jcolumn++)
317 {
318 offsets[irow][jcolumn] = offset;
319 noiseCuts[irow][jcolumn] = columnNoiseCuts[jcolumn];
320 slopes[irow][jcolumn] = columnSlopes[jcolumn];
321 }
322 }
323 }
324
325} // end of namespace bracket
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
SG::ReadCondHandleKey< gFEXDBCondData > m_DBToolKey
Internal data.
Definition gFEXFPGA.h:47
virtual void FillgTowerEDMForward(const EventContext &, SG::WriteHandle< xAOD::gFexTowerContainer > &, int, const gTowersForward &, const gTowersForward &, gTowersType &, gTowersType &, gTowersType &) const override
Definition gFEXFPGA.cxx:145
SG::ReadHandleKey< LVL1::gTowerContainer > m_gFEXFPGA_gTowerContainerKey
Definition gFEXFPGA.h:55
void calLookup(int *tower, const int offset, const int noiseCut, const int slope) const
Definition gFEXFPGA.cxx:279
virtual StatusCode initialize() override
standard Athena-Algorithm method
Definition gFEXFPGA.cxx:34
virtual ~gFEXFPGA()
Destructor.
Definition gFEXFPGA.cxx:28
SG::ReadHandleKey< LVL1::gTowerContainer > m_gFEXFPGA_gTower50ContainerKey
Definition gFEXFPGA.h:56
void calExpand(gTowersType &offsets, gTowersType &noiseCuts, gTowersType &slopes, const int offset, const std::array< int, 12 > &columnNoiseCuts, const std::array< int, 12 > &columnSlopes) const
Definition gFEXFPGA.cxx:309
virtual void FillgTowerEDMCentral(const EventContext &, SG::WriteHandle< xAOD::gFexTowerContainer > &, int, const gTowersCentral &, gTowersType &, gTowersType &, gTowersType &) const override
Definition gFEXFPGA.cxx:44
gFEXFPGA(const std::string &type, const std::string &name, const IInterface *parent)
Constructors.
Definition gFEXFPGA.cxx:22
void gtCalib(gTowersType &twrs, const gTowersType &offsets, const gTowersType &noiseCuts, const gTowersType &slopes) const
Definition gFEXFPGA.cxx:265
The gTower class is an interface object for gFEX trigger algorithms The purposes are twofold:
Definition gTower.h:38
int getFWID(int &iPhiFW, int &iEtaFW) const
Calculates and returns the firmware ID, as well as iPhi and iEta in FT/global scheme.
Definition gTower.cxx:195
char isSaturated() const
Returns true if is saturated.
Definition gTower.cxx:172
float phi() const
Definition gTower.h:69
float eta() const
Definition gTower.h:68
int getET() const
Get ET (total) in MeV.
Definition gTower.cxx:140
virtual bool isValid() override final
Can the handle be successfully dereferenced?
eFexTowerBuilder creates xAOD::eFexTowerContainer from supercells (LATOME) and triggerTowers (TREX) i...
std::array< std::array< int, 8 >, 32 > gTowersForward
std::array< std::array< int, 12 >, 32 > gTowersCentral
std::array< std::array< int, 12 >, 32 > gTowersType
Definition IgFEXFPGA.h:25
gFexTower_v1 gFexTower
Define the latest version of the TriggerTower class.
Definition gFexTower.h:15