ATLAS Offline Software
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 "L1CaloFEXSim/gFEXFPGA.h"
13 #include "StoreGate/WriteHandle.h"
14 #include "StoreGate/ReadHandle.h"
15 #include <algorithm>
16 
17 namespace 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 
29  {
30  }
31 
32  //---------------- Initialisation -------------------------------------------------
33 
35  {
36 
39  ATH_CHECK(m_DBToolKey.initialize());
40 
41  return StatusCode::SUCCESS;
42  }
43 
45  {
46  m_fpgaId = id;
47 
48  return StatusCode::SUCCESS;
49  }
50 
52  {
53 
54  m_fpgaId = -1;
55  }
56 
58  gTowersCentral &gTowersIDs_central, // input, IDs
59  // int fpga, // input fpga (A=0, B=1)
60  gTowersType &output_gTower_energies, // output, 200 MeV
61  gTowersType &output_gTower50_energies, // output, 50 MeV
62  gTowersType &output_saturation)
63  { // output, saturation
65  if (!myDBTool.isValid())
66  {
67  ATH_MSG_ERROR("Could not retrieve DB tool " << m_DBToolKey);
68  }
69  gFEXFPGA::calExpand(m_offsetsDefaultA, m_noiseCutsDefaultA, m_slopesDefaultA, 48, myDBTool->get_AnoiseCuts(), myDBTool->get_Aslopes());
70  gFEXFPGA::calExpand(m_offsetsDefaultB, m_noiseCutsDefaultB, m_slopesDefaultB, 48, myDBTool->get_BnoiseCuts(), myDBTool->get_Bslopes());
71 
72  float Eta = 99;
73  float Phi = 99;
74  int TowerEt = -99;
75  int Fpga = m_fpgaId;
76  char IsSaturated = 0;
77 
78  float etaSum = 0;
79 
80  SG::ReadHandle<gTowerContainer> gFEXFPGA_gTowerContainer(m_gFEXFPGA_gTowerContainerKey /*,ctx*/); // 200 MeV
81  SG::ReadHandle<gTowerContainer> gFEXFPGA_gTower50Container(m_gFEXFPGA_gTower50ContainerKey /*,ctx*/); // 50 MeV
82 
83  bool is_mc = false;
84  if (!gFEXFPGA_gTower50Container.isValid())
85  {
86  is_mc = true;
87  }
88 
89  int rows = gTowersIDs_central.size();
90  int cols = gTowersIDs_central[0].size();
91 
92  for (int myrow = 0; myrow < rows; myrow++)
93  {
94  for (int mycol = 0; mycol < cols; mycol++)
95  {
96 
97  output_gTower_energies[myrow][mycol] = 0;
98  output_gTower50_energies[myrow][mycol] = 0;
99  output_saturation[myrow][mycol] = 0;
100 
101  int towerID = gTowersIDs_central[myrow][mycol];
102  if (towerID == 0)
103  continue;
104 
105  const LVL1::gTower *tmpTower = gFEXFPGA_gTowerContainer->findTower(towerID);
106  const LVL1::gTower *tmpTower50 = tmpTower;
107  if (!is_mc)
108  {
109  tmpTower50 = gFEXFPGA_gTower50Container->findTower(towerID);
110  }
111 
112  if (tmpTower == nullptr)
113  continue;
114 
115  TowerEt = tmpTower->getET();
116  Eta = tmpTower->eta();
117  Phi = tmpTower->phi();
118 
119  etaSum += Eta;
120 
121  int iPhiFW, iEtaFW;
122  uint32_t gFEXtowerID = tmpTower->getFWID(iPhiFW, iEtaFW);
123  IsSaturated = tmpTower->isSaturated();
124  std::unique_ptr<xAOD::gFexTower> gTowerEDM(new xAOD::gFexTower());
125  gTowersContainer->push_back(std::move(gTowerEDM));
126  gTowersContainer->back()->initialize(iEtaFW, iPhiFW, Eta, Phi, TowerEt, Fpga, IsSaturated, gFEXtowerID);
127 
128  output_gTower_energies[myrow][mycol] = tmpTower->getET();
129  output_gTower50_energies[myrow][mycol] = is_mc ? tmpTower50->getET() * 4. : tmpTower50->getET();
130  output_saturation[myrow][mycol] = tmpTower->isSaturated();
131  }
132  }
133 
134  // apply defualt slopes set in initialization.
135  // In the future these values will be read from the online COOL data base
136  // Note the unforutnate hack used to figure out if we are in FPGA A or B.
137  //
138 
139  if (etaSum < 0)
140  {
141  // FPGA A
143  }
144  else
145  {
146  // FPGA B
148  }
149  }
150 
152  gTowersForward &gTowersIDs_forward_n,
153  gTowersForward &gTowersIDs_forward_p,
154  gTowersType &output_gTower_energies,
155  gTowersType &output_gTower50_energies,
156  gTowersType &output_saturation)
157  {
159  if (!myDBTool.isValid())
160  {
161  ATH_MSG_ERROR("Could not retrieve DB tool " << m_DBToolKey);
162  }
163  gFEXFPGA::calExpand(m_offsetsDefaultC, m_noiseCutsDefaultC, m_slopesDefaultC, 48, myDBTool->get_CnoiseCuts(), myDBTool->get_Cslopes());
164 
165  char IsSaturated = 0;
166 
167  SG::ReadHandle<gTowerContainer> gFEXFPGA_gTowerContainer(m_gFEXFPGA_gTowerContainerKey /*,ctx*/);
168  SG::ReadHandle<gTowerContainer> gFEXFPGA_gTower50Container(m_gFEXFPGA_gTower50ContainerKey /*,ctx*/);
169 
170  bool is_mc = false;
171  if (!gFEXFPGA_gTower50Container.isValid())
172  {
173  is_mc = true;
174  }
175 
176  //
177  // C-N
178  //
179  int rows = gTowersIDs_forward_n.size();
180  int cols = gTowersIDs_forward_n[0].size();
181 
182  for (int myrow = 0; myrow < rows; myrow++)
183  {
184  for (int mycol = 0; mycol < cols; mycol++)
185  {
186 
187  int towerID = gTowersIDs_forward_n[myrow][mycol];
188  if (towerID == 0)
189  continue;
190 
191  const LVL1::gTower *tmpTower = gFEXFPGA_gTowerContainer->findTower(towerID);
192  const LVL1::gTower *tmpTower50 = tmpTower;
193  if (!is_mc)
194  {
195  tmpTower50 = gFEXFPGA_gTower50Container->findTower(towerID);
196  }
197 
198  if (tmpTower == nullptr)
199  continue;
200 
201  int TowerEt = tmpTower->getET();
202  float Eta = tmpTower->eta();
203  float Phi = tmpTower->phi();
204  int Fpga = m_fpgaId;
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, Fpga, 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 Fpga = m_fpgaId;
247  int iPhiFW, iEtaFW;
248  uint32_t gFEXtowerID = tmpTower->getFWID(iPhiFW, iEtaFW);
249  IsSaturated = tmpTower->isSaturated();
250  std::unique_ptr<xAOD::gFexTower> gTowerEDM(new xAOD::gFexTower());
251  gTowersContainer->push_back(std::move(gTowerEDM));
252  gTowersContainer->back()->initialize(iEtaFW, iPhiFW, Eta, Phi, TowerEt, Fpga, IsSaturated, gFEXtowerID);
253 
254  output_gTower_energies[iPhiFW][iEtaFW - 32 + 6] = tmpTower->getET();
255  output_gTower50_energies[iPhiFW][iEtaFW - 32 + 6] = is_mc ? tmpTower50->getET() * 4. : tmpTower50->getET();
256  output_saturation[iPhiFW][iEtaFW - 32 + 6] = tmpTower->isSaturated();
257  }
258  }
259 
260  // apply defualt slopes set in initialization.
261  // In the future these values will be read from the online COOL data base
262 
264  }
265 
266  void gFEXFPGA::gtCalib(gTowersType &twrs, const gTowersType &offsets, const gTowersType &noiseCuts, const gTowersType &slopes) const
267  {
268  int rows = twrs.size();
269  int cols = twrs[0].size();
270  for (int irow = 0; irow < rows; irow++)
271  {
272  for (int jcolumn = 0; jcolumn < cols; jcolumn++)
273  {
274  twrs[irow][jcolumn] = twrs[irow][jcolumn] + offsets[irow][jcolumn];
275  calLookup(&twrs[irow][jcolumn], offsets[irow][jcolumn], noiseCuts[irow][jcolumn], slopes[irow][jcolumn]);
276  }
277  }
278  }
279 
280  void gFEXFPGA::calLookup(int *tower, const int offset, const int noiseCut, const int calib) const
281  {
282  int address = *tower;
283 
284  if (address < 0)
285  {
286  ATH_MSG_DEBUG("gTower lookup address out of range " << address);
287  address = 0;
288  }
289  if (address > 2047)
290  {
291  ATH_MSG_DEBUG("gTower lookup address out of range " << address);
292  address = 2047;
293  }
294 
295  // noise cut is made before calibraiton
296  if ((address - offset) < noiseCut)
297  address = offset;
298 
299  int calTower = ((calib * address + 511) >> 10) - ((calib * offset + 511) >> 10);
300 
301  if (calTower < -2048)
302  calTower = -2048;
303  if (calTower > 2047)
304  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
LVL1::gFEXFPGA::gFEXFPGA
gFEXFPGA(const std::string &type, const std::string &name, const IInterface *parent)
Constructors.
Definition: gFEXFPGA.cxx:22
LVL1::gFEXFPGA::reset
virtual void reset() override
Definition: gFEXFPGA.cxx:51
LVL1::gFEXFPGA::m_slopesDefaultB
gTowersType m_slopesDefaultB
Definition: gFEXFPGA.h:62
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
LVL1::gTower::getFWID
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:197
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
LVL1::gFEXFPGA::m_slopesDefaultC
gTowersType m_slopesDefaultC
Definition: gFEXFPGA.h:66
LVL1::gFEXFPGA::~gFEXFPGA
virtual ~gFEXFPGA()
Destructor.
Definition: gFEXFPGA.cxx:28
gTowerContainer.h
LVL1::gTower::isSaturated
char isSaturated() const
Returns true if is saturated.
Definition: gTower.cxx:174
LVL1::gTower
The gTower class is an interface object for gFEX trigger algorithms The purposes are twofold:
Definition: gTower.h:38
LVL1::gFEXFPGA::m_fpgaId
int m_fpgaId
Definition: gFEXFPGA.h:54
LVL1::gTower::phi
float phi() const
Definition: gTower.h:69
SG::ReadCondHandle::isValid
bool isValid()
Definition: ReadCondHandle.h:206
Phi
@ Phi
Definition: RPCdef.h:8
LVL1
eFexTowerBuilder creates xAOD::eFexTowerContainer from supercells (LATOME) and triggerTowers (TREX) i...
Definition: ICMMCPHitsCnvTool.h:18
LVL1::gFEXFPGA::FillgTowerEDMCentral
virtual void FillgTowerEDMCentral(SG::WriteHandle< xAOD::gFexTowerContainer > &, gTowersCentral &, gTowersType &, gTowersType &, gTowersType &) override
Definition: gFEXFPGA.cxx:57
LVL1::gTower::getET
int getET() const
Get ET (total) in MeV.
Definition: gTower.cxx:142
WriteHandle.h
Handle class for recording to StoreGate.
LVL1::gFEXFPGA::m_noiseCutsDefaultB
gTowersType m_noiseCutsDefaultB
Definition: gFEXFPGA.h:61
beamspotnt.cols
list cols
Definition: bin/beamspotnt.py:1114
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
LVL1::gFEXFPGA::gtCalib
void gtCalib(gTowersType &twrs, const gTowersType &offsets, const gTowersType &noiseCuts, const gTowersType &slopes) const
Definition: gFEXFPGA.cxx:266
LVL1::gFEXFPGA::calLookup
void calLookup(int *tower, const int offset, const int noiseCut, const int slope) const
Definition: gFEXFPGA.cxx:280
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
LVL1::gFEXFPGA::m_offsetsDefaultC
gTowersType m_offsetsDefaultC
Definition: gFEXFPGA.h:64
LVL1::gFEXFPGA::m_gFEXFPGA_gTower50ContainerKey
SG::ReadHandleKey< LVL1::gTowerContainer > m_gFEXFPGA_gTower50ContainerKey
Definition: gFEXFPGA.h:78
test_pyathena.parent
parent
Definition: test_pyathena.py:15
LVL1::gFEXFPGA::m_DBToolKey
SG::ReadCondHandleKey< gFEXDBCondData > m_DBToolKey
Internal data.
Definition: gFEXFPGA.h:52
gFEXFPGA.h
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
LVL1::gFEXFPGA::m_noiseCutsDefaultC
gTowersType m_noiseCutsDefaultC
Definition: gFEXFPGA.h:65
xAOD::gFexTower_v1
Class describing input data of a LVL1 eFEX.
Definition: gFexTower_v1.h:22
beamspotnt.rows
list rows
Definition: bin/beamspotnt.py:1112
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
DataVector::back
const T * back() const
Access the last element in the collection as an rvalue.
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
TrigConf::name
Definition: HLTChainList.h:35
LVL1::gTower::eta
float eta() const
Definition: gTower.h:68
LVL1::gTowersCentral
std::array< std::array< int, 12 >, 32 > gTowersCentral
Definition: IgFEXaltMetAlgo.h:19
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:227
LVL1::gFEXFPGA::calExpand
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
LVL1::gFEXFPGA::m_offsetsDefaultA
gTowersType m_offsetsDefaultA
Definition: gFEXFPGA.h:56
LVL1::gFEXFPGA::initialize
virtual StatusCode initialize() override
standard Athena-Algorithm method
Definition: gFEXFPGA.cxx:34
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
RTTAlgmain.address
address
Definition: RTTAlgmain.py:55
LVL1::gFEXFPGA::m_gFEXFPGA_gTowerContainerKey
SG::ReadHandleKey< LVL1::gTowerContainer > m_gFEXFPGA_gTowerContainerKey
Definition: gFEXFPGA.h:77
LVL1::gFEXFPGA::m_slopesDefaultA
gTowersType m_slopesDefaultA
Definition: gFEXFPGA.h:58
PlotSFuncertainty.calib
calib
Definition: PlotSFuncertainty.py:110
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
convertTimingResiduals.offset
offset
Definition: convertTimingResiduals.py:71
LVL1::gTowersForward
std::array< std::array< int, 8 >, 32 > gTowersForward
Definition: IgFEXaltMetAlgo.h:20
LVL1::gTowersType
std::array< std::array< int, 12 >, 32 > gTowersType
Definition: IgFEXFPGA.h:25
LVL1::gFEXFPGA::init
virtual StatusCode init(int id) override
Definition: gFEXFPGA.cxx:44
LVL1::gFEXFPGA::m_offsetsDefaultB
gTowersType m_offsetsDefaultB
Definition: gFEXFPGA.h:60
ReadHandle.h
Handle class for reading from StoreGate.
AthAlgTool
Definition: AthAlgTool.h:26
LVL1::gFEXFPGA::FillgTowerEDMForward
virtual void FillgTowerEDMForward(SG::WriteHandle< xAOD::gFexTowerContainer > &, gTowersForward &, gTowersForward &, gTowersType &, gTowersType &, gTowersType &) override
Definition: gFEXFPGA.cxx:151
LVL1::gFEXFPGA::m_noiseCutsDefaultA
gTowersType m_noiseCutsDefaultA
Definition: gFEXFPGA.h:57
Eta
@ Eta
Definition: RPCdef.h:8