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