ATLAS Offline Software
gFexInputByteStreamTool.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 //***************************************************************************
6 // gFexInputByteStreamTool - This tool decodes Run3 gFEX input data!
7 // -------------------
8 // begin : 10 08 2022
9 // email : cecilia.tosciri@cern.ch
10 // ***************************************************************************/
11 
13 #include "gFexPos.h"
14 #include "eformat/SourceIdentifier.h"
15 #include "eformat/Status.h"
16 
17 #include <span>
18 
21 
22 namespace gPos = LVL1::gFEXPos;
23 
24 
26  const std::string& name,
27  const IInterface* parent)
28  : base_class(type, name, parent) {}
29 
31 
32  ATH_MSG_DEBUG(" ROB IDs: " << MSG::hex << m_robIds.value() << MSG::dec);
33 
34  // Conversion mode for gTowers
35  ConversionMode gTowersmode = getConversionMode(m_gTowersReadKey, m_gTowersWriteKey, msg());
37  ATH_CHECK(m_gTowersWriteKey.initialize(gTowersmode==ConversionMode::Decoding));
38  ATH_CHECK(m_gTowers50WriteKey.initialize(gTowersmode==ConversionMode::Decoding));
39  ATH_CHECK(m_gTowersReadKey.initialize(gTowersmode==ConversionMode::Encoding));
40  ATH_MSG_DEBUG((gTowersmode==ConversionMode::Encoding ? "Encoding" : "Decoding") << " gTowers ");
41 
42  // Initialize monitoring tool if not empty
43  if (!m_monTool.empty()) {
44  ATH_CHECK(m_monTool.retrieve());
45  ATH_MSG_INFO("Logging errors to " << m_monTool.name() << " monitoring tool");
46  m_UseMonitoring = true;
47  }
48 
49 
50  return StatusCode::SUCCESS;
51 }
52 
53 // BS->xAOD conversion
54 StatusCode gFexInputByteStreamTool::convertFromBS(const std::vector<const ROBF*>& vrobf, const EventContext& ctx) const {
55 
56  //WriteHandle for gFEX EDMs
57 
58  //---gTower EDM
60  ATH_CHECK(gTowersContainer.record(std::make_unique<xAOD::gFexTowerContainer>(), std::make_unique<xAOD::gFexTowerAuxContainer>()));
61  ATH_MSG_DEBUG("Recorded gFexTowerContainer (200 MeV resolution, default) with key " << gTowersContainer.key());
62 
64  ATH_CHECK(gTowers50Container.record(std::make_unique<xAOD::gFexTowerContainer>(), std::make_unique<xAOD::gFexTowerAuxContainer>()));
65  ATH_MSG_DEBUG("Recorded gFexTower50Container (50 MeV resolution) with key " << gTowers50Container.key());
66 
67  // Iterate over ROBFragments to decode
68  for (const ROBF* rob : vrobf) {
69  // Iterate over ROD words and decode
70 
71 
72  ATH_MSG_DEBUG("Starting to decode " << rob->rod_ndata() << " ROD words from ROB 0x" << std::hex << rob->rob_source_id());
73  //There is no data to decode.. not even the ROD trailers
74  if(rob->rod_ndata() <= 0){
75  continue;
76  }
77 
78  const auto dataArray = std::span{rob->rod_data(), rob->rod_ndata()};
79 
80  // Starting to loop over the gFEX words
81 
82  unsigned int n_words = rob->rod_ndata();
83 
84  int fpga = -99; //FPGA number 0,1,2 -> A,B,C
85  int fpgaPosition = -99; //Position of the FPGA header in the dataframe
86 
87  // Preparing input fiber arrays to be used as input to the routine
88  // for converting fiber information into towers
89  gfiber Afiber = {{{0}}};
90  gfiber Bfiber = {{{0}}};
91  gfiber Cfiber = {{{0}}};
92 
93  gfiber AMapped = {{{0}}};
94  gfiber BMapped = {{{0}}};
95  gfiber CMapped = {{{0}}};
96 
97  int rows = Afiber.size();
98  int cols = Afiber[0].size();
99 
100  // Loop over the 32-bit words to extract words relative to each FPGA
101  // Put 100x7 words available for each FPGA in corresponding arrays
102  for(unsigned int iWord=0; iWord<n_words; iWord++) {
103  if (dataArray[iWord] == gPos::FPGA_A_INPUT_HEADER){
104  fpga = 0;
105  fpgaPosition = iWord;
106  }
107  else if (dataArray[iWord] == gPos::FPGA_B_INPUT_HEADER) {
108  fpga = 1;
109  fpgaPosition = iWord;
110  }
111  else if (dataArray[iWord] == gPos::FPGA_C_INPUT_HEADER) {
112  fpga = 2;
113  fpgaPosition = iWord;
114  }
115  else continue;
116 
117 
118  if (fpga == 0){
119  for (int irow = 0; irow < rows; irow++){
120  for (int icol = 0; icol < cols; icol++){
121  Afiber[irow][icol] = dataArray[fpgaPosition + (7*irow) + 1 + icol];
122  }
123  }
124  }
125 
126  if (fpga == 1){
127  for (int irow = 0; irow < rows; irow++){
128  for (int icol = 0; icol < cols; icol++){
129  Bfiber[irow][icol] = dataArray[fpgaPosition + (7*irow) + 1 + icol];
130  }
131  }
132  }
133 
134  if (fpga == 2){
135  for (int irow = 0; irow < rows; irow++){
136  for (int icol = 0; icol < cols; icol++){
137  Cfiber[irow][icol] = dataArray[fpgaPosition + (7*irow) + 1 + icol];
138  }
139  }
140  }
141  }
142 
143  // For each FPGA we resemble the fibers->gTowers used in hardware
144  // Atwr, Btwr, Ctwr will contain towers for each FPGA
145  gtFPGA Atwr = {{{0}}};
146  gtFPGA Btwr = {{{0}}};
147  gtFPGA Ctwr = {{{0}}};
148 
149  gtFPGA AtwrF = {{{0}}};
150  gtFPGA BtwrF = {{{0}}};
151  gtFPGA CtwrF = {{{0}}};
152 
153  gtFPGA Asatur = {{{0}}};
154  gtFPGA Bsatur = {{{0}}};
155  gtFPGA Csatur = {{{0}}};
156 
157  a_gtrx_map(Afiber, AMapped);
158 
159  int fpgaA = 0;
160  int fBcidA = -1;
161  int do_lconv = 1;
162 
163  gtReconstructABC(fpgaA,
164  AMapped, // input fibers AB_FIBER = 80 > C fibers
166  AtwrF,
167  Atwr,
168  &fBcidA,
169  do_lconv, // flag to indicate multilinear conversion
175  gPos::AMSK,
176  Asatur );
177 
178  gtCalib(Atwr,200, 0,gPos::CAL_OFF);
179 
180 
181  b_gtrx_map(Bfiber, BMapped);
182 
183  int fpgaB = 1;
184  int fBcidB = -1;
185 
186  gtReconstructABC( fpgaB,
187  BMapped, gPos::AB_FIBERS,
188  BtwrF,
189  Btwr,
190  &fBcidB,
191  do_lconv,
197  gPos::BMSK,
198  Bsatur );
199 
200  gtCalib(Btwr,200, 0,gPos::CAL_OFF);
201 
202  c_gtrx_map(Cfiber, CMapped);
203 
204  int fpgaC = 2;
205  int fBcidC = -1;
206 
207  gtReconstructABC( fpgaC,
208  CMapped, gPos::C_FIBERS,
209  CtwrF,
210  Ctwr,
211  &fBcidC,
212  do_lconv,
218  gPos::CMSK,
219  Csatur );
220 
221  gtCalib(Ctwr,200, 0,gPos::CAL_OFF);
222 
223  // Fill the gTower EDM with the corresponding towers
224  int iEta = 0;
225  int iPhi = 0;
226  float Eta = 0;
227  float Phi = 0;
228  int Et = 0;
229  int EtF = 0;
230  int Fpga = 0;
231  char IsSaturated = 0;
232  int towerID = 0;
233 
234  // Assign ID based on FPGA (FPGA-A 0->0; FPGA-B 1->10000, FPGA-C 2->20000) and gTower number assigned as per firmware convention
235 
236 
237  int twr_rows = Atwr.size();
238  int twr_cols = Atwr[0].size();
239 
240  Fpga = 0;
241 
242  // Save towers from FPGA A in gTower EDM
243  for (int irow = 0; irow < twr_rows; irow++){
244  for (int icol = 0; icol < twr_cols; icol++){
245  iEta = icol + 8;
246  iPhi = irow;
247  Et = Atwr[irow][icol];
248  EtF = AtwrF[irow][icol];
249  IsSaturated = Asatur[irow][icol];
250 
251  getEtaPhi(Eta, Phi, iEta, iPhi, towerID);
252  gTowersContainer->push_back( std::make_unique<xAOD::gFexTower>() );
253  gTowersContainer->back()->initialize(iEta, iPhi, Eta, Phi, Et, Fpga, IsSaturated, towerID);
254  gTowers50Container->push_back( std::make_unique<xAOD::gFexTower>() );
255  gTowers50Container->back()->initialize(iEta, iPhi, Eta, Phi, EtF, Fpga, IsSaturated, towerID);
256  towerID += 1;
257 
258  }
259  }
260 
261  // Save towers from FPGA B in gTower EDM
262  Fpga = 1;
263  towerID = 10000;
264  // Save towers from FPGA B in gTower EDM
265  for (int irow = 0; irow < twr_rows; irow++){
266  for (int icol = 0; icol < twr_cols; icol++){
267  iEta = icol + 20;
268  iPhi = irow;
269  Et = Btwr[irow][icol];
270  EtF = BtwrF[irow][icol];
271  IsSaturated = Bsatur[irow][icol];
272  getEtaPhi(Eta, Phi, iEta, iPhi, towerID);
273  gTowersContainer->push_back( std::make_unique<xAOD::gFexTower>() );
274  gTowersContainer->back()->initialize(iEta, iPhi, Eta, Phi, Et, Fpga, IsSaturated, towerID);
275  gTowers50Container->push_back( std::make_unique<xAOD::gFexTower>() );
276  gTowers50Container->back()->initialize(iEta, iPhi, Eta, Phi, EtF, Fpga, IsSaturated, towerID);
277  towerID += 1;
278 
279  }
280  }
281 
282  // Save towers from FPGA C in gTower EDM
283  Fpga = 2;
284  towerID = 20000;
285  for (int irow = 0; irow < twr_rows; irow++){
286  for (int icol = 0; icol < twr_cols/2; icol++){
287  iEta = icol + 2;
288  iPhi = irow;
289  Et = Ctwr[irow][icol];
290  EtF = CtwrF[irow][icol];
291  IsSaturated = Csatur[irow][icol];
292  getEtaPhi(Eta, Phi, iEta, iPhi, towerID);
293  gTowersContainer->push_back( std::make_unique<xAOD::gFexTower>() );
294  gTowersContainer->back()->initialize(iEta, iPhi, Eta, Phi, Et, Fpga, IsSaturated, towerID);
295  gTowers50Container->push_back( std::make_unique<xAOD::gFexTower>() );
296  gTowers50Container->back()->initialize(iEta, iPhi, Eta, Phi, EtF, Fpga, IsSaturated, towerID);
297  towerID += 1;
298  }
299  for (int icol = twr_cols/2; icol < twr_cols; icol++){
300  iEta = icol + 26;
301  iPhi = irow;
302  Et = Ctwr[irow][icol];
303  EtF = CtwrF[irow][icol];
304  IsSaturated = Csatur[irow][icol];
305  getEtaPhi(Eta, Phi, iEta, iPhi, towerID);
306  gTowersContainer->push_back( std::make_unique<xAOD::gFexTower>() );
307  gTowersContainer->back()->initialize(iEta, iPhi, Eta, Phi, Et, Fpga, IsSaturated, towerID);
308  gTowers50Container->push_back( std::make_unique<xAOD::gFexTower>() );
309  gTowers50Container->back()->initialize(iEta, iPhi, Eta, Phi, EtF, Fpga, IsSaturated, towerID);
310  towerID += 1;
311 
312  }
313  }
314 
315 
316  }
317 
318  return StatusCode::SUCCESS;
319 }
320 
321 
322 
323 
324 void gFexInputByteStreamTool::a_gtrx_map( const gfiber &inputData, gfiber &jf_lar_rx_data) const{
325 
326  int rows = inputData.size();
327  int cols = inputData[0].size();
328 
329  for(int i = 0; i < rows; i++){
330  for (int j=0; j< cols; j++){
331  if(i < 80) {
332  jf_lar_rx_data[i][j] = inputData[gPos::GTRX_MAP_A_IND[i]][j];
333  }
334  else if (j<cols-1){
335  jf_lar_rx_data[i][j] = 0;
336  }
337  else {
338  jf_lar_rx_data[i][j] = (inputData[0][0] & 0x03F0000);
339  }
340  }
341  }
342 }
343 
344 
345 void gFexInputByteStreamTool::b_gtrx_map( const gfiber &inputData, gfiber &jf_lar_rx_data) const{
346 
347  int rows = inputData.size();
348  int cols = inputData[0].size();
349 
350  for(int i =0; i< rows; i++){
351  for (int j=0; j< cols; j++){
352  if( i< 80) {
353  jf_lar_rx_data[i][j] = inputData[gPos::GTRX_MAP_B_IND[i]][j];
354  }
355  else if (j<cols-1){
356  jf_lar_rx_data[i][j] = 0;
357  }
358  else {
359  jf_lar_rx_data[i][j] = (inputData[0][0] & 0x03F0000);
360  }
361  }
362  }
363 }
364 
365 
366 void gFexInputByteStreamTool::c_gtrx_map( const gfiber &inputData, gfiber &outputData) const{
367 
368  int rows = inputData.size();
369  int cols = inputData[0].size();
370 
371  for(int i =0; i< rows; i++){
372  for (int j=0; j< cols; j++){
373  if( i< 50) {
374  outputData[i][j] = inputData[gPos::GTRX_MAP_C_IND[i]][j];
375  }
376  else if( j< cols-1 ) {
377  outputData[i][j] = 0;
378  }
379  else {
380  outputData[i][j] = ( inputData[0][0] & 0x03F0000);
381  }
382  }
383  }
384 }
385 
386 
388  gfiber Xfiber, int Xin,
389  gtFPGA &XgtF, gtFPGA &Xgt,
390  int *BCIDptr,
391  int do_lconv,
392  const std::array<int, gPos::MAX_FIBERS> &XMPD_NFI,
393  const std::array<int, gPos::MAX_FIBERS> &XCALO_TYPE,
394  const gCaloTwr & XMPD_GTRN_ARR,
395  const gType & XMPD_DSTRT_ARR,
396  gTypeChar XMPD_DTYP_ARR,
397  const std::array<int, gPos::MAX_FIBERS> &XMSK,
398  gtFPGA &Xsaturation) const{
399 
400 // Output is uncalibrated gTowers with 50MeV LSB
401 // Xfiber -- 80 fibers, each with seven words, 32 bits per word
402 // Xin -- usually 80 -- number of fibers actually used, is 50 for EMEC/HEC FPGAC
403 // XgtF -- 12*32 = 384 towers -- 50 MeV LSB
404 // Xgt -- 12*32 = 384 towers -- given as integers
405 
406 
407 // XMPD_NFI -- gives the fiber type 0, 1, 2, 3 (A & B only use types 0,1,2)
408 // XMPD_DTYP_ARR -- gives the detector type for the 20 fields on a fiber
409 // XMPD_D_STRT -- gives the starting bit out of 224 for 20 fields that can be on a fiber
410 // XMPD_GTRN_ARR -- maps the first 16 of 20 fields onto one of the 384 towers
411 
412 // In the firmware Xfiber is an array of 32 bit words and on each of seven clocks new data for a BC comes in.
413 
414  // gtFPGA Xsaturation;
415 
416  //loop over fibers --
417  for(int irow=0; irow<gPos::ABC_ROWS; irow++){
418  for(int icolumn=0; icolumn<gPos::AB_COLUMNS; icolumn++){
419  Xgt[irow][icolumn] = 0;
420  XgtF[irow][icolumn] = 0;
421  Xsaturation[irow][icolumn] = 0;
422  }
423  }
424 
425  // detector (data field type) type :
426  // -- "0000" - EMB, EMB/EMEC -> EM contribution 0
427  // -- "0001" - TREX,HEC - Had contribution 1
428  // -- "0010" - extended region ( EMEC) 2
429  // -- "0011" - extended region ( HEC) 3
430  // -- "0100" - position info (for EMB, EMB/EMEC)
431  // -- "0101" - CRC
432  // -- "0110" - overlaping HEC - gTower will be sum of EMEC + TREX + overlaping HEC input) 6
433  // -- "1000" - saturation flags for inputs 7-0
434  // -- "1001" - saturation flags for inputs 15-8
435  // -- "1010" - BCID_LOW
436  // -- "1111" - unused field
437 
438  // use fiber 0 for BCID
439  *BCIDptr = (Xfiber[0][gPos::W280-1]&0x007F0000) >>16;
440 
441  //200 MeV towers
442  std::array<int, gPos::AB_TOWERS> etowerData{};
443  std::array<int, gPos::AB_TOWERS> htowerData{};
444  std::array<int, gPos::ABC_ROWS> xetowerData{};
445  std::array<int, gPos::ABC_ROWS> xhtowerData{};
446  std::array<int, gPos::ABC_ROWS> ohtowerData{};
447 
448  //50 MeV towers
449  std::array<int, gPos::AB_TOWERS> etowerDataF{};
450  std::array<int, gPos::AB_TOWERS> htowerDataF{};
451  std::array<int, gPos::ABC_ROWS> xetowerDataF{};
452  std::array<int, gPos::ABC_ROWS> xhtowerDataF{};
453  std::array<int, gPos::ABC_ROWS> ohtowerDataF{};
454 
455 
456 
457  // save values from fiber fields for monitoring (50 MeV towers)
458 
459  gFields fiberFields{{}};
460  gFields fiberFieldsUndecoded{{}};
461  gSatur fiberSaturation{{}};
462 
463 
464  for(unsigned int i=0; i<100; i++){
465 
466  if( ( Xfiber[i][gPos::W280-1] & 0x000000FF ) == 0x000000BC ) {
467 
468  fiberFields[i][16] = 1;
469  }
470  else {
471  fiberFields[i][16] = 0;
472  }
473 
474 
475  fiberFields[i][18] = ( Xfiber[i][gPos::W280-1] & 0x007F0000) >>16 ;
476  fiberFields[i][19] = ( Xfiber[i][gPos::W280-1] & 0xFF800000) >>23 ;
477 
478  if (XMPD_DTYP_ARR[ XMPD_NFI[i] ][17] == 8) {
479 
480  fiberFields[i][17] = ( Xfiber[i][gPos::W280-1] & 0x0000FF00) >>8 ;
481  // fill in saturation bits
482  for(unsigned int k=0; k<8; k++){
483  if( fiberFields[i][17] & (1<<k) ) {
484  fiberSaturation[i][k] = 1;
485  }
486  }
487  }
488 
489  int kFilled = 0;
490  for(unsigned int k=0; k<16; k++){
491  if( (XMPD_DTYP_ARR[ XMPD_NFI[i] ][k] != 4 ) && ( XMPD_GTRN_ARR[i][k] > -1 ) ) {
492  int krow = XMPD_GTRN_ARR[i][k]/12;
493  int kcolumn = XMPD_GTRN_ARR[i][k]%12;
494  if(kFilled <8 ){
495  if( fiberSaturation[i][kFilled] == 1 ) {
496  Xsaturation[ krow][kcolumn] = 1;
497  }
498  }
499  kFilled = kFilled + 1;
500  }
501  }
502  }
503 
504  //Loop over fibers
505  for(int iFiber = 0; iFiber < Xin; iFiber++) {
506  // first do CRC check
507  std::array<uint32_t, 6> tmp;
508  for(int i = 0; i < 6; i++){ tmp[i] = Xfiber[iFiber][i]; };
509  // coverity[uninit_use_in_cal : FALSE]
510  uint32_t CRC = crc9d32(tmp, 6, 1);
511  int withoutComma = Xfiber[iFiber][6] & 0xFFFFFF00 ;
512  CRC = crc9d23(withoutComma, CRC, 1 );
513  uint32_t StoredCRC = ( (Xfiber[iFiber][6]>>23) & 0x000001FF);
514  if( (CRC != StoredCRC) && (StoredCRC != 0 ) ) {
515 
516  std::stringstream sdetail;
517  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: Fiber " << iFiber << "of Xin " << Xin << ": BAD New CRC: " << CRC << "Stored CRC "<< StoredCRC ;
518  std::stringstream slocation;
519  slocation << "Fiber " << iFiber << "of Xin " << Xin;
520  std::stringstream stitle;
521  stitle << "Bad CRC" ;
522  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
523 
524  }
525 
526  // now check if CRC lower bits are correct in the trailer
527  int fiber_type = XMPD_NFI[iFiber];
528  // each fiber has 20 pieces of information -- called iDatum here
529  for(int iDatum = 0; iDatum < 16; iDatum++) {
530  // tells where the data is coming from -- see data field type above
531  int dataType = XMPD_DTYP_ARR[fiber_type][iDatum];
532  // tower number 0 - 383
533  int ntower = XMPD_GTRN_ARR[iFiber][iDatum];
534  if( ntower == -1 ){
535  ATH_MSG_DEBUG("[gFexInputByteStreamTool::gtReconstructABC: unused location iFiber "<< iFiber << ", calo type "<< XCALO_TYPE[iFiber]<<", data type "<< dataType <<", iDatum " << iDatum << "tower " << ntower);
536  }
537  else if( (ntower < 0) || (ntower >383) ){
538 
539  std::stringstream sdetail;
540  sdetail << "[gFexInputByteStreamTool::gtReconstructABC: bad value of ntower: iFiber "<< iFiber<< ", calo type"<< XCALO_TYPE[iFiber]<< ", data type "<< dataType<< ", iDatum "<< iDatum<< "tower "<< ntower ;
541  std::stringstream slocation;
542  slocation << "iFiber "<< iFiber<< ", calo type"<< XCALO_TYPE[iFiber];
543  std::stringstream stitle;
544  stitle << "Bad value of ntower" ;
545  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
546 
547  }
548 
549  // bit number in the 32*7 = 234 bits transmitted in one BC
550  // word refers to the 7 32 bits words transmitted in each BC
551  int ihigh = XMPD_DSTRT_ARR[fiber_type][iDatum];
552  int ihword = ihigh/32;
553  int ihbit = ihigh%32;
554 
555  int ilow = 0;
556  int ilword = 0;
557  int ilbit = 0;
558 
559  int hTREXval = 0;
560  int lTREXval = 0;
561  int hHECval = 0;
562  int lHECval = 0;
563 
564  // need to be sure to skip positon data!
565  int mask = 0;
566  int lmask = 0;
567  int hmask = 0;
568 
569  if( XMSK[iFiber] != 1 ) {
570  dataType = 99;
571  }
572 
573  //Different kinds of data type
574  if( (XCALO_TYPE[iFiber] < 3) && (ntower>-1) && (ntower<384) ) {
575  switch(dataType){
576  case 0:
577  ilow = ihigh - 11;
578  ilword = ilow/32;
579  ilbit = ilow%32;
580  if(ilword == ihword){
581  mask = 0x00000FFF;
582  mask = mask << (ilbit);
583  etowerData[ntower] = etowerData[ntower] | ( (Xfiber[iFiber][ihword] & mask) >> ilbit );
584  // undo multilinear decoding
585  if( do_lconv){
586  fiberFieldsUndecoded[iFiber][iDatum] = etowerData[ntower];
587  undoMLE( etowerData[ntower] );
588  etowerDataF[ntower] = etowerData[ntower];
589  fiberFields[iFiber][iDatum] = etowerData[ntower];
590 
591  }
592  else {
593  // sign extend etower data
594  if( etowerData[ntower] & 0x00000800 ){ etowerData[ntower] = (etowerData[ntower] | 0xFFFFF000) ;}
595  etowerData[ntower] = etowerData[ntower]*4;
596  etowerDataF[ntower] = etowerData[ntower];
597  }
598  }
599  else {
600 
601  std::stringstream sdetail;
602  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: wrongly packed data "<< fiber_type<< ", "<<dataType<< ", "<<ilword<< ", " <<ihword ;
603  std::stringstream slocation;
604  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
605  std::stringstream stitle;
606  stitle << "Wrongly packed data" ;
607  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
608 
609  }
610  break;
611 
612  case 1:
613  ilow = ihigh - 11;
614  ilword = ilow/32;
615  ilbit = ilow%32;
616 
617  hTREXval = Xfiber[iFiber][ihword];
618  lTREXval = Xfiber[iFiber][ilword];
619  mask =0;
620  lmask =0;
621  hmask =0;
622 
623  if(ilword == ihword){
624  mask = 0x00000FFF;
625  mask = mask << ilbit;
626  htowerData[ntower] = htowerData[ntower] | ( (hTREXval & mask) >> (ilbit) );
627  }
628  else if ( ihbit == 7 ) {
629  mask = 0x0000000F;
630  hmask = 0x000000FF;
631  htowerData[ntower] = htowerData[ntower] | ( (hTREXval & hmask) << 4);
632  lmask = 0xF0000000;
633  htowerData[ntower] = htowerData[ntower] | ( ( (lTREXval & lmask) >> 28)&mask) ;
634  }
635  else if ( ihbit == 3) {
636  mask = 0x000000FF;
637  hmask = 0x0000000F;
638  htowerData[ntower] = htowerData[ntower] | ( ( hTREXval & hmask) << 8);
639  lmask = 0xFF000000;
640  htowerData[ntower] = htowerData[ntower] | ( ( (lTREXval & lmask) >> 24) &mask) ;
641  }
642  else {
643 
644  std::stringstream sdetail;
645  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: wrongly packed data "<< fiber_type<< ", "<<dataType<< ", "<<ilword<< ", " <<ihword ;
646  std::stringstream slocation;
647  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
648  std::stringstream stitle;
649  stitle << "Wrongly packed data" ;
650  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
651 
652  }
653 
654  // mulitply by 20 to make 50 MeV LSB
655  if( (Xin > 50) ) {
656  // include this here before mulitplicaiton by 20
657  fiberFieldsUndecoded[iFiber][iDatum] = htowerData[ntower];
658  htowerData[ntower] = 20*htowerData[ntower];
659  htowerDataF[ntower] = htowerData[ntower];
660  fiberFields[iFiber][iDatum] = htowerData[ntower];
661  }
662  else {
663  if( do_lconv){
664  fiberFieldsUndecoded[iFiber][1] = htowerData[ntower];
665  undoMLE( htowerData[ntower] );
666  htowerDataF[ntower] = htowerData[ntower];
667  fiberFields[iFiber][1] = htowerData[ntower];
668  }
669  else {
670  // sign extend etower data
671  if( htowerData[ntower] & 0x00000800 ){ htowerData[ntower] = (htowerData[ntower] | 0xFFFFF000) ;}
672  htowerData[ntower] = htowerData[ntower]*4;
673  htowerDataF[ntower] = htowerData[ntower];
674  }
675  }
676  break;
677 
678  case 2:
679  ilow = ihigh - 11;
680  ilword = ilow/32;
681  ilbit = ilow%32;
682  if( (ntower > 32) || (ntower < 0) ){
683 
684  std::stringstream sdetail;
685  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: bad value of nTower for extended region 2.4 - 2.5 in eta" ;
686  std::stringstream slocation;
687  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
688  std::stringstream stitle;
689  stitle << "Bad value of nTower in extended eta" ;
690  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
691 
692  }
693  if(ilword == ihword){
694  int mask = 0x00000FFF;
695  mask = mask << ilbit;
696  xetowerData[ntower] = xetowerData[ntower] | ( (Xfiber[iFiber][ihword]&mask) >> (ilbit) );
697  }
698  else if ( ihbit == 7 ) {
699  mask = 0x0000000F;
700  hmask = 0x000000FF;
701  xetowerData[ntower] = xetowerData[ntower] | ( (Xfiber[iFiber][ihword]&hmask) << 4);
702  lmask = 0xF0000000;
703  xetowerData[ntower] = xetowerData[ntower] | ( ( (Xfiber[iFiber][ilword]&lmask) >> 28)&mask) ;
704  }
705  else if ( ihbit == 3) {
706  mask = 0x000000FF;
707  hmask = 0x000000F;
708  xetowerData[ntower] = xetowerData[ntower] | ( (Xfiber[iFiber][ihword]&hmask) << 8);
709  lmask = 0xFF000000;
710  xetowerData[ntower] = xetowerData[ntower] | ( ( (Xfiber[iFiber][ilword]&lmask) >> 24)&mask) ;
711  }
712  else {
713 
714  std::stringstream sdetail;
715  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: wrongly packed data "<< fiber_type<< ", "<<dataType<< ", "<<ilword<< ", " <<ihword ;
716  std::stringstream slocation;
717  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
718  std::stringstream stitle;
719  stitle << "Wrongly packed data" ;
720  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
721 
722  }
723  // undo multilinear decoding
724  if( do_lconv){
725  fiberFieldsUndecoded[iFiber][iDatum] = xetowerData[ntower];
726  undoMLE( xetowerData[ntower] );
727  xetowerDataF[ntower] = xetowerData[ntower];
728  fiberFields[iFiber][iDatum] = xetowerData[ntower];
729 
730  }
731  else {
732  // sign extend etower data
733  if( xetowerData[ntower] & 0x00000800 ){ xetowerData[ntower] = (xetowerData[ntower] | 0xFFFFF000) ;}
734  xetowerData[ntower] = xetowerData[ntower]*4;
735  xetowerDataF[ntower] = xetowerData[ntower];
736  }
737  break;
738 
739  case 3:
740  ilow = ihigh - 11;
741  ilword = ilow/32;
742  ilbit = ilow%32;
743  if(ilword == ihword){
744  mask = 0x00000FFF;
745  mask = mask << ilbit;
746  xhtowerData[ntower] = xhtowerData[ntower] | ( (Xfiber[iFiber][ihword]&mask) >> (ilbit) );
747  }
748  else if ( ihbit == 7 ) {
749  mask = 0x0000000F;
750  hmask = 0x000000FF;
751  xhtowerData[ntower] = xhtowerData[ntower] | ( (Xfiber[iFiber][ihword]&hmask) << 4);
752  lmask = 0xF0000000;
753  xhtowerData[ntower] = xhtowerData[ntower] | ( ( (Xfiber[iFiber][ilword]&lmask) >> 28)&mask) ;
754  }
755  else if ( ihbit == 3) {
756  mask = 0x000000FF;
757  hmask = 0x0000000F;
758  xhtowerData[ntower] = xhtowerData[ntower] | ( (Xfiber[iFiber][ihword]&hmask) << 8);
759  lmask = 0xFF000000;
760  xhtowerData[ntower] = xhtowerData[ntower] | ( ( (Xfiber[iFiber][ilword]&lmask) >> 24)&mask) ;
761  }
762  else {
763 
764  std::stringstream sdetail;
765  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: wrongly packed data "<< fiber_type<< ", "<<dataType<< ", "<<ilword<< ", " <<ihword ;
766  std::stringstream slocation;
767  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
768  std::stringstream stitle;
769  stitle << "Wrongly packed data" ;
770  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
771 
772  }
773  if( ntower > 32 ){
774 
775  std::stringstream sdetail;
776  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: bad value of nTower for extended region 2.4 - 2.5 in eta" ;
777  std::stringstream slocation;
778  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
779  std::stringstream stitle;
780  stitle << "Bad value of nTower in extended eta" ;
781  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
782 
783  }
784  // undo multilinear decoding
785  if( do_lconv){
786  fiberFieldsUndecoded[iFiber][iDatum] = xhtowerData[ntower];
787  undoMLE( xhtowerData[ntower] );
788  xhtowerDataF[ntower] = xhtowerData[ntower];
789  fiberFields[iFiber][iDatum] = xhtowerData[ntower];
790  }
791  else {
792  // sign extend etower data
793  if( xhtowerData[ntower] & 0x00000800 ){ xhtowerData[ntower] = (xhtowerData[ntower] | 0xFFFFF000) ;}
794  xhtowerData[ntower] = xhtowerData[ntower]*4;
795  xhtowerDataF[ntower] = xhtowerData[ntower];
796  }
797  break;
798 
799  case 6:
800  ilow = ihigh - 11;
801  ilword = ilow/32;
802  ilbit = ilow%32;
803  if(ilword == ihword){
804  mask = 0x00000FFF;
805  mask = mask << ilbit;
806  ohtowerData[ntower] = ohtowerData[ntower] | ( (Xfiber[iFiber][ihword]&mask) >> (ilbit) );
807  }
808  else if ( ihbit == 7 ) {
809  mask = 0x0000000F;
810  hmask = 0x000000FF;
811  ohtowerData[ntower] = ohtowerData[ntower] | ( (Xfiber[iFiber][ihword]&hmask) << 4);
812  lmask = 0xF0000000;
813  ohtowerData[ntower] = ohtowerData[ntower] | ( ( (Xfiber[iFiber][ilword]&lmask) >> 28)&mask) ;
814  }
815  else if ( ihbit == 3) {
816  mask = 0x000000FF;
817  hmask = 0x0000000F;
818  ohtowerData[ntower] = ohtowerData[ntower] | ( (Xfiber[iFiber][ihword]&hmask) << 8);
819  lmask = 0xFF000000;
820  ohtowerData[ntower] = ohtowerData[ntower] | ( ( (Xfiber[iFiber][ilword]&lmask) >> 24)&mask) ;
821  }
822  else {
823 
824  std::stringstream sdetail;
825  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: wrongly packed data "<< fiber_type<< ", "<<dataType<< ", "<<ilword<< ", " <<ihword ;
826  std::stringstream slocation;
827  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
828  std::stringstream stitle;
829  stitle << "Wrongly packed data" ;
830  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
831 
832  }
833  if( ntower > 32 ){
834 
835  std::stringstream sdetail;
836  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: bad value of nTower for extended region 2.4 - 2.5 in eta" ;
837  std::stringstream slocation;
838  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
839  std::stringstream stitle;
840  stitle << "Bad value of nTower in extended eta" ;
841  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
842 
843  }
844  if( do_lconv){
845  fiberFieldsUndecoded[iFiber][iDatum] = ohtowerData[ntower];
846  undoMLE( ohtowerData[ntower] );
847  ohtowerDataF[ntower] = ohtowerData[ntower];
848  fiberFields[iFiber][iDatum] = ohtowerData[ntower];
849  }
850  else {
851  // sign extend etower data
852  if( ohtowerData[ntower] & 0x00000800 ){ ohtowerData[ntower] = (ohtowerData[ntower] | 0xFFFFF000) ;}
853  ohtowerData[ntower] = ohtowerData[ntower]*4;
854  ohtowerDataF[ntower] = ohtowerData[ntower];
855  }
856  break;
857 
858  case 11:
859  ilow = ihigh - 11;
860  ilword = ilow/32;
861  ilbit = ilow%32;
862 
863  hHECval = Xfiber[iFiber][ihword];
864  lHECval = Xfiber[iFiber][ilword];
865  if(ilword == ihword){
866  mask = 0x00000FFF;
867  mask = mask << ilbit;
868  htowerData[ntower] = htowerData[ntower] | ( (hHECval & mask) >> (ilbit) );
869  }
870  else if ( ihbit == 7 ) {
871  mask = 0x0000000F;
872  hmask = 0x000000FF;
873  htowerData[ntower] = htowerData[ntower] | ( (hHECval & hmask) << 4);
874  lmask = 0xFF000000;
875  htowerData[ntower] = htowerData[ntower] | ( ( (lHECval & lmask) >> 28)&mask) ;
876  }
877  else if ( ihbit == 3) {
878  mask = 0x000000FF;
879  hmask = 0x0000000F;
880  htowerData[ntower] = htowerData[ntower] | ( ( hHECval & hmask) << 8);
881  lmask = 0xFF000000;
882  htowerData[ntower] = htowerData[ntower] | ( ( (lHECval & lmask) >> 24) &mask) ;
883  }
884  else {
885 
886  std::stringstream sdetail;
887  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: wrongly packed data "<< fiber_type<< ", "<<dataType<< ", "<<ilword<< ", " <<ihword ;
888  std::stringstream slocation;
889  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
890  std::stringstream stitle;
891  stitle << "Wrongly packed data" ;
892  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
893 
894  }
895  if( do_lconv){
896  fiberFieldsUndecoded[iFiber][iDatum] = htowerData[ntower];
897  undoMLE( htowerData[ntower] );
898  htowerDataF[ntower] = htowerData[ntower];
899  fiberFields[iFiber][iDatum] = htowerData[ntower];
900  }
901  else {
902  // sign extend etower data
903  if( htowerData[ntower] & 0x00000800 ){ htowerData[ntower] = (htowerData[ntower] | 0xFFFFF000) ;}
904  htowerData[ntower] = htowerData[ntower]*4;
905  htowerDataF[ntower] = htowerData[ntower];
906  }
907  break;
908  }
909  // FPGA C EMEC/HEC + FCAL
910  // These all have same dataType as extended ECAL and extended HCAL
911  }
912  else if ( (ntower>-1) && (ntower<384) ){
913  // this is FPGA C
914  // only types 2 and 3 exist in FPGA C
915 
916  switch(dataType){
917  case 2:
918  ilow = ihigh - 11;
919  ilword = ilow/32;
920  ilbit = ilow%32;
921 
922  if( etowerData[ntower] != 0 ) {
923 
924  std::stringstream sdetail;
925  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: etowerData[nTower] is not zero, inconsistent constants! "<< etowerData[ntower] ;
926  std::stringstream slocation;
927  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
928  std::stringstream stitle;
929  stitle << "etowerData not zero" ;
930  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
931 
932  } else {
933 
934  if(ilword == ihword){
935  int mask = 0x00000FFF;
936  mask = mask << ilbit;
937  etowerData[ntower] = etowerData[ntower] | ( (Xfiber[iFiber][ihword]&mask) >> (ilbit) );
938  }
939  else if ( ihbit == 7 ) {
940  mask = 0x0000000F;
941  hmask = 0x000000FF;
942  etowerData[ntower] = etowerData[ntower] | ( (Xfiber[iFiber][ihword]&hmask) << 4);
943  lmask = 0xF0000000;
944  etowerData[ntower] = etowerData[ntower] | ( ( (Xfiber[iFiber][ilword]&lmask) >> 28)&mask) ;
945  }
946  else if ( ihbit == 3) {
947  mask = 0x000000FF;
948  hmask = 0x000000F;
949  etowerData[ntower] = etowerData[ntower] | ( (Xfiber[iFiber][ihword]&hmask) << 8);
950  lmask = 0xFF000000;
951  etowerData[ntower] = etowerData[ntower] | ( ( (Xfiber[iFiber][ilword]&lmask) >> 24)&mask) ;
952  }
953  else {
954 
955  std::stringstream sdetail;
956  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: wrongly packed data "<< fiber_type<< ", "<<dataType<< ", "<<ilword<< ", " <<ihword ;
957  std::stringstream slocation;
958  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
959  std::stringstream stitle;
960  stitle << "Wrongly packed data" ;
961  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
962 
963  }
964  // undo multilinear decoding
965  if( do_lconv){
966  fiberFieldsUndecoded[iFiber][iDatum] = etowerData[ntower];
967  undoMLE( etowerData[ntower] );
968  etowerDataF[ntower] = etowerData[ntower];
969  fiberFields[iFiber][iDatum] = etowerData[ntower];
970  }
971  else {
972  // sign extend etower data
973  if( etowerData[ntower] & 0x00000800 ){ etowerData[ntower] = (etowerData[ntower] | 0xFFFFF000) ;}
974  etowerData[ntower] = etowerData[ntower]*4;
975  etowerDataF[ntower] = etowerData[ntower];
976  }
977  }
978  break;
979 
980  case 3:
981  ilow = ihigh - 11;
982  ilword = ilow/32;
983  ilbit = ilow%32;
984 
985  if( htowerData[ntower] != 0 ) {
986  std::stringstream sdetail;
987  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: etowerData[nTower] is not zero, inconsistent constants! "<< etowerData[ntower] ;
988  std::stringstream slocation;
989  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
990  std::stringstream stitle;
991  stitle << "etowerData not zero" ;
992  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
993 
994  } else {
995 
996  if(ilword == ihword){
997  mask = 0x00000FFF;
998  mask = mask << ilbit;
999  htowerData[ntower] = htowerData[ntower] | ( (Xfiber[iFiber][ihword]&mask) >> (ilbit) );
1000  }
1001  else if ( ihbit == 7 ) {
1002  mask = 0x0000000F;
1003  hmask = 0x000000FF;
1004  htowerData[ntower] = htowerData[ntower] | ( (Xfiber[iFiber][ihword]&hmask) << 4);
1005  lmask = 0xF0000000;
1006  htowerData[ntower] = htowerData[ntower] | ( ( (Xfiber[iFiber][ilword]&lmask) >> 28)&mask) ;
1007  }
1008  else if ( ihbit == 3) {
1009  mask = 0x000000FF;
1010  hmask = 0x0000000F;
1011  htowerData[ntower] = htowerData[ntower] | ( (Xfiber[iFiber][ihword]&hmask) << 8);
1012  lmask = 0xFF000000;
1013  htowerData[ntower] = htowerData[ntower] | ( ( (Xfiber[iFiber][ilword]&lmask) >> 24)&mask) ;
1014  }
1015  else {
1016 
1017  std::stringstream sdetail;
1018  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: wrongly packed data "<< fiber_type<< ", "<<dataType<< ", "<<ilword<< ", " <<ihword ;
1019  std::stringstream slocation;
1020  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
1021  std::stringstream stitle;
1022  stitle << "Wrongly packed data" ;
1023  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
1024 
1025  }
1026  // undo multilinear decoding
1027  if( do_lconv){
1028  fiberFieldsUndecoded[iFiber][iDatum] = htowerData[ntower];
1029  undoMLE( htowerData[ntower] );
1030  htowerDataF[ntower] = htowerData[ntower];
1031  fiberFields[iFiber][iDatum] = htowerData[ntower];
1032  }
1033  else {
1034  // sign extend etower data
1035  if( htowerData[ntower] & 0x00000800 ){ htowerData[ntower] = (htowerData[ntower] | 0xFFFFF000) ;}
1036  htowerData[ntower] = htowerData[ntower]*4;
1037  htowerDataF[ntower] = htowerData[ntower];
1038  }
1039  }
1040  break;
1041 
1042  case 15:
1043  break;
1044 
1045  case 99:
1046  break;
1047 
1048  default:
1049 
1050  std::stringstream sdetail;
1051  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: wrong detector type "<< dataType ;
1052  std::stringstream slocation;
1053  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
1054  std::stringstream stitle;
1055  stitle << "Wrong detector type" ;
1056  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
1057 
1058  } // end of case statement for FPGAC
1059  } // end of | eta | > 2,5
1060  } // end of loop over words
1061  } // end of loop over fibers
1062 
1063 
1064  // no need for xdtower, xhtower and ohtower in FPGA C -- but these will all be zero in that case.
1065  if( XFPGA == 0 ) {
1066  for(int itower=0;itower<384;itower++){
1067  int icolumn = itower%12;
1068  int irow = itower/12;
1069 
1070  // 50 MeV towers
1071  int xF = etowerDataF[itower] + htowerDataF[itower];
1072  // 200 MeV towers
1073  int x = ( (etowerData[itower]>>2) + (htowerData[itower]>>2) );
1074 
1075  signExtend(&xF,18);
1076  signExtend(&x,18);
1077 
1078  Xgt[irow][icolumn] = x;
1079  XgtF[irow][icolumn] = xF;
1080 
1081  // etra region in FPGA A (eta ~ -2.5)
1082  if ( icolumn == 0) {
1083  int xx = ( (xetowerData[irow]>>2) + (xhtowerData[irow]>>2) );
1084  signExtend(&xx,18);
1085  Xgt[irow][icolumn] = Xgt[irow][icolumn] + xx;
1086  }
1087  if ( icolumn == 4) {
1088  // 200 MeV towers
1089  int ox = (ohtowerData[irow] >> 2 ) ;
1090  signExtend(&ox,18);
1091  Xgt[irow][icolumn] = Xgt[irow][icolumn] + ox ;
1092  }
1093  }
1094  }
1095  else if ( XFPGA == 1 ) {
1096  for(int itower=0;itower<384;itower++){
1097  int icolumn = itower%12;
1098  int irow = itower/12;
1099 
1100  // 50 MeV towers
1101  int xF = etowerDataF[itower] + htowerDataF[itower] ;
1102  // 200 MeV towers
1103  int x = ( (etowerData[itower]>>2) + (htowerData[itower] >> 2) );
1104 
1105  signExtend(&xF,18);
1106  signExtend(&x,18);
1107 
1108  Xgt[irow][icolumn] = x;
1109  XgtF[irow][icolumn] = xF;
1110 
1111  // extra region FPGA B (eta ~ 2.5)
1112  if ( icolumn == 11) {
1113  // 50 MeV towers
1114  // int xxF = xetower_dataF[irow] + xhtower_dataF[irow] ;
1115  // 200 MeV towers
1116  int xx = ( (xetowerData[irow]>>2) + (xhtowerData[irow]>>2) );
1117  // signExtend(&xxF,18);
1118  signExtend(&xx,18);
1119  Xgt[irow][icolumn] = Xgt[irow][icolumn] + xx;
1120  }
1121  if ( icolumn == 7 ) {
1122  // 200 MeV towers
1123  // int xoF = ohtowerData[irow];
1124  int xo = ohtowerData[irow]>>2;
1125  // signExtend(&xoF,18);
1126  signExtend(&xo,18);
1127  Xgt[irow][icolumn] = Xgt[irow][icolumn] + xo;
1128  }
1129  }
1130  }
1131  else if ( XFPGA == 2 ) {
1132  for(int itower=0;itower<384;itower++){
1133  int icolumn = itower%12;
1134  int irow = itower/12;
1135 
1136  // 50 MeV towers
1137  int xF = etowerDataF[itower] + htowerDataF[itower] ;
1138  // 200 MeV towers
1139  int x = ( (etowerData[itower]>>2 ) + (htowerData[itower]>>2));
1140  signExtend(&xF,18);
1141  signExtend(&x,18);
1142 
1143  Xgt[irow][icolumn] = x;
1144  XgtF[irow][icolumn] = xF;
1145  }
1146  }
1147  else {
1148  ATH_MSG_DEBUG("[gFexInputByteStreamTool::gtReconstructABC]: Bad FPGA # "<< XFPGA);
1149  }
1150 }
1151 
1152 
1153 
1154 int gFexInputByteStreamTool::crc9d32(const std::array<uint32_t, 6> &inWords,int numWords,int reverse) const{
1155  // calculate this for reversed bits
1156 
1157  std::array<uint32_t, 32> dIn;
1158  std::array<uint32_t, 9> crc_s;
1159  std::array<uint32_t, 9> crc_r;
1160 
1161  crc_s.fill(1);
1162  crc_r.fill(1);
1163 
1164  int crc_word = 0x000;
1165  unsigned int mask = 0x00000001;
1166 
1167  for(int k =0; k < numWords; k++) {
1168  if( reverse == 1 ) {
1169  for (int i =0 ; i < 32; i++ ) {
1170  dIn[31-i] = (inWords[k] & (mask << i));
1171  dIn[31-i] = ((dIn[31-i] >> i) & 0x00000001);
1172  }
1173  }
1174  else {
1175  for (int i =0 ; i<32; i++ ) {
1176  dIn[i] = inWords[k] & (mask << i);
1177  dIn[i] = ((dIn[i] >> i) & 0x0000001);
1178  }
1179  }
1180  for(int j=0; j<9; j++){
1181  crc_s[j] = crc_r[j];
1182  }
1183 
1184  crc_r[0] = crc_s[0] ^ crc_s[2] ^ crc_s[3] ^ crc_s[6] ^ crc_s[8] ^ dIn[0] ^ dIn[2] ^ dIn[3] ^ dIn[5] ^ dIn[6] ^ dIn[7] ^ dIn[8] ^ dIn[9] ^ dIn[10] ^ dIn[11] ^ dIn[15] ^ dIn[18] ^ dIn[19] ^ dIn[20] ^ dIn[21] ^ dIn[22] ^ dIn[23] ^ dIn[25] ^ dIn[26] ^ dIn[29] ^ dIn[31];
1185 
1186  crc_r[1] = crc_s[1] ^ crc_s[2] ^ crc_s[4] ^ crc_s[6] ^ crc_s[7] ^ crc_s[8] ^ dIn[0] ^ dIn[1] ^ dIn[2] ^ dIn[4] ^ dIn[5] ^ dIn[12] ^ dIn[15] ^ dIn[16] ^ dIn[18] ^ dIn[24] ^ dIn[25] ^ dIn[27] ^ dIn[29] ^ dIn[30] ^ dIn[31];
1187 
1188  crc_r[2] = crc_s[2] ^ crc_s[3] ^ crc_s[5] ^ crc_s[7] ^ crc_s[8] ^ dIn[1] ^ dIn[2] ^ dIn[3] ^ dIn[5] ^ dIn[6] ^ dIn[13] ^ dIn[16] ^ dIn[17] ^ dIn[19] ^ dIn[25] ^ dIn[26] ^ dIn[28] ^ dIn[30] ^ dIn[31];
1189 
1190  crc_r[3] = crc_s[0] ^ crc_s[2] ^ crc_s[4] ^ dIn[0] ^ dIn[4] ^ dIn[5] ^ dIn[8] ^ dIn[9] ^ dIn[10] ^ dIn[11] ^ dIn[14] ^ dIn[15] ^ dIn[17] ^ dIn[19] ^ dIn[21] ^ dIn[22] ^ dIn[23] ^ dIn[25] ^ dIn[27];
1191 
1192  crc_r[4] = crc_s[1] ^ crc_s[2] ^ crc_s[5] ^ crc_s[6] ^ crc_s[8] ^ dIn[0] ^ dIn[1] ^ dIn[2] ^ dIn[3] ^ dIn[7] ^ dIn[8] ^ dIn[12] ^ dIn[16] ^ dIn[19] ^ dIn[21] ^ dIn[24] ^ dIn[25] ^ dIn[28] ^ dIn[29] ^ dIn[31];
1193 
1194  crc_r[5] = crc_s[0] ^ crc_s[7] ^ crc_s[8] ^ dIn[0] ^ dIn[1] ^ dIn[4] ^ dIn[5] ^ dIn[6] ^ dIn[7] ^ dIn[10] ^ dIn[11] ^ dIn[13] ^ dIn[15] ^ dIn[17] ^ dIn[18] ^ dIn[19] ^ dIn[21] ^ dIn[23] ^ dIn[30] ^ dIn[31];
1195 
1196  crc_r[6] = crc_s[0] ^ crc_s[1] ^ crc_s[2] ^ crc_s[3] ^ crc_s[6] ^ dIn[0] ^ dIn[1] ^ dIn[3] ^ dIn[9] ^ dIn[10] ^ dIn[12] ^ dIn[14] ^ dIn[15] ^ dIn[16] ^ dIn[21] ^ dIn[23] ^ dIn[24] ^ dIn[25] ^ dIn[26] ^ dIn[29];
1197 
1198  crc_r[7] = crc_s[0] ^ crc_s[1] ^ crc_s[4] ^ crc_s[6] ^ crc_s[7] ^ crc_s[8] ^ dIn[0] ^ dIn[1] ^ dIn[3] ^ dIn[4] ^ dIn[5] ^ dIn[6] ^ dIn[7] ^ dIn[8] ^ dIn[9] ^ dIn[13] ^ dIn[16] ^ dIn[17] ^ dIn[18] ^ dIn[19] ^ dIn[20] ^ dIn[21] ^ dIn[23] ^ dIn[24] ^ dIn[27] ^ dIn[29] ^ dIn[30] ^ dIn[31];
1199 
1200  crc_r[8] = crc_s[1] ^ crc_s[2] ^ crc_s[5] ^ crc_s[7] ^ crc_s[8] ^ dIn[1] ^ dIn[2] ^ dIn[4] ^ dIn[5] ^ dIn[6] ^ dIn[7] ^ dIn[8] ^ dIn[9] ^ dIn[10] ^ dIn[14] ^ dIn[17] ^ dIn[18] ^ dIn[19] ^ dIn[20] ^ dIn[21] ^ dIn[22] ^ dIn[24] ^ dIn[25] ^ dIn[28] ^ dIn[30] ^ dIn[31];
1201 
1202  }
1203 
1204  if ( reverse == 1){
1205  for (int i = 0; i < 9; i++) {
1206  crc_word = crc_word | (crc_r[8-i] << i) ;
1207  }
1208  }
1209  else {
1210  for(int i = 0; i < 9; i++ ){
1211  crc_word = crc_word | (crc_r[i] << i);
1212  }
1213  }
1214  return crc_word;
1215 }
1216 
1217 
1219 
1220  int mask = 0x00000001;
1221  //#dIn is a '23-bit input word'
1222  std::array<uint32_t, 23> dIn;
1223 
1224  std::array<uint32_t, 9> crc_r;
1225  std::array<uint32_t, 9> crc_in_s;
1226 
1227  crc_r.fill(1);
1228  crc_in_s.fill(1);
1229 
1230  int crc_word = 0x000;
1231 
1232  //32-bit word crc calculation
1233 
1234  if (reverse == 1) {
1235  for(int i = 0; i < 23;i++){
1236  dIn[22-i] = ( inword & (mask << i));
1237  dIn[22-i] = ( dIn[22-i] >> i);
1238  }
1239  for(int i = 0; i < 9;i++){
1240  crc_in_s[8-i] = ( in_crc & (mask << i) );
1241  crc_in_s[8-i] = ( crc_in_s[8-i] >> i );
1242  }
1243  }
1244  else{
1245  for(int i = 0; i < 23; i++) {
1246  dIn[i] = ( inword & (mask << i) );
1247  dIn[i] = (dIn[i] >> i);
1248  }
1249  for(int i=0; i<9; i++){
1250  crc_in_s[i] = ( in_crc & (mask << i));
1251  crc_in_s[i] = (crc_in_s[i] >> i);
1252  }
1253  }
1254 
1255  crc_r[0] = crc_in_s[1] ^ crc_in_s[4] ^ crc_in_s[5] ^ crc_in_s[6] ^ crc_in_s[7] ^ crc_in_s[8] ^ dIn[0] ^ dIn[2] ^ dIn[3] ^ dIn[5] ^ dIn[6] ^ dIn[7] ^ dIn[8] ^ dIn[9] ^ dIn[10] ^ dIn[11] ^ dIn[15] ^ dIn[18] ^ dIn[19] ^ dIn[20] ^ dIn[21] ^ dIn[22];
1256  crc_r[1] = crc_in_s[1] ^ crc_in_s[2] ^ crc_in_s[4] ^ dIn[0] ^ dIn[1] ^ dIn[2] ^ dIn[4] ^ dIn[5] ^ dIn[12] ^ dIn[15] ^ dIn[16] ^ dIn[18];
1257  crc_r[2] = crc_in_s[2] ^ crc_in_s[3] ^ crc_in_s[5] ^ dIn[1] ^ dIn[2] ^ dIn[3] ^ dIn[5] ^ dIn[6] ^ dIn[13] ^ dIn[16] ^ dIn[17] ^ dIn[19];
1258  crc_r[3] = crc_in_s[0] ^ crc_in_s[1] ^ crc_in_s[3] ^ crc_in_s[5] ^ crc_in_s[7] ^ crc_in_s[8] ^ dIn[0] ^ dIn[4] ^ dIn[5] ^ dIn[8] ^ dIn[9] ^ dIn[10] ^ dIn[11] ^ dIn[14] ^ dIn[15] ^ dIn[17] ^ dIn[19] ^ dIn[21] ^ dIn[22];
1259  crc_r[4] = crc_in_s[2] ^ crc_in_s[5] ^ crc_in_s[7] ^ dIn[0] ^ dIn[1] ^ dIn[2] ^ dIn[3] ^ dIn[7] ^ dIn[8] ^ dIn[12] ^ dIn[16] ^ dIn[19] ^ dIn[21];
1260  crc_r[5] = crc_in_s[1] ^ crc_in_s[3] ^ crc_in_s[4] ^ crc_in_s[5] ^ crc_in_s[7] ^ dIn[0] ^ dIn[1] ^ dIn[4] ^ dIn[5] ^ dIn[6] ^ dIn[7] ^ dIn[10] ^ dIn[11] ^ dIn[13] ^ dIn[15] ^ dIn[17] ^ dIn[18] ^ dIn[19] ^ dIn[21];
1261  crc_r[6] = crc_in_s[0] ^ crc_in_s[1] ^ crc_in_s[2] ^ crc_in_s[7] ^ dIn[0] ^ dIn[1] ^ dIn[3] ^ dIn[9] ^ dIn[10] ^ dIn[12] ^ dIn[14] ^ dIn[15] ^ dIn[16] ^ dIn[21];
1262  crc_r[7] = crc_in_s[2] ^ crc_in_s[3] ^ crc_in_s[4] ^ crc_in_s[5] ^ crc_in_s[6] ^ crc_in_s[7] ^ dIn[0] ^ dIn[1] ^ dIn[3] ^ dIn[4] ^ dIn[5] ^ dIn[6] ^ dIn[7] ^ dIn[8] ^ dIn[9] ^ dIn[13] ^ dIn[16] ^ dIn[17] ^ dIn[18] ^ dIn[19] ^ dIn[20] ^ dIn[21];
1263  crc_r[8] = crc_in_s[0] ^ crc_in_s[3] ^ crc_in_s[4] ^ crc_in_s[5] ^ crc_in_s[6] ^ crc_in_s[7] ^ crc_in_s[8] ^ dIn[1] ^ dIn[2] ^ dIn[4] ^ dIn[5] ^ dIn[6] ^ dIn[7] ^ dIn[8] ^ dIn[9] ^ dIn[10] ^ dIn[14] ^ dIn[17] ^ dIn[18] ^ dIn[19] ^ dIn[20] ^ dIn[21] ^ dIn[22];
1264 
1265  crc_word = 0x000;
1266  if (reverse == 1){
1267  for(int i = 0; i < 9; i++) {
1268  crc_word = ( crc_word | (crc_r[8-i] << i));
1269  }
1270  }
1271  else{
1272  for(int i = 0; i < 9; i++) {
1273  crc_word = ( crc_word | (crc_r[i] << i) );
1274  }
1275  }
1276  return (crc_word);
1277 }
1278 
1279 void gFexInputByteStreamTool::undoMLE(int &datumPtr ) const{
1280  // limit input to 12 bits to avoid accidental sign extension
1281  int din = (0x00000FFF & datumPtr );
1282  // map all special cases to zero for now
1283  if( din > 0x0FDE ) din = 0x4EE;
1284  // limit negative values
1285  if( (din > 0) && ( din < 962 ) ) din = 962;
1286  //zeroZero
1287  if( din == 0) din = 0x4EE;
1288 
1289  int dout = 0;
1290 
1291  int FPGA_CONVLIN_TH1 = 5;
1292  int FPGA_CONVLIN_TH2 = 749;
1293  int FPGA_CONVLIN_TH3 = 1773;
1294  int FPGA_CONVLIN_TH4 = 2541;
1295  int FPGA_CONVLIN_TH5 = 4029;
1296 
1297  int FPGA_CONVLIN_OF0 = -5072;
1298  int FPGA_CONVLIN_OF1 = -2012;
1299  int FPGA_CONVLIN_OF2 = -1262;
1300  int FPGA_CONVLIN_OF3 = -3036;
1301  int FPGA_CONVLIN_OF4 = -8120;
1302  int FPGA_CONVLIN_OF5 = -4118720;
1303 
1304  int oth0 = 0;
1305  int oth1 = 0;
1306  int oth2 = 0;
1307  int oth3 = 0;
1308  int oth4 = 0;
1309  int oth5 = 0;
1310 
1311  int r1shv = 0;
1312  int r2shv = 0;
1313  int r3shv = 0;
1314  int r4shv = 0;
1315  int r5shv = 0;
1316  int r6shv = 0;
1317  // int trxv = 0;
1318 
1319  int r1conv = 0;
1320  int r2conv = 0;
1321  int r3conv = 0;
1322  int r4conv = 0;
1323  int r5conv = 0;
1324  int r6conv = 0;
1325  // int r3offs = 0;
1326 
1327  r1shv = ((din & 0x0000007F) << 9 ) & 0x0000FE00 ;
1328  r2shv = ((din & 0x00000FFF) << 1 ) & 0x00001FFE ;
1329  r3shv = (din & 0x00000FFF) ;
1330  r4shv = ((din & 0x00000FFF) << 1 ) & 0x00001FFE ;
1331  r5shv = ((din & 0x00000FFF) << 2 ) & 0x00003FFC ;
1332  r6shv = ((din & 0x00000FFF) << 10 ) & 0x003FFC00 ;
1333 
1334  r1conv = r1shv + FPGA_CONVLIN_OF0;
1335  r2conv = r2shv + FPGA_CONVLIN_OF1;
1336  r3conv = r3shv + FPGA_CONVLIN_OF2;
1337  r4conv = r4shv + FPGA_CONVLIN_OF3;
1338  r5conv = r5shv + FPGA_CONVLIN_OF4;
1339  r6conv = r6shv + FPGA_CONVLIN_OF5;
1340 
1341  if( din > 0 ) {
1342  oth0 = 1;
1343  }
1344  else{
1345  oth0 = 0;
1346  }
1347  if ( din > FPGA_CONVLIN_TH1 ){
1348  oth1 = 1;
1349  }
1350  else{
1351  oth1 = 0;
1352  }
1353  if ( din > FPGA_CONVLIN_TH2 ){
1354  oth2 = 1;
1355  }else{
1356  oth2 = 0;
1357  }
1358  if ( din > FPGA_CONVLIN_TH3 ){
1359  oth3 = 1;
1360  }else{
1361  oth3 = 0;
1362  }
1363  if ( din > FPGA_CONVLIN_TH4 ){
1364  oth4 = 1;
1365  }else{
1366  oth4 = 0;
1367  }
1368  if ( din > FPGA_CONVLIN_TH5 ){
1369  oth5 = 1;
1370  }
1371  else{
1372  oth5 = 0;
1373  }
1374 
1375  // divide by 2 to 50 MeV LSB
1376 
1377  if( (! oth0) & (! oth1 ) & (! oth2 ) & (! oth3 ) & (! oth4 ) & (! oth5 ) ) {
1378  dout = 0;
1379  }
1380  else if( ( oth0) & (! oth1 ) & (! oth2 ) & (! oth3 ) & (! oth4 ) & (! oth5 ) ) {
1381  dout = r1conv >>1;
1382  }
1383  else if( ( oth0) & ( oth1 ) & (! oth2 ) & (! oth3 ) & (! oth4 ) & (! oth5 ) ) {
1384  dout = r2conv >>1;
1385  }
1386  else if( ( oth0) & ( oth1 ) & ( oth2 ) & (! oth3 ) & (! oth4 ) & (! oth5 ) ) {
1387  dout = r3conv >>1;
1388  }
1389  else if( ( oth0) & ( oth1 ) & ( oth2 ) & ( oth3 ) & (! oth4 ) & (! oth5 ) ) {
1390  dout = r4conv >>1;
1391  }
1392  else if( ( oth0) & ( oth1 ) & ( oth2 ) & ( oth3 ) & ( oth4 ) & (! oth5 ) ) {
1393  dout = r5conv >>1;
1394  }
1395  else if( ( oth0) & ( oth1 ) & ( oth2 ) & ( oth3 ) & ( oth4 ) & ( oth5 ) ) {
1396  dout = r6conv >>1;
1397  }
1398  else {
1399  dout = 0;
1400  }
1401 
1402  signExtend(&dout,15);
1403 
1404  datumPtr = dout;
1405 }
1406 
1407 
1408 void gFexInputByteStreamTool::getEtaPhi ( float &Eta, float &Phi, int iEta, int iPhi, int gFEXtowerID) const{
1409 
1410  float s_centralPhiWidth = (2*M_PI)/32; //In central region, gFex has 32 bins in phi
1411  float s_forwardPhiWidth = (2*M_PI)/16; //In forward region, gFex has 16 bins in phi (before rearranging bins)
1412 
1413  const std::vector<float> s_EtaCenter = { -4.7, -4.2, -3.7, -3.4, -3.2, -3,
1414  -2.8, -2.6, -2.35, -2.1, -1.9, -1.7, -1.5, -1.3, -1.1, -0.9,
1415  -0.7, -0.5, -0.3, -0.1, 0.1, 0.3, 0.5, 0.7, 0.9, 1.1,
1416  1.3, 1.5, 1.7, 1.9, 2.1, 2.35, 2.6, 2.8, 3.0,
1417  3.2, 3.4, 3.7, 4.2, 4.7};
1418 
1419  // Transform Eta and Phi indices for the most forward towers into the "original" indices,
1420  // as before rearranging the towers such that the forward region is 12(ieta)x32(iphi).
1421  // The FPGA-C has now the same format (12*32) as FPGA-A and FPGA-B.
1422  // This is the result of a transformation in the firmware.
1423  // Note that for the most forward towers, the Phi index and Eta index have been considered accordingly,
1424  // so in order to get the correct float values of Phi and Eta we need to retrieve the "original" indices.
1425  int towerID_base = 20000;
1426  int iEtaOld=0, iPhiOld=0;
1427 
1428  if (iEta == 2){
1429  if (iPhi == ((gFEXtowerID - towerID_base)/24)*2){
1430  iEtaOld = 0;
1431  iPhiOld = iPhi/2;
1432  }
1433  if (iPhi == (((gFEXtowerID - towerID_base - 12)/24)*2) + 1){
1434  iEtaOld = 1;
1435  iPhiOld = (iPhi-1)/2;
1436  }
1437  }
1438 
1439  else if (iEta == 3){
1440  if (iPhi == ((gFEXtowerID - towerID_base - 1)/24)*2){
1441  iEtaOld = 2;
1442  iPhiOld = iPhi/2;
1443  }
1444  if (iPhi == (((gFEXtowerID - towerID_base - 13)/24)*2) + 1){
1445  iEtaOld = 3;
1446  iPhiOld = (iPhi-1)/2;
1447  }
1448  }
1449 
1450  else if (iEta == 36){
1451  if (iPhi == (((gFEXtowerID - towerID_base - 22)/24)*2) + 1){
1452  iEtaOld = 36;
1453  iPhiOld = (iPhi-1)/2;
1454  }
1455  if (iPhi == ((gFEXtowerID - towerID_base - 10)/24)*2){
1456  iEtaOld = 37;
1457  iPhiOld = iPhi/2;
1458  }
1459  }
1460 
1461  else if (iEta == 37){
1462  if (iPhi == (((gFEXtowerID - towerID_base - 23)/24)*2) + 1){
1463  iEtaOld = 38;
1464  iPhiOld = (iPhi-1)/2;
1465  }
1466  if (iPhi == ((gFEXtowerID - towerID_base - 11)/24)*2){
1467  iEtaOld = 39;
1468  iPhiOld = iPhi/2;
1469  }
1470  }
1471 
1472  else {
1473  iEtaOld = iEta;
1474  iPhiOld = iPhi;
1475  }
1476 
1477  Eta = s_EtaCenter[iEtaOld];
1478 
1479  float Phi_gFex = -99;
1480 
1481  if (( iEtaOld <= 3 ) || ( (iEtaOld >= 36) )){
1482  Phi_gFex = ( (iPhiOld * s_forwardPhiWidth) + s_forwardPhiWidth/2);
1483  }
1484  else {
1485  Phi_gFex = ( (iPhiOld * s_centralPhiWidth) + s_centralPhiWidth/2);
1486  }
1487 
1488  if (Phi_gFex < M_PI) {
1489  Phi = Phi_gFex;
1490  }
1491  else {
1492  Phi = (Phi_gFex - 2*M_PI);
1493  }
1494 }
1495 
1496 void gFexInputByteStreamTool::signExtend(int *xptr, int upto) const{
1497 
1498  // sign extend x to 32 bits assuming a hardware word length upto+1 bits (e.g. for 16 bit word upto should be 15 as in firmware)
1499  // xptr pointer to input datum
1500  // word length in hardware
1501  int x = *xptr;
1502  //printf("before %x \n", x);
1503  //printf("masks %x %x \n", (0x00000001<<upto) , (0xFFFFFFFF<<(upto+1)) );
1504  if( x & (0x00000001<<upto) ) {
1505  x = ( x | (0xFFFFFFFF<<(upto+1)) );
1506  } else {
1507  // for now assume 17 bits -- but could be up to 18 bits
1508  x = ( x & 0x000FFFF);
1509  }
1510  *xptr = x;
1511 
1512 }
1513 
1514 void gFexInputByteStreamTool::gtCalib(gtFPGA &gtf, int towerLSB, int fpga, unsigned int offset ) const{
1515  // does calibration of input gTowers according the fpga and the
1516 
1517  int ABCrows = gtf.size();
1518  int ABcolumns = gtf[0].size();
1519  // check on fpga number to fool compiler into not giving a warning.
1520  // eventually will use for possilbe look up table modification
1521  if(fpga <0 || fpga >2 ) printf("*E: gtCalib FPGA number %d out of range\n",fpga);
1522 
1523  // regular towers 200 MeV towers
1524  // for now just do and undo offset and simulate tuncation effect
1525 
1526  for(int irow=0; irow<ABCrows; irow++){
1527  for( int icolumn=0; icolumn<ABcolumns; icolumn++){
1528 
1529  // 200 MEV Towers
1530  if( towerLSB == 200 ) {
1531  if( gtf[irow][icolumn] > 1500 ){
1532  // printf( "*I gtCalib: gtf before calibration %x offset %x \n", gtf[irow][icolumn], offset);
1533  }
1534  gtf[irow][icolumn] = gtf[irow][icolumn] + offset;
1535 
1536  if( gtf[irow][icolumn] > 2047 ) {
1537  gtf[irow][icolumn] = 2047;
1538  } else if( gtf[irow][icolumn] < 0 ){
1539  gtf[irow][icolumn] = 0;
1540  }
1541  gtf[irow][icolumn] = gtf[irow][icolumn] - offset;
1542 
1543  if( gtf[irow][icolumn] > 1500 ){
1544  // printf( "*I gtCalib: gtf after calibration %x \n", gtf[irow][icolumn] );
1545  }
1546 
1547  //printf( "gtf out %x \n ", gtf[irow][icolumn] );
1548  //#endif
1549 
1550 
1551  // 50 MEV Towers
1552  } else {
1553 
1554  gtf[irow][icolumn] = gtf[irow][icolumn] + offset;
1555 
1556  if( gtf[irow][icolumn] > 1023 ){
1557  gtf[irow][icolumn] = 1023;
1558  } else if ( gtf[irow][icolumn] < 0 ){
1559  gtf[irow][icolumn] = 0;
1560  }
1561  gtf[irow][icolumn] = gtf[irow][icolumn] - offset;
1562 
1563  }
1564  }
1565  }
1566 }
1567 
1568 
1569 
1571 StatusCode gFexInputByteStreamTool::convertToBS(std::vector<WROBF*>& /*vrobf*/, const EventContext& /*eventContext*/) {
1572 
1573  return StatusCode::SUCCESS;
1574 }
1575 
1576 void gFexInputByteStreamTool::printError(const std::string& location, const std::string& title, MSG::Level type, const std::string& detail) const{
1577 
1578  if(m_UseMonitoring){
1580  Monitored::Scalar("gfexDecoderErrorLocation",location.empty() ? std::string("UNKNOWN") : location),
1581  Monitored::Scalar("gfexDecoderErrorTitle" ,title.empty() ? std::string("UNKNOWN") : title)
1582  );
1583  }
1584  else {
1585  msg() << type << detail << endmsg;
1586  }
1587 }
LVL1::gFEXPos::AMSK
constexpr std::array< int, 100 > AMSK
Definition: gFexPos.h:231
gFexInputByteStreamTool::m_robIds
Gaudi::Property< std::vector< uint32_t > > m_robIds
Definition: gFexInputByteStreamTool.h:79
CxxUtils::span
span(T *ptr, std::size_t sz) -> span< T >
A couple needed deduction guides.
LVL1::gFEXPos::CMPD_DSTRT_ARR
constexpr std::array< std::array< int, 20 >, 4 > CMPD_DSTRT_ARR
Definition: gFexPos.h:484
gFexInputByteStreamTool::convertFromBS
virtual StatusCode convertFromBS(const std::vector< const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment * > &vrobf, const EventContext &eventContext) const override
BS->xAOD conversion.
Definition: gFexInputByteStreamTool.cxx:54
TrigDefs::Group
Group
Properties of a chain group.
Definition: GroupProperties.h:13
gFexInputByteStreamTool::gType
std::array< std::array< int, 20 >, 4 > gType
Definition: gFexInputByteStreamTool.h:50
Undefined
@ Undefined
Definition: MaterialTypes.h:8
gFexInputByteStreamTool::m_gTowers50WriteKey
SG::WriteHandleKey< xAOD::gFexTowerContainer > m_gTowers50WriteKey
Definition: gFexInputByteStreamTool.h:83
gFexInputByteStreamTool::gtCalib
virtual void gtCalib(gtFPGA &gtf, int towerLSB, int fpga, unsigned int offset) const
Definition: gFexInputByteStreamTool.cxx:1514
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
gFexInputByteStreamTool::m_monTool
ToolHandle< GenericMonitoringTool > m_monTool
Definition: gFexInputByteStreamTool.h:73
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
LVL1::gFEXPos::FPGA_B_INPUT_HEADER
constexpr uint32_t FPGA_B_INPUT_HEADER
Definition: gFexPos.h:53
LVL1::gFEXPos::AB_COLUMNS
constexpr int AB_COLUMNS
Definition: gFexPos.h:62
gFexInputByteStreamTool::signExtend
virtual void signExtend(int *xptr, int upto) const
Definition: gFexInputByteStreamTool.cxx:1496
LVL1::gFEXPos::CMPD_DTYP_ARR
constexpr std::array< std::array< char, 20 >, 4 > CMPD_DTYP_ARR
Definition: gFexPos.h:492
gFexInputByteStreamTool::m_UseMonitoring
bool m_UseMonitoring
Definition: gFexInputByteStreamTool.h:74
M_PI
#define M_PI
Definition: ActiveFraction.h:11
gFexPos.h
downloadSingle.dataType
string dataType
Definition: downloadSingle.py:18
LVL1::gFEXPos::BMPD_DSTRT_ARR
constexpr std::array< std::array< int, 20 >, 4 > BMPD_DSTRT_ARR
Definition: gFexPos.h:340
LVL1::gFEXPos::CMPD_NFI
constexpr std::array< int, 100 > CMPD_NFI
Definition: gFexPos.h:373
detail
Definition: extract_histogram_tag.cxx:14
gFexInputByteStreamTool::gtFPGA
std::array< std::array< int, 12 >, 32 > gtFPGA
Definition: gFexInputByteStreamTool.h:45
gFexInputByteStreamTool::undoMLE
virtual void undoMLE(int &datumPtr) const
Definition: gFexInputByteStreamTool.cxx:1279
Phi
@ Phi
Definition: RPCdef.h:8
LVL1::gFEXPos::BMPD_NFI
constexpr std::array< int, 100 > BMPD_NFI
Definition: gFexPos.h:239
gFexInputByteStreamTool::a_gtrx_map
virtual void a_gtrx_map(const gfiber &inputData, gfiber &jf_lar_rx_data) const
Definition: gFexInputByteStreamTool.cxx:324
PixelByteStreamErrors::Decoding
@ Decoding
Definition: PixelByteStreamErrors.h:14
LVL1::gFEXPos::BMSK
constexpr std::array< int, 100 > BMSK
Definition: gFexPos.h:365
x
#define x
LVL1::gFEXPos::CMPD_GTRN_ARR
constexpr std::array< std::array< int, 16 >, 100 > CMPD_GTRN_ARR
Definition: gFexPos.h:395
LVL1::gFEXPos::AB_FIBERS
constexpr int AB_FIBERS
Definition: gFexPos.h:57
python.utils.AtlRunQueryLookup.mask
string mask
Definition: AtlRunQueryLookup.py:460
atlasStyleMacro.icol
int icol
Definition: atlasStyleMacro.py:13
LVL1::gFEXPos::BMPD_GTRN_ARR
constexpr std::array< std::array< int, 16 >, 100 > BMPD_GTRN_ARR
Definition: gFexPos.h:255
gFexInputByteStreamTool::gtReconstructABC
virtual void gtReconstructABC(int XFPGA, gfiber Xfiber, int Xin, gtFPGA &XgtF, gtFPGA &Xgt, int *BCIDptr, int do_lconv, const std::array< int, gPos::MAX_FIBERS > &XMPD_NFI, const std::array< int, gPos::MAX_FIBERS > &XCALO_TYPE, const gCaloTwr &XMPD_GTRN_ARR, const gType &XMPD_DSTRT_ARR, gTypeChar XMPD_DTYP_ARR, const std::array< int, gPos::MAX_FIBERS > &XMSK, gtFPGA &Xsatur) const
Definition: gFexInputByteStreamTool.cxx:387
DeMoUpdate.reverse
reverse
Definition: DeMoUpdate.py:563
ROBF
OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment ROBF
Definition: ByteStreamMergeOutputSvc.cxx:16
gFexInputByteStreamTool::crc9d23
uint32_t crc9d23(uint32_t inword, uint32_t in_crc, int reverse) const
Definition: gFexInputByteStreamTool.cxx:1218
gFexInputByteStreamTool::printError
void printError(const std::string &location, const std::string &title, MSG::Level type, const std::string &detail) const
Definition: gFexInputByteStreamTool.cxx:1576
LVL1::gFEXPos::BMPD_DTYP_ARR
constexpr std::array< std::array< char, 20 >, 4 > BMPD_DTYP_ARR
Definition: gFexPos.h:349
Muon::nsw::STGTPPad::n_words
constexpr std::size_t n_words
Definition: NSWSTGTPDecodeBitmaps.h:62
LVL1::gFEXPos::CAL_OFF
constexpr int CAL_OFF
Definition: gFexPos.h:69
LVL1::gFEXPos::GTRX_MAP_B_IND
constexpr std::array< unsigned int, 80 > GTRX_MAP_B_IND
Definition: gFexPos.h:81
beamspotnt.cols
list cols
Definition: bin/beamspotnt.py:1114
LVL1::gFEXPos::W280
constexpr int W280
Definition: gFexPos.h:64
gFexInputByteStreamTool::crc9d32
virtual int crc9d32(const std::array< uint32_t, 6 > &inWords, int numWords, int reverse) const
Definition: gFexInputByteStreamTool.cxx:1154
LVL1::gFEXPos::ACALO_TYPE
constexpr std::array< int, 100 > ACALO_TYPE
Definition: gFexPos.h:112
TrigConf::MSGTC::Level
Level
Definition: Trigger/TrigConfiguration/TrigConfBase/TrigConfBase/MsgStream.h:21
gFexInputByteStreamTool::initialize
virtual StatusCode initialize() override
Definition: gFexInputByteStreamTool.cxx:30
gFexInputByteStreamTool::m_gTowersReadKey
SG::ReadHandleKey< xAOD::gFexTowerContainer > m_gTowersReadKey
Definition: gFexInputByteStreamTool.h:86
gFexInputByteStreamTool::gSatur
std::array< std::array< int, 8 >, 100 > gSatur
Definition: gFexInputByteStreamTool.h:48
lumiFormat.i
int i
Definition: lumiFormat.py:92
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
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
python.sizes.location
string location
Definition: sizes.py:11
covarianceTool.title
title
Definition: covarianceTool.py:542
LVL1::gFEXPos::CMSK
constexpr std::array< int, 100 > CMSK
Definition: gFexPos.h:505
test_pyathena.parent
parent
Definition: test_pyathena.py:15
gFexInputByteStreamTool::gCaloTwr
std::array< std::array< int, 16 >, 100 > gCaloTwr
Definition: gFexInputByteStreamTool.h:47
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
beamspotnt.rows
list rows
Definition: bin/beamspotnt.py:1112
gFexInputByteStreamTool::gfiber
std::array< std::array< uint32_t, 7 >, 100 > gfiber
Definition: gFexInputByteStreamTool.h:43
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
gFexInputByteStreamTool::m_gTowersWriteKey
SG::WriteHandleKey< xAOD::gFexTowerContainer > m_gTowersWriteKey
Definition: gFexInputByteStreamTool.h:82
DataVector::back
const T * back() const
Access the last element in the collection as an rvalue.
LVL1::gFEXPos::GTRX_MAP_C_IND
constexpr std::array< unsigned int, 50 > GTRX_MAP_C_IND
Definition: gFexPos.h:90
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
LVL1::gFEXPos::C_FIBERS
constexpr int C_FIBERS
Definition: gFexPos.h:58
LVL1::gFEXPos::AMPD_GTRN_ARR
constexpr std::array< std::array< int, 16 >, 100 > AMPD_GTRN_ARR
Definition: gFexPos.h:122
gFexInputByteStreamTool::gFexInputByteStreamTool
gFexInputByteStreamTool(const std::string &type, const std::string &name, const IInterface *parent)
Definition: gFexInputByteStreamTool.cxx:25
gFexInputByteStreamTool::getEtaPhi
virtual void getEtaPhi(float &Eta, float &Phi, int iEta, int iPhi, int gFEXtowerID) const
Definition: gFexInputByteStreamTool.cxx:1408
gFexInputByteStreamTool::gFields
std::array< std::array< int, 20 >, 100 > gFields
Definition: gFexInputByteStreamTool.h:46
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
LVL1::gFEXPos::CCALO_TYPE
constexpr std::array< int, 100 > CCALO_TYPE
Definition: gFexPos.h:387
OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment
eformat::ROBFragment< PointerType > ROBFragment
Definition: RawEvent.h:27
SG::VarHandleBase::key
virtual const std::string & key() const override final
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleBase.cxx:64
LVL1::gFEXPos::AMPD_DSTRT_ARR
constexpr std::array< std::array< int, 20 >, 4 > AMPD_DSTRT_ARR
Definition: gFexPos.h:206
Trk::iPhi
@ iPhi
Definition: ParamDefs.h:53
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
LVL1::gFEXPos::FPGA_C_INPUT_HEADER
constexpr uint32_t FPGA_C_INPUT_HEADER
Definition: gFexPos.h:54
LVL1::gFEXPos::AMPD_NFI
constexpr std::array< int, 100 > AMPD_NFI
Definition: gFexPos.h:103
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment
eformat::write::ROBFragment ROBFragment
Definition: RawEvent.h:33
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
WROBF
OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment WROBF
Definition: eFexByteStreamTool.cxx:27
DEBUG
#define DEBUG
Definition: page_access.h:11
convertTimingResiduals.offset
offset
Definition: convertTimingResiduals.py:71
LVL1::gFEXPos::ABC_ROWS
constexpr int ABC_ROWS
Definition: gFexPos.h:61
LVL1::gFEXPos::GTRX_MAP_A_IND
constexpr std::array< unsigned int, 80 > GTRX_MAP_A_IND
Definition: gFexPos.h:72
LVL1::gFEXPos
Definition: gFexPos.h:11
LVL1::gFEXPos::FPGA_A_INPUT_HEADER
constexpr uint32_t FPGA_A_INPUT_HEADER
Definition: gFexPos.h:52
LVL1::gFEXPos::AMPD_DTYP_ARR
constexpr std::array< std::array< char, 20 >, 4 > AMPD_DTYP_ARR
Definition: gFexPos.h:214
gFexInputByteStreamTool::b_gtrx_map
virtual void b_gtrx_map(const gfiber &inputData, gfiber &jf_lar_rx_data) const
Definition: gFexInputByteStreamTool.cxx:345
Monitored::Scalar
Declare a monitored scalar variable.
Definition: MonitoredScalar.h:34
gFexInputByteStreamTool::gTypeChar
std::array< std::array< char, 20 >, 4 > gTypeChar
Definition: gFexInputByteStreamTool.h:51
gFexInputByteStreamTool::convertToBS
virtual StatusCode convertToBS(std::vector< OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment * > &vrobf, const EventContext &eventContext) override
xAOD->BS conversion
Definition: gFexInputByteStreamTool.cxx:1571
xAOD::iEta
setScale setgFexType iEta
Definition: gFexJetRoI_v1.cxx:74
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
Eta
@ Eta
Definition: RPCdef.h:8
gFexInputByteStreamTool::c_gtrx_map
virtual void c_gtrx_map(const gfiber &inputData, gfiber &outputData) const
Definition: gFexInputByteStreamTool.cxx:366
fitman.k
k
Definition: fitman.py:528
gFexInputByteStreamTool.h
LVL1::gFEXPos::BCALO_TYPE
constexpr std::array< int, 100 > BCALO_TYPE
Definition: gFexPos.h:247