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 (XMPD_NFI[i] < 0) continue;
467 
468  if( ( Xfiber[i][gPos::W280-1] & 0x000000FF ) == 0x000000BC ) {
469 
470  fiberFields[i][16] = 1;
471  }
472  else {
473  fiberFields[i][16] = 0;
474  }
475 
476 
477  fiberFields[i][18] = ( Xfiber[i][gPos::W280-1] & 0x007F0000) >>16 ;
478  fiberFields[i][19] = ( Xfiber[i][gPos::W280-1] & 0xFF800000) >>23 ;
479 
480  if (XMPD_DTYP_ARR[ XMPD_NFI[i] ][17] == 8) {
481 
482  fiberFields[i][17] = ( Xfiber[i][gPos::W280-1] & 0x0000FF00) >>8 ;
483  // fill in saturation bits
484  for(unsigned int k=0; k<8; k++){
485  if( fiberFields[i][17] & (1<<k) ) {
486  fiberSaturation[i][k] = 1;
487  }
488  }
489  }
490 
491  int kFilled = 0;
492  for(unsigned int k=0; k<16; k++){
493  if( (XMPD_DTYP_ARR[ XMPD_NFI[i] ][k] != 4 ) && ( XMPD_GTRN_ARR[i][k] > -1 ) ) {
494  int krow = XMPD_GTRN_ARR[i][k]/12;
495  int kcolumn = XMPD_GTRN_ARR[i][k]%12;
496  if(kFilled <8 ){
497  if( fiberSaturation[i][kFilled] == 1 ) {
498  Xsaturation[ krow][kcolumn] = 1;
499  }
500  }
501  kFilled = kFilled + 1;
502  }
503  }
504  }
505 
506  //Loop over fibers
507  for(int iFiber = 0; iFiber < Xin; iFiber++) {
508  // first do CRC check
509  std::array<uint32_t, 6> tmp;
510  for(int i = 0; i < 6; i++){ tmp[i] = Xfiber[iFiber][i]; };
511  // coverity[uninit_use_in_cal : FALSE]
512  uint32_t CRC = crc9d32(tmp, 6, 1);
513  int withoutComma = Xfiber[iFiber][6] & 0xFFFFFF00 ;
514  CRC = crc9d23(withoutComma, CRC, 1 );
515  uint32_t StoredCRC = ( (Xfiber[iFiber][6]>>23) & 0x000001FF);
516  if( (CRC != StoredCRC) && (StoredCRC != 0 ) ) {
517 
518  std::stringstream sdetail;
519  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: Fiber " << iFiber << "of Xin " << Xin << ": BAD New CRC: " << CRC << "Stored CRC "<< StoredCRC ;
520  std::stringstream slocation;
521  slocation << "Fiber " << iFiber << "of Xin " << Xin;
522  std::stringstream stitle;
523  stitle << "Bad CRC" ;
524  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
525 
526  }
527 
528  // now check if CRC lower bits are correct in the trailer
529  int fiber_type = XMPD_NFI[iFiber];
530  // each fiber has 20 pieces of information -- called iDatum here
531  for(int iDatum = 0; iDatum < 16; iDatum++) {
532  // tells where the data is coming from -- see data field type above
533  int dataType = XMPD_DTYP_ARR[fiber_type][iDatum];
534  // tower number 0 - 383
535  int ntower = XMPD_GTRN_ARR[iFiber][iDatum];
536  if( ntower == -1 ){
537  ATH_MSG_DEBUG("[gFexInputByteStreamTool::gtReconstructABC: unused location iFiber "<< iFiber << ", calo type "<< XCALO_TYPE[iFiber]<<", data type "<< dataType <<", iDatum " << iDatum << "tower " << ntower);
538  }
539  else if( (ntower < 0) || (ntower >383) ){
540 
541  std::stringstream sdetail;
542  sdetail << "[gFexInputByteStreamTool::gtReconstructABC: bad value of ntower: iFiber "<< iFiber<< ", calo type"<< XCALO_TYPE[iFiber]<< ", data type "<< dataType<< ", iDatum "<< iDatum<< "tower "<< ntower ;
543  std::stringstream slocation;
544  slocation << "iFiber "<< iFiber<< ", calo type"<< XCALO_TYPE[iFiber];
545  std::stringstream stitle;
546  stitle << "Bad value of ntower" ;
547  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
548 
549  }
550 
551  // bit number in the 32*7 = 234 bits transmitted in one BC
552  // word refers to the 7 32 bits words transmitted in each BC
553  int ihigh = XMPD_DSTRT_ARR[fiber_type][iDatum];
554  int ihword = ihigh/32;
555  int ihbit = ihigh%32;
556 
557  int ilow = 0;
558  int ilword = 0;
559  int ilbit = 0;
560 
561  int hTREXval = 0;
562  int lTREXval = 0;
563  int hHECval = 0;
564  int lHECval = 0;
565 
566  // need to be sure to skip positon data!
567  int mask = 0;
568  int lmask = 0;
569  int hmask = 0;
570 
571  if( XMSK[iFiber] != 1 ) {
572  dataType = 99;
573  }
574 
575  //Different kinds of data type
576  if( (XCALO_TYPE[iFiber] < 3) && (ntower>-1) && (ntower<384) ) {
577  switch(dataType){
578  case 0:
579  ilow = ihigh - 11;
580  ilword = ilow/32;
581  ilbit = ilow%32;
582  if(ilword == ihword){
583  mask = 0x00000FFF;
584  mask = mask << (ilbit);
585  etowerData[ntower] = etowerData[ntower] | ( (Xfiber[iFiber][ihword] & mask) >> ilbit );
586  // undo multilinear decoding
587  if( do_lconv){
588  fiberFieldsUndecoded[iFiber][iDatum] = etowerData[ntower];
589  undoMLE( etowerData[ntower] );
590  etowerDataF[ntower] = etowerData[ntower];
591  fiberFields[iFiber][iDatum] = etowerData[ntower];
592 
593  }
594  else {
595  // sign extend etower data
596  if( etowerData[ntower] & 0x00000800 ){ etowerData[ntower] = (etowerData[ntower] | 0xFFFFF000) ;}
597  etowerData[ntower] = etowerData[ntower]*4;
598  etowerDataF[ntower] = etowerData[ntower];
599  }
600  }
601  else {
602 
603  std::stringstream sdetail;
604  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: wrongly packed data "<< fiber_type<< ", "<<dataType<< ", "<<ilword<< ", " <<ihword ;
605  std::stringstream slocation;
606  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
607  std::stringstream stitle;
608  stitle << "Wrongly packed data" ;
609  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
610 
611  }
612  break;
613 
614  case 1:
615  ilow = ihigh - 11;
616  ilword = ilow/32;
617  ilbit = ilow%32;
618 
619  hTREXval = Xfiber[iFiber][ihword];
620  lTREXval = Xfiber[iFiber][ilword];
621  mask =0;
622  lmask =0;
623  hmask =0;
624 
625  if(ilword == ihword){
626  mask = 0x00000FFF;
627  mask = mask << ilbit;
628  htowerData[ntower] = htowerData[ntower] | ( (hTREXval & mask) >> (ilbit) );
629  }
630  else if ( ihbit == 7 ) {
631  mask = 0x0000000F;
632  hmask = 0x000000FF;
633  htowerData[ntower] = htowerData[ntower] | ( (hTREXval & hmask) << 4);
634  lmask = 0xF0000000;
635  htowerData[ntower] = htowerData[ntower] | ( ( (lTREXval & lmask) >> 28)&mask) ;
636  }
637  else if ( ihbit == 3) {
638  mask = 0x000000FF;
639  hmask = 0x0000000F;
640  htowerData[ntower] = htowerData[ntower] | ( ( hTREXval & hmask) << 8);
641  lmask = 0xFF000000;
642  htowerData[ntower] = htowerData[ntower] | ( ( (lTREXval & lmask) >> 24) &mask) ;
643  }
644  else {
645 
646  std::stringstream sdetail;
647  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: wrongly packed data "<< fiber_type<< ", "<<dataType<< ", "<<ilword<< ", " <<ihword ;
648  std::stringstream slocation;
649  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
650  std::stringstream stitle;
651  stitle << "Wrongly packed data" ;
652  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
653 
654  }
655 
656  // mulitply by 20 to make 50 MeV LSB
657  if( (Xin > 50) ) {
658  // include this here before mulitplicaiton by 20
659  fiberFieldsUndecoded[iFiber][iDatum] = htowerData[ntower];
660  htowerData[ntower] = 20*htowerData[ntower];
661  htowerDataF[ntower] = htowerData[ntower];
662  fiberFields[iFiber][iDatum] = htowerData[ntower];
663  }
664  else {
665  if( do_lconv){
666  fiberFieldsUndecoded[iFiber][1] = htowerData[ntower];
667  undoMLE( htowerData[ntower] );
668  htowerDataF[ntower] = htowerData[ntower];
669  fiberFields[iFiber][1] = htowerData[ntower];
670  }
671  else {
672  // sign extend etower data
673  if( htowerData[ntower] & 0x00000800 ){ htowerData[ntower] = (htowerData[ntower] | 0xFFFFF000) ;}
674  htowerData[ntower] = htowerData[ntower]*4;
675  htowerDataF[ntower] = htowerData[ntower];
676  }
677  }
678  break;
679 
680  case 2:
681  ilow = ihigh - 11;
682  ilword = ilow/32;
683  ilbit = ilow%32;
684  if( (ntower > 32) || (ntower < 0) ){
685 
686  std::stringstream sdetail;
687  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: bad value of nTower for extended region 2.4 - 2.5 in eta" ;
688  std::stringstream slocation;
689  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
690  std::stringstream stitle;
691  stitle << "Bad value of nTower in extended eta" ;
692  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
693 
694  }
695  if(ilword == ihword){
696  int mask = 0x00000FFF;
697  mask = mask << ilbit;
698  xetowerData[ntower] = xetowerData[ntower] | ( (Xfiber[iFiber][ihword]&mask) >> (ilbit) );
699  }
700  else if ( ihbit == 7 ) {
701  mask = 0x0000000F;
702  hmask = 0x000000FF;
703  xetowerData[ntower] = xetowerData[ntower] | ( (Xfiber[iFiber][ihword]&hmask) << 4);
704  lmask = 0xF0000000;
705  xetowerData[ntower] = xetowerData[ntower] | ( ( (Xfiber[iFiber][ilword]&lmask) >> 28)&mask) ;
706  }
707  else if ( ihbit == 3) {
708  mask = 0x000000FF;
709  hmask = 0x000000F;
710  xetowerData[ntower] = xetowerData[ntower] | ( (Xfiber[iFiber][ihword]&hmask) << 8);
711  lmask = 0xFF000000;
712  xetowerData[ntower] = xetowerData[ntower] | ( ( (Xfiber[iFiber][ilword]&lmask) >> 24)&mask) ;
713  }
714  else {
715 
716  std::stringstream sdetail;
717  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: wrongly packed data "<< fiber_type<< ", "<<dataType<< ", "<<ilword<< ", " <<ihword ;
718  std::stringstream slocation;
719  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
720  std::stringstream stitle;
721  stitle << "Wrongly packed data" ;
722  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
723 
724  }
725  // undo multilinear decoding
726  if( do_lconv){
727  fiberFieldsUndecoded[iFiber][iDatum] = xetowerData[ntower];
728  undoMLE( xetowerData[ntower] );
729  xetowerDataF[ntower] = xetowerData[ntower];
730  fiberFields[iFiber][iDatum] = xetowerData[ntower];
731 
732  }
733  else {
734  // sign extend etower data
735  if( xetowerData[ntower] & 0x00000800 ){ xetowerData[ntower] = (xetowerData[ntower] | 0xFFFFF000) ;}
736  xetowerData[ntower] = xetowerData[ntower]*4;
737  xetowerDataF[ntower] = xetowerData[ntower];
738  }
739  break;
740 
741  case 3:
742  ilow = ihigh - 11;
743  ilword = ilow/32;
744  ilbit = ilow%32;
745  if(ilword == ihword){
746  mask = 0x00000FFF;
747  mask = mask << ilbit;
748  xhtowerData[ntower] = xhtowerData[ntower] | ( (Xfiber[iFiber][ihword]&mask) >> (ilbit) );
749  }
750  else if ( ihbit == 7 ) {
751  mask = 0x0000000F;
752  hmask = 0x000000FF;
753  xhtowerData[ntower] = xhtowerData[ntower] | ( (Xfiber[iFiber][ihword]&hmask) << 4);
754  lmask = 0xF0000000;
755  xhtowerData[ntower] = xhtowerData[ntower] | ( ( (Xfiber[iFiber][ilword]&lmask) >> 28)&mask) ;
756  }
757  else if ( ihbit == 3) {
758  mask = 0x000000FF;
759  hmask = 0x0000000F;
760  xhtowerData[ntower] = xhtowerData[ntower] | ( (Xfiber[iFiber][ihword]&hmask) << 8);
761  lmask = 0xFF000000;
762  xhtowerData[ntower] = xhtowerData[ntower] | ( ( (Xfiber[iFiber][ilword]&lmask) >> 24)&mask) ;
763  }
764  else {
765 
766  std::stringstream sdetail;
767  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: wrongly packed data "<< fiber_type<< ", "<<dataType<< ", "<<ilword<< ", " <<ihword ;
768  std::stringstream slocation;
769  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
770  std::stringstream stitle;
771  stitle << "Wrongly packed data" ;
772  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
773 
774  }
775  if( ntower > 32 ){
776 
777  std::stringstream sdetail;
778  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: bad value of nTower for extended region 2.4 - 2.5 in eta" ;
779  std::stringstream slocation;
780  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
781  std::stringstream stitle;
782  stitle << "Bad value of nTower in extended eta" ;
783  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
784 
785  }
786  // undo multilinear decoding
787  if( do_lconv){
788  fiberFieldsUndecoded[iFiber][iDatum] = xhtowerData[ntower];
789  undoMLE( xhtowerData[ntower] );
790  xhtowerDataF[ntower] = xhtowerData[ntower];
791  fiberFields[iFiber][iDatum] = xhtowerData[ntower];
792  }
793  else {
794  // sign extend etower data
795  if( xhtowerData[ntower] & 0x00000800 ){ xhtowerData[ntower] = (xhtowerData[ntower] | 0xFFFFF000) ;}
796  xhtowerData[ntower] = xhtowerData[ntower]*4;
797  xhtowerDataF[ntower] = xhtowerData[ntower];
798  }
799  break;
800 
801  case 6:
802  ilow = ihigh - 11;
803  ilword = ilow/32;
804  ilbit = ilow%32;
805  if(ilword == ihword){
806  mask = 0x00000FFF;
807  mask = mask << ilbit;
808  ohtowerData[ntower] = ohtowerData[ntower] | ( (Xfiber[iFiber][ihword]&mask) >> (ilbit) );
809  }
810  else if ( ihbit == 7 ) {
811  mask = 0x0000000F;
812  hmask = 0x000000FF;
813  ohtowerData[ntower] = ohtowerData[ntower] | ( (Xfiber[iFiber][ihword]&hmask) << 4);
814  lmask = 0xF0000000;
815  ohtowerData[ntower] = ohtowerData[ntower] | ( ( (Xfiber[iFiber][ilword]&lmask) >> 28)&mask) ;
816  }
817  else if ( ihbit == 3) {
818  mask = 0x000000FF;
819  hmask = 0x0000000F;
820  ohtowerData[ntower] = ohtowerData[ntower] | ( (Xfiber[iFiber][ihword]&hmask) << 8);
821  lmask = 0xFF000000;
822  ohtowerData[ntower] = ohtowerData[ntower] | ( ( (Xfiber[iFiber][ilword]&lmask) >> 24)&mask) ;
823  }
824  else {
825 
826  std::stringstream sdetail;
827  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: wrongly packed data "<< fiber_type<< ", "<<dataType<< ", "<<ilword<< ", " <<ihword ;
828  std::stringstream slocation;
829  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
830  std::stringstream stitle;
831  stitle << "Wrongly packed data" ;
832  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
833 
834  }
835  if( ntower > 32 ){
836 
837  std::stringstream sdetail;
838  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: bad value of nTower for extended region 2.4 - 2.5 in eta" ;
839  std::stringstream slocation;
840  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
841  std::stringstream stitle;
842  stitle << "Bad value of nTower in extended eta" ;
843  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
844 
845  }
846  if( do_lconv){
847  fiberFieldsUndecoded[iFiber][iDatum] = ohtowerData[ntower];
848  undoMLE( ohtowerData[ntower] );
849  ohtowerDataF[ntower] = ohtowerData[ntower];
850  fiberFields[iFiber][iDatum] = ohtowerData[ntower];
851  }
852  else {
853  // sign extend etower data
854  if( ohtowerData[ntower] & 0x00000800 ){ ohtowerData[ntower] = (ohtowerData[ntower] | 0xFFFFF000) ;}
855  ohtowerData[ntower] = ohtowerData[ntower]*4;
856  ohtowerDataF[ntower] = ohtowerData[ntower];
857  }
858  break;
859 
860  case 11:
861  ilow = ihigh - 11;
862  ilword = ilow/32;
863  ilbit = ilow%32;
864 
865  hHECval = Xfiber[iFiber][ihword];
866  lHECval = Xfiber[iFiber][ilword];
867  if(ilword == ihword){
868  mask = 0x00000FFF;
869  mask = mask << ilbit;
870  htowerData[ntower] = htowerData[ntower] | ( (hHECval & mask) >> (ilbit) );
871  }
872  else if ( ihbit == 7 ) {
873  mask = 0x0000000F;
874  hmask = 0x000000FF;
875  htowerData[ntower] = htowerData[ntower] | ( (hHECval & hmask) << 4);
876  lmask = 0xFF000000;
877  htowerData[ntower] = htowerData[ntower] | ( ( (lHECval & lmask) >> 28)&mask) ;
878  }
879  else if ( ihbit == 3) {
880  mask = 0x000000FF;
881  hmask = 0x0000000F;
882  htowerData[ntower] = htowerData[ntower] | ( ( hHECval & hmask) << 8);
883  lmask = 0xFF000000;
884  htowerData[ntower] = htowerData[ntower] | ( ( (lHECval & lmask) >> 24) &mask) ;
885  }
886  else {
887 
888  std::stringstream sdetail;
889  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: wrongly packed data "<< fiber_type<< ", "<<dataType<< ", "<<ilword<< ", " <<ihword ;
890  std::stringstream slocation;
891  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
892  std::stringstream stitle;
893  stitle << "Wrongly packed data" ;
894  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
895 
896  }
897  if( do_lconv){
898  fiberFieldsUndecoded[iFiber][iDatum] = htowerData[ntower];
899  undoMLE( htowerData[ntower] );
900  htowerDataF[ntower] = htowerData[ntower];
901  fiberFields[iFiber][iDatum] = htowerData[ntower];
902  }
903  else {
904  // sign extend etower data
905  if( htowerData[ntower] & 0x00000800 ){ htowerData[ntower] = (htowerData[ntower] | 0xFFFFF000) ;}
906  htowerData[ntower] = htowerData[ntower]*4;
907  htowerDataF[ntower] = htowerData[ntower];
908  }
909  break;
910  }
911  // FPGA C EMEC/HEC + FCAL
912  // These all have same dataType as extended ECAL and extended HCAL
913  }
914  else if ( (ntower>-1) && (ntower<384) ){
915  // this is FPGA C
916  // only types 2 and 3 exist in FPGA C
917 
918  switch(dataType){
919  case 2:
920  ilow = ihigh - 11;
921  ilword = ilow/32;
922  ilbit = ilow%32;
923 
924  if( etowerData[ntower] != 0 ) {
925 
926  std::stringstream sdetail;
927  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: etowerData[nTower] is not zero, inconsistent constants! "<< etowerData[ntower] ;
928  std::stringstream slocation;
929  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
930  std::stringstream stitle;
931  stitle << "etowerData not zero" ;
932  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
933 
934  } else {
935 
936  if(ilword == ihword){
937  int mask = 0x00000FFF;
938  mask = mask << ilbit;
939  etowerData[ntower] = etowerData[ntower] | ( (Xfiber[iFiber][ihword]&mask) >> (ilbit) );
940  }
941  else if ( ihbit == 7 ) {
942  mask = 0x0000000F;
943  hmask = 0x000000FF;
944  etowerData[ntower] = etowerData[ntower] | ( (Xfiber[iFiber][ihword]&hmask) << 4);
945  lmask = 0xF0000000;
946  etowerData[ntower] = etowerData[ntower] | ( ( (Xfiber[iFiber][ilword]&lmask) >> 28)&mask) ;
947  }
948  else if ( ihbit == 3) {
949  mask = 0x000000FF;
950  hmask = 0x000000F;
951  etowerData[ntower] = etowerData[ntower] | ( (Xfiber[iFiber][ihword]&hmask) << 8);
952  lmask = 0xFF000000;
953  etowerData[ntower] = etowerData[ntower] | ( ( (Xfiber[iFiber][ilword]&lmask) >> 24)&mask) ;
954  }
955  else {
956 
957  std::stringstream sdetail;
958  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: wrongly packed data "<< fiber_type<< ", "<<dataType<< ", "<<ilword<< ", " <<ihword ;
959  std::stringstream slocation;
960  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
961  std::stringstream stitle;
962  stitle << "Wrongly packed data" ;
963  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
964 
965  }
966  // undo multilinear decoding
967  if( do_lconv){
968  fiberFieldsUndecoded[iFiber][iDatum] = etowerData[ntower];
969  undoMLE( etowerData[ntower] );
970  etowerDataF[ntower] = etowerData[ntower];
971  fiberFields[iFiber][iDatum] = etowerData[ntower];
972  }
973  else {
974  // sign extend etower data
975  if( etowerData[ntower] & 0x00000800 ){ etowerData[ntower] = (etowerData[ntower] | 0xFFFFF000) ;}
976  etowerData[ntower] = etowerData[ntower]*4;
977  etowerDataF[ntower] = etowerData[ntower];
978  }
979  }
980  break;
981 
982  case 3:
983  ilow = ihigh - 11;
984  ilword = ilow/32;
985  ilbit = ilow%32;
986 
987  if( htowerData[ntower] != 0 ) {
988  std::stringstream sdetail;
989  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: etowerData[nTower] is not zero, inconsistent constants! "<< etowerData[ntower] ;
990  std::stringstream slocation;
991  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
992  std::stringstream stitle;
993  stitle << "etowerData not zero" ;
994  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
995 
996  } else {
997 
998  if(ilword == ihword){
999  mask = 0x00000FFF;
1000  mask = mask << ilbit;
1001  htowerData[ntower] = htowerData[ntower] | ( (Xfiber[iFiber][ihword]&mask) >> (ilbit) );
1002  }
1003  else if ( ihbit == 7 ) {
1004  mask = 0x0000000F;
1005  hmask = 0x000000FF;
1006  htowerData[ntower] = htowerData[ntower] | ( (Xfiber[iFiber][ihword]&hmask) << 4);
1007  lmask = 0xF0000000;
1008  htowerData[ntower] = htowerData[ntower] | ( ( (Xfiber[iFiber][ilword]&lmask) >> 28)&mask) ;
1009  }
1010  else if ( ihbit == 3) {
1011  mask = 0x000000FF;
1012  hmask = 0x0000000F;
1013  htowerData[ntower] = htowerData[ntower] | ( (Xfiber[iFiber][ihword]&hmask) << 8);
1014  lmask = 0xFF000000;
1015  htowerData[ntower] = htowerData[ntower] | ( ( (Xfiber[iFiber][ilword]&lmask) >> 24)&mask) ;
1016  }
1017  else {
1018 
1019  std::stringstream sdetail;
1020  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: wrongly packed data "<< fiber_type<< ", "<<dataType<< ", "<<ilword<< ", " <<ihword ;
1021  std::stringstream slocation;
1022  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
1023  std::stringstream stitle;
1024  stitle << "Wrongly packed data" ;
1025  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
1026 
1027  }
1028  // undo multilinear decoding
1029  if( do_lconv){
1030  fiberFieldsUndecoded[iFiber][iDatum] = htowerData[ntower];
1031  undoMLE( htowerData[ntower] );
1032  htowerDataF[ntower] = htowerData[ntower];
1033  fiberFields[iFiber][iDatum] = htowerData[ntower];
1034  }
1035  else {
1036  // sign extend etower data
1037  if( htowerData[ntower] & 0x00000800 ){ htowerData[ntower] = (htowerData[ntower] | 0xFFFFF000) ;}
1038  htowerData[ntower] = htowerData[ntower]*4;
1039  htowerDataF[ntower] = htowerData[ntower];
1040  }
1041  }
1042  break;
1043 
1044  case 15:
1045  break;
1046 
1047  case 99:
1048  break;
1049 
1050  default:
1051 
1052  std::stringstream sdetail;
1053  sdetail << "[gFexInputByteStreamTool::gtReconstructABC]: wrong detector type "<< dataType ;
1054  std::stringstream slocation;
1055  slocation << "Fiber type "<< fiber_type<< " and data type"<< dataType;
1056  std::stringstream stitle;
1057  stitle << "Wrong detector type" ;
1058  printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
1059 
1060  } // end of case statement for FPGAC
1061  } // end of | eta | > 2,5
1062  } // end of loop over words
1063  } // end of loop over fibers
1064 
1065 
1066  // no need for xdtower, xhtower and ohtower in FPGA C -- but these will all be zero in that case.
1067  if( XFPGA == 0 ) {
1068  for(int itower=0;itower<384;itower++){
1069  int icolumn = itower%12;
1070  int irow = itower/12;
1071 
1072  // 50 MeV towers
1073  int xF = etowerDataF[itower] + htowerDataF[itower];
1074  // 200 MeV towers
1075  int x = ( (etowerData[itower]>>2) + (htowerData[itower]>>2) );
1076 
1077  signExtend(&xF,18);
1078  signExtend(&x,18);
1079 
1080  Xgt[irow][icolumn] = x;
1081  XgtF[irow][icolumn] = xF;
1082 
1083  // etra region in FPGA A (eta ~ -2.5)
1084  if ( icolumn == 0) {
1085  int xx = ( (xetowerData[irow]>>2) + (xhtowerData[irow]>>2) );
1086  signExtend(&xx,18);
1087  Xgt[irow][icolumn] = Xgt[irow][icolumn] + xx;
1088  }
1089  if ( icolumn == 4) {
1090  // 200 MeV towers
1091  int ox = (ohtowerData[irow] >> 2 ) ;
1092  signExtend(&ox,18);
1093  Xgt[irow][icolumn] = Xgt[irow][icolumn] + ox ;
1094  }
1095  }
1096  }
1097  else if ( XFPGA == 1 ) {
1098  for(int itower=0;itower<384;itower++){
1099  int icolumn = itower%12;
1100  int irow = itower/12;
1101 
1102  // 50 MeV towers
1103  int xF = etowerDataF[itower] + htowerDataF[itower] ;
1104  // 200 MeV towers
1105  int x = ( (etowerData[itower]>>2) + (htowerData[itower] >> 2) );
1106 
1107  signExtend(&xF,18);
1108  signExtend(&x,18);
1109 
1110  Xgt[irow][icolumn] = x;
1111  XgtF[irow][icolumn] = xF;
1112 
1113  // extra region FPGA B (eta ~ 2.5)
1114  if ( icolumn == 11) {
1115  // 50 MeV towers
1116  // int xxF = xetower_dataF[irow] + xhtower_dataF[irow] ;
1117  // 200 MeV towers
1118  int xx = ( (xetowerData[irow]>>2) + (xhtowerData[irow]>>2) );
1119  // signExtend(&xxF,18);
1120  signExtend(&xx,18);
1121  Xgt[irow][icolumn] = Xgt[irow][icolumn] + xx;
1122  }
1123  if ( icolumn == 7 ) {
1124  // 200 MeV towers
1125  // int xoF = ohtowerData[irow];
1126  int xo = ohtowerData[irow]>>2;
1127  // signExtend(&xoF,18);
1128  signExtend(&xo,18);
1129  Xgt[irow][icolumn] = Xgt[irow][icolumn] + xo;
1130  }
1131  }
1132  }
1133  else if ( XFPGA == 2 ) {
1134  for(int itower=0;itower<384;itower++){
1135  int icolumn = itower%12;
1136  int irow = itower/12;
1137 
1138  // 50 MeV towers
1139  int xF = etowerDataF[itower] + htowerDataF[itower] ;
1140  // 200 MeV towers
1141  int x = ( (etowerData[itower]>>2 ) + (htowerData[itower]>>2));
1142  signExtend(&xF,18);
1143  signExtend(&x,18);
1144 
1145  Xgt[irow][icolumn] = x;
1146  XgtF[irow][icolumn] = xF;
1147  }
1148  }
1149  else {
1150  ATH_MSG_DEBUG("[gFexInputByteStreamTool::gtReconstructABC]: Bad FPGA # "<< XFPGA);
1151  }
1152 }
1153 
1154 
1155 
1156 int gFexInputByteStreamTool::crc9d32(const std::array<uint32_t, 6> &inWords,int numWords,int reverse) const{
1157  // calculate this for reversed bits
1158 
1159  std::array<uint32_t, 32> dIn;
1160  std::array<uint32_t, 9> crc_s;
1161  std::array<uint32_t, 9> crc_r;
1162 
1163  crc_s.fill(1);
1164  crc_r.fill(1);
1165 
1166  int crc_word = 0x000;
1167  unsigned int mask = 0x00000001;
1168 
1169  for(int k =0; k < numWords; k++) {
1170  if( reverse == 1 ) {
1171  for (int i =0 ; i < 32; i++ ) {
1172  dIn[31-i] = (inWords[k] & (mask << i));
1173  dIn[31-i] = ((dIn[31-i] >> i) & 0x00000001);
1174  }
1175  }
1176  else {
1177  for (int i =0 ; i<32; i++ ) {
1178  dIn[i] = inWords[k] & (mask << i);
1179  dIn[i] = ((dIn[i] >> i) & 0x0000001);
1180  }
1181  }
1182  for(int j=0; j<9; j++){
1183  crc_s[j] = crc_r[j];
1184  }
1185 
1186  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];
1187 
1188  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];
1189 
1190  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];
1191 
1192  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];
1193 
1194  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];
1195 
1196  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];
1197 
1198  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];
1199 
1200  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];
1201 
1202  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];
1203 
1204  }
1205 
1206  if ( reverse == 1){
1207  for (int i = 0; i < 9; i++) {
1208  crc_word = crc_word | (crc_r[8-i] << i) ;
1209  }
1210  }
1211  else {
1212  for(int i = 0; i < 9; i++ ){
1213  crc_word = crc_word | (crc_r[i] << i);
1214  }
1215  }
1216  return crc_word;
1217 }
1218 
1219 
1221 
1222  int mask = 0x00000001;
1223  //#dIn is a '23-bit input word'
1224  std::array<uint32_t, 23> dIn;
1225 
1226  std::array<uint32_t, 9> crc_r;
1227  std::array<uint32_t, 9> crc_in_s;
1228 
1229  crc_r.fill(1);
1230  crc_in_s.fill(1);
1231 
1232  int crc_word = 0x000;
1233 
1234  //32-bit word crc calculation
1235 
1236  if (reverse == 1) {
1237  for(int i = 0; i < 23;i++){
1238  dIn[22-i] = ( inword & (mask << i));
1239  dIn[22-i] = ( dIn[22-i] >> i);
1240  }
1241  for(int i = 0; i < 9;i++){
1242  crc_in_s[8-i] = ( in_crc & (mask << i) );
1243  crc_in_s[8-i] = ( crc_in_s[8-i] >> i );
1244  }
1245  }
1246  else{
1247  for(int i = 0; i < 23; i++) {
1248  dIn[i] = ( inword & (mask << i) );
1249  dIn[i] = (dIn[i] >> i);
1250  }
1251  for(int i=0; i<9; i++){
1252  crc_in_s[i] = ( in_crc & (mask << i));
1253  crc_in_s[i] = (crc_in_s[i] >> i);
1254  }
1255  }
1256 
1257  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];
1258  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];
1259  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];
1260  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];
1261  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];
1262  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];
1263  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];
1264  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];
1265  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];
1266 
1267  crc_word = 0x000;
1268  if (reverse == 1){
1269  for(int i = 0; i < 9; i++) {
1270  crc_word = ( crc_word | (crc_r[8-i] << i));
1271  }
1272  }
1273  else{
1274  for(int i = 0; i < 9; i++) {
1275  crc_word = ( crc_word | (crc_r[i] << i) );
1276  }
1277  }
1278  return (crc_word);
1279 }
1280 
1281 void gFexInputByteStreamTool::undoMLE(int &datumPtr ) const{
1282  // limit input to 12 bits to avoid accidental sign extension
1283  int din = (0x00000FFF & datumPtr );
1284  // map all special cases to zero for now
1285  if( din > 0x0FDE ) din = 0x4EE;
1286  // limit negative values
1287  if( (din > 0) && ( din < 962 ) ) din = 962;
1288  //zeroZero
1289  if( din == 0) din = 0x4EE;
1290 
1291  int dout = 0;
1292 
1293  int FPGA_CONVLIN_TH1 = 5;
1294  int FPGA_CONVLIN_TH2 = 749;
1295  int FPGA_CONVLIN_TH3 = 1773;
1296  int FPGA_CONVLIN_TH4 = 2541;
1297  int FPGA_CONVLIN_TH5 = 4029;
1298 
1299  int FPGA_CONVLIN_OF0 = -5072;
1300  int FPGA_CONVLIN_OF1 = -2012;
1301  int FPGA_CONVLIN_OF2 = -1262;
1302  int FPGA_CONVLIN_OF3 = -3036;
1303  int FPGA_CONVLIN_OF4 = -8120;
1304  int FPGA_CONVLIN_OF5 = -4118720;
1305 
1306  int oth0 = 0;
1307  int oth1 = 0;
1308  int oth2 = 0;
1309  int oth3 = 0;
1310  int oth4 = 0;
1311  int oth5 = 0;
1312 
1313  int r1shv = 0;
1314  int r2shv = 0;
1315  int r3shv = 0;
1316  int r4shv = 0;
1317  int r5shv = 0;
1318  int r6shv = 0;
1319  // int trxv = 0;
1320 
1321  int r1conv = 0;
1322  int r2conv = 0;
1323  int r3conv = 0;
1324  int r4conv = 0;
1325  int r5conv = 0;
1326  int r6conv = 0;
1327  // int r3offs = 0;
1328 
1329  r1shv = ((din & 0x0000007F) << 9 ) & 0x0000FE00 ;
1330  r2shv = ((din & 0x00000FFF) << 1 ) & 0x00001FFE ;
1331  r3shv = (din & 0x00000FFF) ;
1332  r4shv = ((din & 0x00000FFF) << 1 ) & 0x00001FFE ;
1333  r5shv = ((din & 0x00000FFF) << 2 ) & 0x00003FFC ;
1334  r6shv = ((din & 0x00000FFF) << 10 ) & 0x003FFC00 ;
1335 
1336  r1conv = r1shv + FPGA_CONVLIN_OF0;
1337  r2conv = r2shv + FPGA_CONVLIN_OF1;
1338  r3conv = r3shv + FPGA_CONVLIN_OF2;
1339  r4conv = r4shv + FPGA_CONVLIN_OF3;
1340  r5conv = r5shv + FPGA_CONVLIN_OF4;
1341  r6conv = r6shv + FPGA_CONVLIN_OF5;
1342 
1343  if( din > 0 ) {
1344  oth0 = 1;
1345  }
1346  else{
1347  oth0 = 0;
1348  }
1349  if ( din > FPGA_CONVLIN_TH1 ){
1350  oth1 = 1;
1351  }
1352  else{
1353  oth1 = 0;
1354  }
1355  if ( din > FPGA_CONVLIN_TH2 ){
1356  oth2 = 1;
1357  }else{
1358  oth2 = 0;
1359  }
1360  if ( din > FPGA_CONVLIN_TH3 ){
1361  oth3 = 1;
1362  }else{
1363  oth3 = 0;
1364  }
1365  if ( din > FPGA_CONVLIN_TH4 ){
1366  oth4 = 1;
1367  }else{
1368  oth4 = 0;
1369  }
1370  if ( din > FPGA_CONVLIN_TH5 ){
1371  oth5 = 1;
1372  }
1373  else{
1374  oth5 = 0;
1375  }
1376 
1377  // divide by 2 to 50 MeV LSB
1378 
1379  if( (! oth0) & (! oth1 ) & (! oth2 ) & (! oth3 ) & (! oth4 ) & (! oth5 ) ) {
1380  dout = 0;
1381  }
1382  else if( ( oth0) & (! oth1 ) & (! oth2 ) & (! oth3 ) & (! oth4 ) & (! oth5 ) ) {
1383  dout = r1conv >>1;
1384  }
1385  else if( ( oth0) & ( oth1 ) & (! oth2 ) & (! oth3 ) & (! oth4 ) & (! oth5 ) ) {
1386  dout = r2conv >>1;
1387  }
1388  else if( ( oth0) & ( oth1 ) & ( oth2 ) & (! oth3 ) & (! oth4 ) & (! oth5 ) ) {
1389  dout = r3conv >>1;
1390  }
1391  else if( ( oth0) & ( oth1 ) & ( oth2 ) & ( oth3 ) & (! oth4 ) & (! oth5 ) ) {
1392  dout = r4conv >>1;
1393  }
1394  else if( ( oth0) & ( oth1 ) & ( oth2 ) & ( oth3 ) & ( oth4 ) & (! oth5 ) ) {
1395  dout = r5conv >>1;
1396  }
1397  else if( ( oth0) & ( oth1 ) & ( oth2 ) & ( oth3 ) & ( oth4 ) & ( oth5 ) ) {
1398  dout = r6conv >>1;
1399  }
1400  else {
1401  dout = 0;
1402  }
1403 
1404  signExtend(&dout,15);
1405 
1406  datumPtr = dout;
1407 }
1408 
1409 
1410 void gFexInputByteStreamTool::getEtaPhi ( float &Eta, float &Phi, int iEta, int iPhi, int gFEXtowerID) const{
1411 
1412  float s_centralPhiWidth = (2*M_PI)/32; //In central region, gFex has 32 bins in phi
1413  float s_forwardPhiWidth = (2*M_PI)/16; //In forward region, gFex has 16 bins in phi (before rearranging bins)
1414 
1415  const std::vector<float> s_EtaCenter = { -4.5, -3.8, -3.38, -3.18, -3.15, -3,
1416  -2.8, -2.6, -2.35, -2.1, -1.9, -1.7, -1.5, -1.3, -1.1, -0.9,
1417  -0.7, -0.5, -0.3, -0.1, 0.1, 0.3, 0.5, 0.7, 0.9, 1.1,
1418  1.3, 1.5, 1.7, 1.9, 2.1, 2.35, 2.6, 2.8, 3.0,
1419  3.15, 3.18, 3.38, 3.8, 4.5};
1420 
1421  // Transform Eta and Phi indices for the most forward towers into the "original" indices,
1422  // as before rearranging the towers such that the forward region is 12(ieta)x32(iphi).
1423  // The FPGA-C has now the same format (12*32) as FPGA-A and FPGA-B.
1424  // This is the result of a transformation in the firmware.
1425  // Note that for the most forward towers, the Phi index and Eta index have been considered accordingly,
1426  // so in order to get the correct float values of Phi and Eta we need to retrieve the "original" indices.
1427  int towerID_base = 20000;
1428  int iEtaOld=0, iPhiOld=0;
1429 
1430  if (iEta == 2){
1431  if (iPhi == ((gFEXtowerID - towerID_base)/24)*2){
1432  iEtaOld = 0;
1433  iPhiOld = iPhi/2;
1434  }
1435  if (iPhi == (((gFEXtowerID - towerID_base - 12)/24)*2) + 1){
1436  iEtaOld = 1;
1437  iPhiOld = (iPhi-1)/2;
1438  }
1439  }
1440 
1441  else if (iEta == 3){
1442  if (iPhi == ((gFEXtowerID - towerID_base - 1)/24)*2){
1443  iEtaOld = 2;
1444  iPhiOld = iPhi/2;
1445  }
1446  if (iPhi == (((gFEXtowerID - towerID_base - 13)/24)*2) + 1){
1447  iEtaOld = 3;
1448  iPhiOld = (iPhi-1)/2;
1449  }
1450  }
1451 
1452  else if (iEta == 36){
1453  if (iPhi == (((gFEXtowerID - towerID_base - 22)/24)*2) + 1){
1454  iEtaOld = 36;
1455  iPhiOld = (iPhi-1)/2;
1456  }
1457  if (iPhi == ((gFEXtowerID - towerID_base - 10)/24)*2){
1458  iEtaOld = 37;
1459  iPhiOld = iPhi/2;
1460  }
1461  }
1462 
1463  else if (iEta == 37){
1464  if (iPhi == (((gFEXtowerID - towerID_base - 23)/24)*2) + 1){
1465  iEtaOld = 38;
1466  iPhiOld = (iPhi-1)/2;
1467  }
1468  if (iPhi == ((gFEXtowerID - towerID_base - 11)/24)*2){
1469  iEtaOld = 39;
1470  iPhiOld = iPhi/2;
1471  }
1472  }
1473 
1474  else {
1475  iEtaOld = iEta;
1476  iPhiOld = iPhi;
1477  }
1478 
1479  Eta = s_EtaCenter[iEtaOld];
1480 
1481  float Phi_gFex = -99;
1482 
1483  if (( iEtaOld <= 3 ) || ( (iEtaOld >= 36) )){
1484  Phi_gFex = ( (iPhiOld * s_forwardPhiWidth) + s_forwardPhiWidth/2);
1485  }
1486  else {
1487  Phi_gFex = ( (iPhiOld * s_centralPhiWidth) + s_centralPhiWidth/2);
1488  }
1489 
1490  if (Phi_gFex < M_PI) {
1491  Phi = Phi_gFex;
1492  }
1493  else {
1494  Phi = (Phi_gFex - 2*M_PI);
1495  }
1496 }
1497 
1498 void gFexInputByteStreamTool::signExtend(int *xptr, int upto) const{
1499 
1500  // 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)
1501  // xptr pointer to input datum
1502  // word length in hardware
1503  int x = *xptr;
1504  //printf("before %x \n", x);
1505  //printf("masks %x %x \n", (0x00000001<<upto) , (0xFFFFFFFF<<(upto+1)) );
1506  if( x & (0x00000001<<upto) ) {
1507  x = ( x | (0xFFFFFFFF<<(upto+1)) );
1508  } else {
1509  // for now assume 17 bits -- but could be up to 18 bits
1510  x = ( x & 0x000FFFF);
1511  }
1512  *xptr = x;
1513 
1514 }
1515 
1516 void gFexInputByteStreamTool::gtCalib(gtFPGA &gtf, int towerLSB, int fpga, unsigned int offset ) const{
1517  // does calibration of input gTowers according the fpga and the
1518 
1519  int ABCrows = gtf.size();
1520  int ABcolumns = gtf[0].size();
1521  // check on fpga number to fool compiler into not giving a warning.
1522  // eventually will use for possilbe look up table modification
1523  if(fpga <0 || fpga >2 ) printf("*E: gtCalib FPGA number %d out of range\n",fpga);
1524 
1525  // regular towers 200 MeV towers
1526  // for now just do and undo offset and simulate tuncation effect
1527 
1528  for(int irow=0; irow<ABCrows; irow++){
1529  for( int icolumn=0; icolumn<ABcolumns; icolumn++){
1530 
1531  // 200 MEV Towers
1532  if( towerLSB == 200 ) {
1533  if( gtf[irow][icolumn] > 1500 ){
1534  // printf( "*I gtCalib: gtf before calibration %x offset %x \n", gtf[irow][icolumn], offset);
1535  }
1536  gtf[irow][icolumn] = gtf[irow][icolumn] + offset;
1537 
1538  if( gtf[irow][icolumn] > 2047 ) {
1539  gtf[irow][icolumn] = 2047;
1540  } else if( gtf[irow][icolumn] < 0 ){
1541  gtf[irow][icolumn] = 0;
1542  }
1543  gtf[irow][icolumn] = gtf[irow][icolumn] - offset;
1544 
1545  if( gtf[irow][icolumn] > 1500 ){
1546  // printf( "*I gtCalib: gtf after calibration %x \n", gtf[irow][icolumn] );
1547  }
1548 
1549  //printf( "gtf out %x \n ", gtf[irow][icolumn] );
1550  //#endif
1551 
1552 
1553  // 50 MEV Towers
1554  } else {
1555 
1556  gtf[irow][icolumn] = gtf[irow][icolumn] + offset;
1557 
1558  if( gtf[irow][icolumn] > 1023 ){
1559  gtf[irow][icolumn] = 1023;
1560  } else if ( gtf[irow][icolumn] < 0 ){
1561  gtf[irow][icolumn] = 0;
1562  }
1563  gtf[irow][icolumn] = gtf[irow][icolumn] - offset;
1564 
1565  }
1566  }
1567  }
1568 }
1569 
1570 
1571 
1573 StatusCode gFexInputByteStreamTool::convertToBS(std::vector<WROBF*>& /*vrobf*/, const EventContext& /*eventContext*/) {
1574 
1575  return StatusCode::SUCCESS;
1576 }
1577 
1578 void gFexInputByteStreamTool::printError(const std::string& location, const std::string& title, MSG::Level type, const std::string& detail) const{
1579 
1580  if(m_UseMonitoring){
1582  Monitored::Scalar("gfexDecoderErrorLocation",location.empty() ? std::string("UNKNOWN") : location),
1583  Monitored::Scalar("gfexDecoderErrorTitle" ,title.empty() ? std::string("UNKNOWN") : title)
1584  );
1585  }
1586  else {
1587  msg() << type << detail << endmsg;
1588  }
1589 }
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:1516
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:1498
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:1281
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:1220
gFexInputByteStreamTool::printError
void printError(const std::string &location, const std::string &title, MSG::Level type, const std::string &detail) const
Definition: gFexInputByteStreamTool.cxx:1578
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:1156
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:85
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
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:228
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:1410
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:47
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:1573
xAOD::iEta
setScale setgFexType iEta
Definition: gFexJetRoI_v1.cxx:77
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