ATLAS Offline Software
gFEXJwoJAlgo.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 // gFEXJwoJAlg - Jets without jets algorithm for gFEX
6 // -------------------
7 // begin : 21 12 2023
8 // email : cecilia.tosciri@cern.ch
9 //***************************************************************************
10 
11 #include <cmath>
12 #include <vector>
13 
14 #include "gFEXJwoJAlgo.h"
17 #include "L1CaloFEXSim/gTower.h"
18 
19 namespace LVL1 {
20 
21  // default constructor for persistency
22 gFEXJwoJAlgo::gFEXJwoJAlgo(const std::string& type, const std::string& name, const IInterface* parent):
24  {
25  declareInterface<IgFEXJwoJAlgo>(this);
26  }
27 
28 
30 
31  return StatusCode::SUCCESS;
32 
33 }
34 
35 
36 void gFEXJwoJAlgo::setAlgoConstant(int aFPGA_A, int bFPGA_A,
37  int aFPGA_B, int bFPGA_B,
38  int aFPGA_C, int bFPGA_C,
39  int gXE_seedThrA, int gXE_seedThrB, int gXE_seedThrC) {
40  m_aFPGA_A = aFPGA_A;
41  m_bFPGA_A = bFPGA_A;
42  m_aFPGA_B = aFPGA_B;
43  m_bFPGA_B = bFPGA_B;
44  m_aFPGA_C = aFPGA_C;
45  m_bFPGA_C = bFPGA_C;
46  m_gBlockthresholdA = gXE_seedThrA;
47  m_gBlockthresholdB = gXE_seedThrB;
48  m_gBlockthresholdC = gXE_seedThrC;
49 }
50 
51 std::vector<std::unique_ptr<gFEXJwoJTOB>> gFEXJwoJAlgo::jwojAlgo(const gTowersType& Atwr,const gTowersType& Btwr, const gTowersType& Ctwr,
52  std::array<int32_t, 4> & outTOB) const {
53 
54 
55  // input towers have 200 MeV LSB
56  bool SumETfast = true;
57 
58  // find gBlocks
59  gTowersType AgBlk;
60  gTowersType Ascaled;
61 
62  gTowersType BgBlk;
63  gTowersType Bscaled;
64 
65  gTowersType CgBlk;
66  gTowersType Cscaled;
67 
68  gTowersType hasSeed;
69 
70  gBlockAB(Atwr, AgBlk, hasSeed, m_gBlockthresholdA);
71  gBlockAB(Btwr, BgBlk, hasSeed, m_gBlockthresholdB);
72  gBlockAB(Ctwr, CgBlk, hasSeed, m_gBlockthresholdC);
73 
74 
75  // switch to 10 bit number
76  // DMS -- do we eventaully need to check for overflows here?
77 
78  for(int irow = 0; irow<FEXAlgoSpaceDefs::ABCrows; irow++){
79  for(int jcolumn = 0; jcolumn<FEXAlgoSpaceDefs::ABcolumns; jcolumn++){
80  Ascaled[irow][jcolumn] = Atwr[irow][jcolumn] >> 2;
81  AgBlk[irow][jcolumn] = AgBlk[irow][jcolumn] >> 2;
82 
83  Bscaled[irow][jcolumn] = Btwr[irow][jcolumn] >> 2;
84  BgBlk[irow][jcolumn] = BgBlk[irow][jcolumn] >> 2;
85 
86  Cscaled[irow][jcolumn] = Ctwr[irow][jcolumn] >> 2;
87  CgBlk[irow][jcolumn] = CgBlk[irow][jcolumn] >> 2;
88 
89  }
90  }
91 
92 
93  //FPGA A observables
94  int A_MHT_x = 0x0;
95  int A_MHT_y = 0x0;
96  int A_MST_x = 0x0;
97  int A_MST_y = 0x0;
98  int A_MET_x = 0x0;
99  int A_MET_y = 0x0;
100 
101  int A_eth = 0x0;
102  int A_ets = 0x0;
103  int A_etw = 0x0;
104 
105  //FPGA B observables
106  int B_MHT_x = 0x0;
107  int B_MHT_y = 0x0;
108  int B_MST_x = 0x0;
109  int B_MST_y = 0x0;
110  int B_MET_x = 0x0;
111  int B_MET_y = 0x0;
112 
113  int B_eth = 0x0;
114  int B_ets = 0x0;
115  int B_etw = 0x0;
116 
117  //FPGA C observables
118  int C_MHT_x = 0x0;
119  int C_MHT_y = 0x0;
120  int C_MST_x = 0x0;
121  int C_MST_y = 0x0;
122  int C_MET_x = 0x0;
123  int C_MET_y = 0x0;
124 
125  int C_eth = 0x0;
126  int C_ets = 0x0;
127  int C_etw = 0x0;
128 
129  //Global observables
130  int MHT_x = 0x0;
131  int MHT_y = 0x0;
132  int MST_x = 0x0;
133  int MST_y = 0x0;
134  int MET_x = 0x0;
135  int MET_y = 0x0;
136 
137  int ETH = 0x0;
138  int ETS = 0x0;
139  int ETW = 0x0;
140 
141  int total_sumEt = 0x0;
142  int MET = 0x0;
143 
144 
145  // will need to hard code etFPGA ,a's and b's
146  int etBprime =0;
147 
148  metFPGA(0, Ascaled, AgBlk, m_gBlockthresholdA, m_aFPGA_A, m_bFPGA_A, A_MHT_x, A_MHT_y, A_MST_x, A_MST_y, A_MET_x, A_MET_y);
149  if (SumETfast) etFastFPGA(0, Ascaled, AgBlk, m_gBlockthresholdA, m_aFPGA_A, etBprime, A_eth, A_ets, A_etw);
150  else etFPGA(0, Ascaled, AgBlk, m_gBlockthresholdA, m_aFPGA_A, etBprime, A_eth, A_ets, A_etw);
151 
152  metFPGA(1, Bscaled, BgBlk, m_gBlockthresholdB, m_aFPGA_B, m_bFPGA_B, B_MHT_x, B_MHT_y, B_MST_x, B_MST_y, B_MET_x, B_MET_y);
153  if (SumETfast) etFastFPGA(1, Bscaled, BgBlk, m_gBlockthresholdB, m_aFPGA_B, etBprime, B_eth, B_ets, B_etw);
154  else etFPGA(1, Bscaled, BgBlk, m_gBlockthresholdB, m_aFPGA_B, etBprime, B_eth, B_ets, B_etw);
155 
156  metFPGA(2, Cscaled, CgBlk, m_gBlockthresholdC, m_aFPGA_C, m_bFPGA_C, C_MHT_x, C_MHT_y, C_MST_x, C_MST_y, C_MET_x, C_MET_y);
157  if (SumETfast) etFastFPGA(2, Cscaled, CgBlk, m_gBlockthresholdC, m_aFPGA_C, etBprime, C_eth, C_ets, C_etw);
158  else etFPGA(2, Cscaled, CgBlk, m_gBlockthresholdC, m_aFPGA_C, etBprime, C_eth, C_ets, C_etw);
159 
160  metTotal(A_MHT_x, A_MHT_y, B_MHT_x, B_MHT_y, C_MHT_x, C_MHT_y, MHT_x, MHT_y);
161  metTotal(A_MST_x, A_MST_y, B_MST_x, B_MST_y, C_MST_x, C_MST_y, MST_x, MST_y);
162  metTotal(A_MET_x, A_MET_y, B_MET_x, B_MET_y, C_MET_x, C_MET_y, MET_x, MET_y);
163 
164  etTotal(A_eth, B_eth, C_eth, ETH);
165  etTotal(A_ets, B_ets, C_ets, ETS);
166  etTotal(A_etw, B_etw, C_etw, ETW);
167  total_sumEt = ETW;
168 
169  // components should all be less than 12 bits at this point with 200 MeV LSB
170  int MET2 = MET_x * MET_x + MET_y * MET_y;
171 
172  if (MET2 > 0x0FFFFFF) {
173  MET = 0x000FFF;
174  } else {
175  // repeat the byte stream converter calculation here -- not what the hardware actually does
176  MET = std::sqrt(MET2);
177 
178 
179  // best guess at current hardware. Note that this is computed in the bytestream converter
180  // take most signficant 12 bits
181  //int MET12 = MET2 >> 12;
182  // simulate the look up -- only 6 most signficant bits currently set -- to be checked
183  //MET = ( (int)(std::sqrt(MET12)) << 6) & 0x00000FC0 ;
184  }
185 
186 
187  //Define a vector to be filled with all the TOBs of one event
188  std::vector<std::unique_ptr<gFEXJwoJTOB>> tobs_v;
189  tobs_v.resize(4);
190 
191 
192  // fill in TOBs
193  // The order of the TOBs is given according to the TOB ID (TODO: check how it's done in fw)
194 
195  // First TOB is (MET, SumEt)
196  outTOB[0] = (total_sumEt & 0x00000FFF) << 0; //set the Quantity2 to the corresponding slot (LSB)
197  outTOB[0] = outTOB[0] | (MET & 0x00000FFF) << 12;//Quantity 1 (in bit number 12)
198  if (total_sumEt != 0) outTOB[0] = outTOB[0] | 0x00000001 << 24;//Status bit for Quantity 2 (0 if quantity is null)
199  if (MET != 0) outTOB[0] = outTOB[0] | 0x00000001 << 25;//Status bit for Quantity 1 (0 if quantity is null)
200  outTOB[0] = outTOB[0] | (1 & 0x0000001F) << 26;//TOB ID is 1 for scalar values (5 bits starting at 26)
201 
202  // std::cout << "DMS MET " << std::hex << MET << " total_sumEt " << total_sumEt << std::endl << std::dec;
203 
204 // Second TOB is (MET_x, MET_y)
205  outTOB[1] = (MET_y & 0x00000FFF) << 0; //set the Quantity2 to the corresponding slot (LSB)
206  outTOB[1] = outTOB[1] | (MET_x & 0x00000FFF) << 12;//Quantity 1 (in bit number 12)
207  if (MET_y != 0) outTOB[1] = outTOB[1] | 0x00000001 << 24;//Status bit for Quantity 2 (0 if quantity is null)
208  if (MET_x != 0) outTOB[1] = outTOB[1] | 0x00000001 << 25;//Status bit for Quantity 1 (0 if quantity is null)
209  outTOB[1] = outTOB[1] | (2 & 0x0000001F) << 26;//TOB ID is 2 for MET_x, MET_y (5 bits starting at 26)
210 
211 // Third TOB is hard components (MHT_x, MHT_y)
212  outTOB[2] = (MHT_y & 0x00000FFF) << 0; //set the Quantity2 to the corresponding slot (LSB)
213  outTOB[2] = outTOB[2] | (MHT_x & 0x00000FFF) << 12;//Quantity 1 (in bit number 12)
214  if (MHT_y != 0) outTOB[2] = outTOB[2] | 0x00000001 << 24;//Status bit for Quantity 2 (0 if quantity is null)
215  if (MHT_x != 0) outTOB[2] = outTOB[2] | 0x00000001 << 25;//Status bit for Quantity 1 (0 if quantity is null)
216  outTOB[2] = outTOB[2] | (3 & 0x0000001F) << 26;//TOB ID is 3 for hard components (5 bits starting at 26)
217 
218  // Fourth TOB is hard components (MST_x, MST_y)
219  outTOB[3] = (MST_y & 0x00000FFF) << 0; //set the Quantity2 to the corresponding slot (LSB)
220  outTOB[3] = outTOB[3] | (MST_x & 0x00000FFF) << 12;//Quantity 1 (in bit number 12)
221  if (MST_y != 0) outTOB[3] = outTOB[3] | 0x00000001 << 24;//Status bit for Quantity 2 (0 if quantity is null)
222  if (MST_x != 0) outTOB[3] = outTOB[3] | 0x00000001 << 25;//Status bit for Quantity 1 (0 if quantity is null)
223  outTOB[3] = outTOB[3] | (4 & 0x0000001F) << 26;//TOB ID is 4 for soft components (5 bits starting at 26)
224 
225 
226  tobs_v[0] = std::make_unique<gFEXJwoJTOB>();
227  tobs_v[0]->setWord(outTOB[0]);
228  tobs_v[0]->setQuantity1(MET);
229  tobs_v[0]->setQuantity2(total_sumEt);
230  tobs_v[0]->setSaturation(0); //Always 0 for now, need a threshold?
231  tobs_v[0]->setTobID(1);
232  if( MET != 0 ) tobs_v[0]->setStatus1(1);
233  else tobs_v[0]->setStatus1(0);
234  if(total_sumEt!= 0) tobs_v[0]->setStatus2(1);
235  else tobs_v[0]->setStatus2(0);
236 
237  tobs_v[1] = std::make_unique<gFEXJwoJTOB>();
238  tobs_v[1]->setWord(outTOB[1]);
239  tobs_v[1]->setQuantity1(MET_x);
240  tobs_v[1]->setQuantity2(MET_y);
241  tobs_v[1]->setSaturation(0); //Always 0 for now, need a threshold?
242  tobs_v[1]->setTobID(2);
243  if( MET_x != 0 ) tobs_v[1]->setStatus1(1);
244  else tobs_v[1]->setStatus1(0);
245  if(MET_y!= 0) tobs_v[1]->setStatus2(1);
246  else tobs_v[1]->setStatus2(0);
247 
248  tobs_v[2] = std::make_unique<gFEXJwoJTOB>();
249  tobs_v[2]->setWord(outTOB[2]);
250  tobs_v[2]->setQuantity1(MHT_x);
251  tobs_v[2]->setQuantity2(MHT_y);
252  tobs_v[2]->setSaturation(0); //Always 0 for now, need a threshold?
253  tobs_v[2]->setTobID(3);
254  if( MHT_x != 0 ) tobs_v[2]->setStatus1(1);
255  else tobs_v[2]->setStatus1(0);
256  if(MHT_y!= 0) tobs_v[2]->setStatus2(1);
257  else tobs_v[2]->setStatus2(0);
258 
259  tobs_v[3] = std::make_unique<gFEXJwoJTOB>();
260  tobs_v[3]->setWord(outTOB[3]);
261  tobs_v[3]->setQuantity1(MST_x);
262  tobs_v[3]->setQuantity2(MST_y);
263  tobs_v[3]->setSaturation(0); //Always 0 for now, need a threshold?
264  tobs_v[3]->setTobID(4);
265  if( MST_x != 0 ) tobs_v[3]->setStatus1(1);
266  else tobs_v[2]->setStatus1(0);
267  if(MST_y!= 0) tobs_v[3]->setStatus2(1);
268  else tobs_v[3]->setStatus2(0);
269 
270 
271  return tobs_v;
272 
273 }
274 
275 
276 
277 void gFEXJwoJAlgo::gBlockAB(const gTowersType & twrs, gTowersType & gBlkSum, gTowersType & hasSeed, int seedThreshold) const {
278 
279  int rows = twrs.size();
280  int cols = twrs[0].size();
281  for( int irow = 0; irow < rows; irow++ ){
282  for(int jcolumn = 0; jcolumn<cols; jcolumn++){
283  // zero jet sum here
284  gBlkSum[irow][jcolumn] = 0;
285  int krowUp = (irow + 1)%32;
286  int krowDn = (irow - 1 +32)%32;
287  if( (jcolumn == 0) || (jcolumn == 6) ) {
288  //left edge case
289  gBlkSum[irow][jcolumn] =
290  twrs[irow][jcolumn] + twrs[krowUp][jcolumn] + twrs[krowDn][jcolumn] +
291  twrs[irow][jcolumn+1] + twrs[krowUp][jcolumn+1] + twrs[krowDn][jcolumn+1];
292  } else if( (jcolumn == 5) || (jcolumn == 11)) {
293  // right edge case
294  gBlkSum[irow][jcolumn] =
295  twrs[irow][jcolumn] + twrs[krowUp][jcolumn] + twrs[krowDn][jcolumn] +
296  twrs[irow][jcolumn-1] + twrs[krowUp][jcolumn-1] + twrs[krowDn][jcolumn-1];
297  } else{
298  // normal case
299  gBlkSum[irow][jcolumn] =
300  twrs[irow][jcolumn] + twrs[krowUp][jcolumn] + twrs[krowDn][jcolumn] +
301  twrs[irow][jcolumn-1] + twrs[krowUp][jcolumn-1] + twrs[krowDn][jcolumn-1] +
302  twrs[irow][jcolumn+1] + twrs[krowUp][jcolumn+1] + twrs[krowDn][jcolumn+1];
303  }
304 
305  if( gBlkSum[irow][jcolumn] > seedThreshold) {
306  hasSeed[irow][jcolumn] = 1;
307  } else {
308  hasSeed[irow][jcolumn] = 0;
309  }
310 
311  if ( gBlkSum[irow][jcolumn] < 0 )
312  gBlkSum[irow][jcolumn] = 0;
313 
314  // was bits 11+3 downto 3, now is 11 downto 0
315  if ( gBlkSum[irow][jcolumn] > FEXAlgoSpaceDefs::gBlockMax ) {
316  gBlkSum[irow][jcolumn] = FEXAlgoSpaceDefs::gBlockMax;
317  }
318  }
319  }
320 }
321 
322 
323 void gFEXJwoJAlgo::metFPGA(int FPGAnum, const gTowersType& twrs,
324  const gTowersType & gBlkSum, int gBlockthreshold,
325  int aFPGA, int bFPGA,
326  int & MHT_x, int & MHT_y,
327  int & MST_x, int & MST_y,
328  int & MET_x, int & MET_y) const {
329 
330  gBlockthreshold = gBlockthreshold * 200 / 800; //gBlockthreshold is provided in counts with a resolution of 200 MeV, but here needs to be applied with a resolution of 800 GeV
331  // in the RTL code these are 19+ 5 = 24 bits
332  int64_t h_tx_hi = 0;
333  int64_t h_ty_hi = 0;
334  int64_t h_tx_lw = 0;
335  int64_t h_ty_lw = 0;
336 
337  int64_t e_tx_hi = 0;
338  int64_t e_ty_hi = 0;
339  int64_t e_tx_lw = 0;
340  int64_t e_ty_lw = 0;
341 
342  for( int irow = 0; irow < FEXAlgoSpaceDefs::ABCrows; irow++ ){
343  for(int jcolumn = 6; jcolumn<12; jcolumn++){
344  if( FPGAnum == 2){
345  int frow = 2*(irow/2) + 1;
346 
347  if(gBlkSum[irow][jcolumn] > gBlockthreshold){
348  h_tx_hi += (twrs[irow][jcolumn])*(cosLUT(frow, 5));
349  h_ty_hi += (twrs[irow][jcolumn])*(sinLUT(frow, 5));
350  } else {
351  e_tx_hi += (twrs[irow][jcolumn])*(cosLUT(frow, 5));
352  e_ty_hi += (twrs[irow][jcolumn])*(sinLUT(frow, 5));
353  }
354 
355  } else {
356 
357  if(gBlkSum[irow][jcolumn] > gBlockthreshold){
358  h_tx_hi += (twrs[irow][jcolumn])*(cosLUT(irow, 5));
359  h_ty_hi += (twrs[irow][jcolumn])*(sinLUT(irow, 5));
360  } else {
361  e_tx_hi += (twrs[irow][jcolumn])*(cosLUT(irow, 5));
362  e_ty_hi += (twrs[irow][jcolumn])*(sinLUT(irow, 5));
363  }
364  }
365  }
366 
367  for(int jcolumn = 0; jcolumn<6; jcolumn++){
368  if( FPGAnum == 2){
369  int frow = 2*(irow/2) + 1;
370 
371  if(gBlkSum[irow][jcolumn] > gBlockthreshold){
372  h_tx_lw += (twrs[irow][jcolumn])*(cosLUT(frow, 5));
373  h_ty_lw += (twrs[irow][jcolumn])*(sinLUT(frow, 5));
374  } else{
375  e_tx_lw += (twrs[irow][jcolumn])*(cosLUT(frow, 5));
376  e_ty_lw += (twrs[irow][jcolumn])*(sinLUT(frow, 5));
377  }
378  } else {
379 
380  if(gBlkSum[irow][jcolumn] > gBlockthreshold){
381  h_tx_lw += (twrs[irow][jcolumn])*(cosLUT(irow, 5));
382  h_ty_lw += (twrs[irow][jcolumn])*(sinLUT(irow, 5));
383  } else {
384  e_tx_lw += (twrs[irow][jcolumn])*(cosLUT(irow, 5));
385  e_ty_lw += (twrs[irow][jcolumn])*(sinLUT(irow, 5));
386  }
387  }
388  }
389  }
390 
391  // According to https://gitlab.cern.ch/atlas-l1calo/gfex/firmware/-/issues/406#note_5662344
392  // there is no division -- so LSB is indeed 25 MeV
393 
394  //but later changed to 200 MeV so divide by 8
395 
396  long int fMHT_x = (h_tx_hi + h_tx_lw) ;
397  long int fMHT_y = (h_ty_hi + h_ty_lw) ;
398  long int fMST_x = (e_tx_hi + e_tx_lw) ;
399  long int fMST_y = (e_ty_hi + e_ty_lw) ;
400 
401  MHT_x = (h_tx_hi + h_tx_lw) >> 3;
402  MHT_y = (h_ty_hi + h_ty_lw) >> 3;
403  MST_x = (e_tx_hi + e_tx_lw) >> 3;
404  MST_y = (e_ty_hi + e_ty_lw) >> 3;
405 
406  // a and b coffecients are 10 bits
407  // multiplication has an addtional 2^10
408  // constant JWJ_OW : integer := 35;--Out width
409  // values are 35 bits long and top 16 bits are taken -- so divide by 2^19
410  // 2^10/2^19 = 1/2^9 = 1/512
411 
412  long int fMET_x = ( aFPGA * (fMHT_x) + bFPGA * (fMST_x) ) >> 13 ;
413  long int fMET_y = ( aFPGA * (fMHT_y) + bFPGA * (fMST_y) ) >> 13 ;
414 
415  MET_x = fMET_x;
416  MET_y = fMET_y;
417 
418 }
419 
420 void gFEXJwoJAlgo::etFPGA(int FPGAnum, const gTowersType& twrs, gTowersType &gBlkSum,
421  int gBlockthreshold, int A, int B, int &eth, int &ets, int &etw) const {
422 
423  gBlockthreshold = gBlockthreshold * 200 / 800; //gBlockthreshold is provided in counts with a resolution of 200 MeV, but here needs to be applied with a resolution of 800 GeV
424 
425  int64_t ethard_hi = 0;
426  int64_t etsoft_hi = 0;
427  int64_t ethard_lo = 0;
428  int64_t etsoft_lo = 0;
429 
430  int64_t ethard = 0.0;
431  int64_t etsoft = 0.0;
432 
433  int multiplicitiveFactor = 0;
434 
435  if(FPGAnum < 2 ) {
436  multiplicitiveFactor = cosLUT(0, 5);
437  } else{
438  multiplicitiveFactor = cosLUT(1, 5);
439  }
440 
441 // firmware treats upper and lower columns differnetly
442 
443  for( int irow = 0; irow < FEXAlgoSpaceDefs::ABCrows; irow++ ){
444  for(int jcolumn = 0; jcolumn<6; jcolumn++){
445  if(gBlkSum[irow][jcolumn] > gBlockthreshold){
446  ethard_lo = ethard_lo + twrs[irow][jcolumn]*multiplicitiveFactor;
447  } else {
448  etsoft_lo = etsoft_lo + twrs[irow][jcolumn]*multiplicitiveFactor;
449  }
450  }
451  }
452 
453  for( int irow = 0; irow < FEXAlgoSpaceDefs::ABCrows; irow++ ){
454  for(int jcolumn = 6; jcolumn<12; jcolumn++){
455  if(gBlkSum[irow][jcolumn] > gBlockthreshold){
456  ethard_hi = ethard_hi + twrs[irow][jcolumn]*multiplicitiveFactor;
457  } else {
458  etsoft_hi = etsoft_hi + twrs[irow][jcolumn]*multiplicitiveFactor;
459  }
460  }
461  }
462 
463  ethard = ethard_hi + ethard_lo;
464 
465  etsoft = etsoft_hi + etsoft_lo;
466 
467 
468  int64_t etsum_hi = ethard_hi*A + etsoft_hi*B ;
469  if ( etsum_hi < 0 ) etsum_hi = 0;
470 
471  int64_t etsum_lo = ethard_lo*A + etsoft_lo*B ;
472  if ( etsum_lo < 0 ) etsum_lo = 0;
473 
474  int64_t etsum = etsum_hi + etsum_lo;
475 
476 
477  // convert 200 MeV LSB here
478  eth = ethard>>3;
479  ets = etsoft>>3;
480  etw = (etsum >>13 ) ;
481 
482  if( etw < 0 ) etw = 0;
483  // max value is 15 bits with 800 MeV LSB -- so 17 bits here
484  if( etw > 0X001FFFF ) etw = 0X001FFFF ;
485 
486 
487  if(msgLvl(MSG::DEBUG)) {
488  std::cout << "DMS FPGA gTEJWOJ " << std::hex << FPGAnum << "et sum hard " << eth << "etsum soft" << ets << " A " << A << " B " << B << " weighted term " << etw << std::endl << std::dec;
489  }
490 }
491 
492 void gFEXJwoJAlgo::etFastFPGA(int FPGAnum, const gTowersType& twrs, gTowersType &gBlkSum,
493  int gBlockthreshold, int A, int B, int &eth, int &ets, int &etw) const {
494 
495  gBlockthreshold = gBlockthreshold * 200 / 800; //gBlockthreshold is provided in counts with a resolution of 200 MeV, but here needs to be applied with a resolution of 800 GeV
496  int64_t ethard_hi = 0;
497  int64_t etsoft_hi = 0;
498  int64_t ethard_lo = 0;
499  int64_t etsoft_lo = 0;
500 
501  int64_t ethard = 0.0;
502  int64_t etsoft = 0.0;
503 
504  // firmware treats upper and lower columns differently
505  for( int irow = 0; irow < FEXAlgoSpaceDefs::ABCrows; irow++ ){
506  for(int jcolumn = 0; jcolumn<6; jcolumn++){
507  if(gBlkSum[irow][jcolumn] > gBlockthreshold){
508  ethard_lo = ethard_lo + twrs[irow][jcolumn];
509  }
510  else {
511  etsoft_lo = etsoft_lo + twrs[irow][jcolumn];
512  }
513  }
514  }
515 
516  for( int irow = 0; irow < FEXAlgoSpaceDefs::ABCrows; irow++ ){
517  for(int jcolumn = 6; jcolumn<12; jcolumn++){
518  if(gBlkSum[irow][jcolumn] > gBlockthreshold){
519  ethard_hi = ethard_hi + twrs[irow][jcolumn];
520  }
521  else {
522  etsoft_hi = etsoft_hi + twrs[irow][jcolumn];
523  }
524  }
525  }
526 
527  ethard = ethard_hi + ethard_lo;
528  etsoft = etsoft_hi + etsoft_lo;
529 
530  // convert 200 MeV LSB here
531  eth = ethard;
532  ets = etsoft; // Keep for reference -- not used in etFast
533  etw = ethard; // For EtFast the weighted term is just the hard term
534 
535  // 16 bits signed, set max and min
536  if( etw < -32768 ) etw = -32768;
537  if( etw > 32767 ) etw = 32767;
538 
539  if(msgLvl(MSG::DEBUG)) {
540  std::cout << "DMS FPGA gTEJWOJ " << std::hex << FPGAnum << "et sum hard " << eth << "etsum soft" << ets << " A " << A << " B " << B << " weighted term " << etw << std::endl << std::dec;
541  }
542 }
543 
544 void gFEXJwoJAlgo::metTotal(int A_MET_x, int A_MET_y,
545  int B_MET_x, int B_MET_y,
546  int C_MET_x, int C_MET_y,
547  int & MET_x, int & MET_y) const {
548 
549 
550  MET_x = A_MET_x + B_MET_x + C_MET_x;
551  MET_y = A_MET_y + B_MET_y+ C_MET_y;
552 
553  // Truncation of the result, as the individual quantities are 16 bits, while the TOB field is 12 bits
554  // MET_x = MET_x >> 4;
555  // MET_y = MET_y >> 4;
556 
557  if (MET_x < -0x000800) MET_x = -0x000800; //-2048
558  if (MET_y < -0x000800) MET_y = -0x000800; //-2048
559 
560  if (MET_x > 0x0007FF) MET_x = 0x0007FF; //2047
561  if (MET_y > 0x0007FF) MET_y = 0x0007FF; //2047
562 
563 }
564 
565 void gFEXJwoJAlgo::etTotal(int A_ET,
566  int B_ET,
567  int C_ET,
568  int & ET ) const {
569 
570  // leave at 200 MeV scale
571  if (A_ET < 0 ) A_ET = 0;
572  if (B_ET < 0 ) B_ET = 0;
573  if (C_ET < 0 ) C_ET = 0;
574 
575  ET = (A_ET + B_ET + C_ET) ;
576 
577  // main value of ET is always positive
578  if( ET > 0x0000FFF) ET = 0x0000FFF;
579 
580 }
581 
582 //----------------------------------------------------------------------------------
583 // bitwise simulation of sine LUT in firmware
584 //----------------------------------------------------------------------------------
585 float gFEXJwoJAlgo::sinLUT(unsigned int phiIDX, unsigned int aw) const
586 {
587  float c = static_cast<float>(phiIDX)/std::pow(2,aw);
588  float rad = (2*M_PI) *c;
589  float rsin = std::sin(rad);
590  int isin = std::round(rsin*(std::pow(2,aw) - 1));
591  return isin;
592 
593 }
594 
595 //----------------------------------------------------------------------------------
596 // bitwise simulation cosine LUT in firmware
597 //----------------------------------------------------------------------------------
598 float gFEXJwoJAlgo::cosLUT(unsigned int phiIDX, unsigned int aw) const
599 {
600  float c = static_cast<float>(phiIDX)/std::pow(2,aw);
601  float rad = (2*M_PI) *c;
602  float rcos = std::cos(rad);
603  int icos = std::round(rcos*(std::pow(2,aw) - 1));
604  return icos;
605 }
606 
607 } // namespace LVL1
LVL1::gFEXJwoJAlgo::m_bFPGA_C
float m_bFPGA_C
Definition: gFEXJwoJAlgo.h:52
LVL1::gFEXJwoJAlgo::metTotal
void metTotal(int A_MET_x, int A_MET_y, int B_MET_x, int B_MET_y, int C_MET_x, int C_MET_y, int &MET_x, int &MET_y) const
Definition: gFEXJwoJAlgo.cxx:544
LVL1::gFEXJwoJAlgo::m_aFPGA_A
float m_aFPGA_A
Definition: gFEXJwoJAlgo.h:47
LVL1::gFEXJwoJAlgo::m_bFPGA_A
float m_bFPGA_A
Definition: gFEXJwoJAlgo.h:48
LVL1::gFEXJwoJAlgo::m_aFPGA_B
float m_aFPGA_B
Definition: gFEXJwoJAlgo.h:49
gTowerContainer.h
MuonGM::round
float round(const float toRound, const unsigned int decimals)
Definition: Mdt.cxx:27
M_PI
#define M_PI
Definition: ActiveFraction.h:11
AthCommonMsg< AlgTool >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
LVL1::gFEXJwoJAlgo::m_gBlockthresholdB
float m_gBlockthresholdB
Definition: gFEXJwoJAlgo.h:54
LVL1::gFEXJwoJAlgo::metFPGA
void metFPGA(int FPGAnum, const gTowersType &twrs, const gTowersType &gBlkSum, int gBlockthreshold, int aFPGA, int bFPGA, int &MHT_x, int &MHT_y, int &MST_x, int &MST_y, int &MET_x, int &MET_y) const
Definition: gFEXJwoJAlgo.cxx:323
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
LVL1
eFexTowerBuilder creates xAOD::eFexTowerContainer from supercells (LATOME) and triggerTowers (TREX) i...
Definition: ICMMCPHitsCnvTool.h:18
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
LVL1::gFEXJwoJAlgo::setAlgoConstant
virtual void setAlgoConstant(int aFPGA_A, int bFPGA_A, int aFPGA_B, int bFPGA_B, int aFPGA_C, int bFPGA_C, int gXE_seedThrA, int gXE_seedThrB, int gXE_seedThrC) override
Definition: gFEXJwoJAlgo.cxx:36
LVL1::gFEXJwoJAlgo::gBlockAB
void gBlockAB(const gTowersType &twrs, gTowersType &gBlkSum, gTowersType &hasSeed, int seedThreshold) const
Definition: gFEXJwoJAlgo.cxx:277
gFEXJwoJTOB.h
LVL1::gFEXJwoJAlgo::cosLUT
float cosLUT(unsigned int phiIDX, unsigned int aw) const
Definition: gFEXJwoJAlgo.cxx:598
beamspotnt.cols
list cols
Definition: bin/beamspotnt.py:1113
A
LVL1::gFEXJwoJAlgo::m_gBlockthresholdA
float m_gBlockthresholdA
Definition: gFEXJwoJAlgo.h:53
LVL1::gFEXJwoJAlgo::jwojAlgo
virtual std::vector< std::unique_ptr< gFEXJwoJTOB > > jwojAlgo(const gTowersType &Atwr, const gTowersType &Btwr, const gTowersType &Ctwr, std::array< int32_t, 4 > &outTOB) const override
Definition: gFEXJwoJAlgo.cxx:51
LVL1::gFEXJwoJAlgo::etFPGA
void etFPGA(int FPGAnum, const gTowersType &twrs, gTowersType &gBlkSum, int gBlockthreshold, int A, int B, int &eth, int &ets, int &etw) const
Definition: gFEXJwoJAlgo.cxx:420
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
LVL1::gFEXJwoJAlgo::m_aFPGA_C
float m_aFPGA_C
Definition: gFEXJwoJAlgo.h:51
test_pyathena.parent
parent
Definition: test_pyathena.py:15
LVL1::gFEXJwoJAlgo::etFastFPGA
void etFastFPGA(int FPGAnum, const gTowersType &twrs, gTowersType &gBlkSum, int gBlockthreshold, int A, int B, int &eth, int &ets, int &etw) const
Definition: gFEXJwoJAlgo.cxx:492
beamspotnt.rows
list rows
Definition: bin/beamspotnt.py:1111
python.SystemOfUnits.rad
float rad
Definition: SystemOfUnits.py:126
LVL1::gFEXJwoJAlgo::gFEXJwoJAlgo
gFEXJwoJAlgo(const std::string &type, const std::string &name, const IInterface *parent)
Constructors.
Definition: gFEXJwoJAlgo.cxx:22
TrigConf::name
Definition: HLTChainList.h:35
LVL1::gFEXJwoJAlgo::etTotal
void etTotal(int A_ET, int B_ET, int C_ET, int &ET) const
Definition: gFEXJwoJAlgo.cxx:565
gFEXJwoJAlgo.h
LVL1::FEXAlgoSpaceDefs::ABcolumns
constexpr static int ABcolumns
Definition: FEXAlgoSpaceDefs.h:158
LVL1::FEXAlgoSpaceDefs::gBlockMax
constexpr static int gBlockMax
Definition: FEXAlgoSpaceDefs.h:161
MET
Definition: MET.py:1
LVL1::FEXAlgoSpaceDefs::ABCrows
constexpr static int ABCrows
Definition: FEXAlgoSpaceDefs.h:157
LVL1::gFEXJwoJAlgo::initialize
virtual StatusCode initialize() override
standard Athena-Algorithm method
Definition: gFEXJwoJAlgo.cxx:29
DEBUG
#define DEBUG
Definition: page_access.h:11
LVL1::gFEXJwoJAlgo::sinLUT
float sinLUT(unsigned int phiIDX, unsigned int aw) const
Definition: gFEXJwoJAlgo.cxx:585
LVL1::gTowersType
std::array< std::array< int, 12 >, 32 > gTowersType
Definition: IgFEXFPGA.h:25
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
AthAlgTool
Definition: AthAlgTool.h:26
LVL1::gFEXJwoJAlgo::m_gBlockthresholdC
float m_gBlockthresholdC
Definition: gFEXJwoJAlgo.h:55
gTower.h
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
python.compressB64.c
def c
Definition: compressB64.py:93
LVL1::gFEXJwoJAlgo::m_bFPGA_B
float m_bFPGA_B
Definition: gFEXJwoJAlgo.h:50