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