11 #include "eformat/ROBFragment.h"
23 #ifndef OFFLINE_DECODER
24 #include "bytestreamDecoder/L1CaloRdoGfexTob.h"
25 #include "bytestreamDecoder/L1CaloRdoGfexTower.h"
26 #include "bytestreamDecoder/L1CaloRdoJfexTob.h"
27 #include "bytestreamDecoder/L1CaloRdoJfexTower.h"
28 #include "bytestreamDecoder/L1CaloRdoMuonTob.h"
29 #include "bytestreamDecoder/L1CaloRdoPh1TopoHit.h"
30 #include "channelMappings/GfexCellMapping.h"
31 #include "channelMappings/JfexCellMapping.h"
33 #include "infraL1Calo/GfexLatomeCentralFibrePacker.h"
34 #include "infraL1Calo/GfexLatomeForwardFibrePacker.h"
35 #include "infraL1Calo/GfexTrexFibrePacker.h"
36 #include "infraL1Calo/JfexLatomeFibrePacker.h"
37 #include "infraL1Calo/JfexTrexFibrePacker.h"
40 #define LOG_ERROR(location,title,detail) { if(m_logger) { std::stringstream s; s << location; std::stringstream s2; s2<<title; std::stringstream s3; s3<<detail; m_logger->err(s.str(),s2.str(),s3.str().empty() ? s2.str() : s3.str()); } }
55 LOG_ERROR(
"ctor",
"unexpected invalid eFEX mapping!?",
"");
57 #ifndef OFFLINE_DECODER
58 JfexCellMapping dummyJfexMapping(0,1,0,0);
59 if (!dummyJfexMapping.getDetectorRegion().getValidity()) {
60 LOG_ERROR(
"ctor",
"unexpected invalid jFEX mapping!?",
"");
62 GfexCellMapping dummyGfexMapping(0,0,0,0);
63 if (!dummyGfexMapping.getDetectorRegion().getValidity()) {
64 LOG_ERROR(
"ctor",
"unexpected invalid gFEX mapping!?",
"");
86 std::list<L1CaloRdoEfexTower>& tower,
87 std::list<L1CaloRdoRodInfo>::const_iterator rodInfo )
const
90 const size_t fragmentSize =
end -
beg;
97 size_t numTowers = tower.size();
98 size_t index = fragmentSize;
101 while (
index > 0 ) {
103 LOG_ERROR(
"decodeEfexData",
"block size error",
104 "remaining block size " <<
index
105 <<
" is too small for the eFEX FPGA trailer");
113 const uint32_t ctrlErrors = ctrlTrailer2 & 0x3f;
114 const uint32_t efexNumber = (ctrlTrailer1 >> 12) & 0xf;
115 const uint32_t shelfNumber = (ctrlTrailer1 >> 16) & 0
x1;
116 const size_t payloadSize = (ctrlTrailer1 & 0xfff) - 2;
118 if ( payloadSize >
index ) {
119 LOG_ERROR(
"decodeEfexData",
"block size error",
"remaining eFEX block size "
120 <<
index <<
" is too small for the claimed payload size "
126 LOG_ERROR(
"decodeEfexData",
"invalid eFEX number " << efexNumber,
134 index -= payloadSize;
135 size_t chanIndex = 0;
137 std::bitset<49> chansWithError;
138 bool anyErrorBit =
false;
139 while ( chanIndex < payloadSize ) {
140 if ( (payloadSize - chanIndex) < 8 ) {
141 LOG_ERROR(
"decodeEfexData s" << shelfNumber <<
" e" << efexNumber,
"block size error",
142 (payloadSize - chanIndex)<<
" is too small for one eFEX input fibre block (8)");
147 ctrlErrors, tower, rodInfo );
149 chanErrorOR |= ( chanErrors & 0x7 );
150 chansWithError[chanNumber] = 1;
158 const uint64_t fpgaErrorBits = ( (
uint64_t)(fpgaTrailer2 & 0x1ffff) << 32 ) | fpgaTrailer1;
159 const uint64_t chanErrorBits = chansWithError.to_ullong();
160 const uint32_t fpgaErrorOR = ( fpgaTrailer2 >> 28 ) & 0xf;
161 if ( fpgaErrorBits != chanErrorBits || fpgaErrorOR != chanErrorOR ) {
162 LOG_ERROR(
"decodeEfexData: s" << shelfNumber <<
" e" << efexNumber,
"errorbit mismatch",
163 "mismatch between errors in FPGA trailer: "
164 << std::hex << fpgaErrorBits <<
" " << fpgaErrorOR
165 <<
" and those derived from channels: " << chanErrorBits <<
" " << chanErrorOR
171 std::cout <<
"L1CaloBsDecoderRun3::decodeEfexData: n.towers added="
172 << tower.size() - numTowers << std::endl;
190 std::list<L1CaloRdoEfexTower>& tower,
191 std::list<L1CaloRdoRodInfo>::const_iterator rodInfo )
const
201 LOG_ERROR(
"decodeEfexDataChan s" << shelfNumber <<
"e" << efexNumber <<
"f" << fpgaNumber,
"invalid channel",
219 int moduleEta = -24 + (efexNumber % 3) * 16;
220 int modulePhi = 2 + (shelfNumber * 32) + (efexNumber / 3) * 8;
223 std::vector<FibrePackerBase::myDataWord> encodedData;
224 for (
size_t i = 0;
i < 7;
i++ ) {
225 encodedData.push_back(
payload[
i] );
234 const uint32_t errorField = ( errorMask & 0x3f )
235 | ( rightCRC ? 0 : 0x80 )
236 | ( errorBits << 8 );
238 if (chanNumber < 40) {
242 std::vector<FibrePackerBase::myDataWord>
cells = packer.
getUnpackedData( encodedData, frameType );
249 const std::vector<uint32_t> cellIndex = { 0, 1, 2, 3, 8, 9,10,11,12,13,
250 4, 5, 6, 7,14,15,16,17,18,19 };
251 for (
size_t k = 0;
k < 2;
k++ ) {
252 std::vector<uint32_t> towerCells( 10, 0 );
255 for (
size_t i = 0;
i < 10;
i++) {
260 towerCells[
i] =
cells[iCell];
261 towerSumEt += towerCells[
i];
269 if ( towerSumEt || towerFlag ) {
274 int localEta = region.
getEtaIndex() - moduleEta + 1;
290 std::cout <<
"L1CaloBsDecoderRun3::decodeEfexDataChan: EM"
291 <<
", shelf=" << shelfNumber <<
", module=" << efexNumber
292 << std::hex <<
", Et=0x" << towerSumEt <<
", flag=0x" << towerFlag
293 << std::dec << std::endl;
303 std::vector<FibrePackerBase::myDataWord> towerVals = packer.
getUnpackedData( encodedData, frameType );
304 size_t numHadTowers =
std::min(towerVals.size(),(
size_t)16);
307 for (
size_t wordNumber = 0; wordNumber < numHadTowers; wordNumber++ ) {
308 const uint32_t towerEt = ( towerVals[wordNumber] == 0x3fe ) ? 0 : towerVals[wordNumber];
309 const uint32_t invalid = ( towerVals[wordNumber] == 0x3fe ) ? 1 : 0;
310 const uint32_t towerFlag = errorMask | ( invalid << 31 );
312 if ( towerEt || towerFlag ) {
322 towerVals[wordNumber] &= 0xff;
325 int localEta = region.
getEtaIndex() - moduleEta + 1;
340 std::cout <<
"L1CaloBsDecoderRun3::decodeEfexDataChan: Had"
341 <<
", shelf=" << shelfNumber <<
", module=" << efexNumber
342 << std::hex <<
", Et=0x" << towerEt <<
", flag=0x" << towerFlag
343 << std::dec << std::endl;
364 std::list<L1CaloRdoEfexTob>& tob,
365 std::list<L1CaloRdoRodInfo>::const_iterator rodInfo )
const
368 const size_t fragmentSize =
end -
beg;
374 if ( fragmentSize < 2 ) {
375 LOG_ERROR(
"decodeEfexTobs",
"ROD trailer fragment size", fragmentSize
376 <<
" is too small for the ROD trailer");
380 size_t index = fragmentSize;
384 const uint32_t rodErrors = rodTrailer2 & 0x7f;
385 const size_t payloadSize = rodTrailer1 & 0xffff;
386 if ( (rodErrors >> 6) & 0
x1 ) {
387 LOG_ERROR(
"decodeEfexTobs",
"Unknown corrective trailer " << std::hex << rodErrors << std::dec,
"");
390 if ( (payloadSize + 2) != fragmentSize ) {
392 LOG_ERROR(
"decodeEfexTobs",
"inconsistent ROD fragment size",
"payload size " << payloadSize
393 <<
" vs ROD fragment size " << fragmentSize);
398 while (
index > 0 ) {
401 <<
" is too small for the eFEX trailer");
404 size_t efexIndex =
index;
410 const uint32_t corrective = (efexTrailer2 >> 5) & 0
x1;
413 size_t corrBlockSize = (efexTrailer1) & 0xffff;
414 const uint32_t efexNumber = (efexTrailer1 >> 16) & 0xf;
415 const uint32_t shelfNumber = (efexTrailer1 >> 20) & 0
x1;
416 const uint32_t ctrlErr = efexTrailer2 & 0x3f;
418 LOG_ERROR(
"decodeEfexTobs s" << shelfNumber <<
"e" << efexNumber,
419 "rod corrective trailer " << std::hex << ctrlErr << std::dec,
"");
421 if (corrBlockSize >
index) {
422 LOG_ERROR(
"decodeEfexTobs s" << shelfNumber <<
"e" << efexNumber,
"excessive rod corrective blocksize",
423 "rod corrective blocksize " << corrBlockSize <<
424 " > remaining blocksize ");
428 index -= corrBlockSize;
433 const size_t efexBlockSize = efexTrailer1 & 0xfff;
434 const uint32_t efexNumber = (efexTrailer1 >> 12) & 0xf;
435 const uint32_t shelfNumber = (efexTrailer1 >> 16) & 0
x1;
437 const uint32_t numSlices = (efexTrailer1 >> 24) & 0xf;
439 const uint32_t efexErrors = efexTrailer2 & 0x3f;
440 if ( efexBlockSize >
index ) {
441 LOG_ERROR(
"decodeEfexTobs s" << shelfNumber <<
"e" << efexNumber,
"excessive block size", efexBlockSize
442 <<
" exceeds remaining data size " <<
index);
446 index = efexIndex - efexBlockSize;
449 const uint32_t errorMask = efexErrors | (rodErrors << 6);
454 while ( efexIndex >
index ) {
455 if ( (efexIndex -
index) < 2 ) {
456 LOG_ERROR(
"decodeEfexTobs s"<< shelfNumber <<
"e" << efexNumber,
458 (efexIndex -
index) <<
" is too small for the eFEX slice trailer");
461 size_t procIndex = efexIndex;
463 numSlices, errorMask, tob, rodInfo );
467 efexIndex = procIndex;
490 std::list<L1CaloRdoEfexTob>& tob,
491 std::list<L1CaloRdoRodInfo>::const_iterator rodInfo )
const
498 const uint32_t corrective = (sliceTrailer >> 31) & 0x01;
504 size_t corrBlockSize = sliceTrailer & 0xfff;
506 const uint32_t fpgaNumber = (sliceTrailer >> 24) & 0x3;
507 const uint32_t plErr = (sliceTrailer >> 30) & 0x01;
508 const uint32_t bcnErr = (sliceTrailer >> 29) & 0x01;
509 LOG_ERROR(
"decodeEfexTobSlice s" << shelfNumber <<
"e" << efexNumber <<
"f" << fpgaNumber,
510 "ctrl corrective trailer " << std::hex << (plErr*2+bcnErr) << std::dec,
"error bits: PacketLength=" << plErr <<
", BCNMismatch=" << bcnErr);
514 corrBlockSize += ((corrBlockSize % 2) == 1) ? 1 : 2;
516 if (corrBlockSize >
index) {
517 LOG_ERROR(
"decodeEfexTobSlice s" << shelfNumber <<
"e" << efexNumber <<
"f" << fpgaNumber,
"excessive ctrl corrective blocksize",
518 "corrective blocksize " << corrBlockSize <<
519 " > remaining blocksize ");
523 index -= corrBlockSize;
527 const uint32_t tobType = (sliceTrailer >> 8) & 0
x1;
528 const uint32_t numTobs = (sliceTrailer >> 9) & 0x7;
529 const uint32_t numEmXtobs = (sliceTrailer >> 12) & 0x3f;
530 const uint32_t numTauXtobs = (sliceTrailer >> 18) & 0x3f;
531 const uint32_t sliceNumber = (sliceTrailer >> 24) & 0x7;
532 const uint32_t safeMode = (sliceTrailer >> 27) & 0
x1;
533 const uint32_t fpgaNumber = (sliceTrailer >> 28) & 0x3;
540 size_t tobSize = (safeMode == 0)
541 ? (1 + numTobs + 2 * (numEmXtobs + numTauXtobs))
543 tobSize += (tobSize % 2);
546 if (tobSize >
index) {
547 LOG_ERROR(
"decodeEfexTobSlice s" << shelfNumber <<
"e" << efexNumber <<
"f" << fpgaNumber,
548 "excessive blocksize",
549 "TOB blocksize " << tobSize <<
" > remaining blocksize " <<
index);
555 LOG_ERROR(
"decodeEfexTobSlice s" << shelfNumber <<
"e" << efexNumber <<
"f" << fpgaNumber,
557 "missed " << numTobs <<
" TOBs, " << numEmXtobs <<
" EM XTOBs, "
558 << numTauXtobs <<
" Tau XTOBs" );
563 const size_t totalTobs = numTobs + numEmXtobs + numTauXtobs;
568 size_t sliceIndex =
index;
569 for (
size_t iTOB = 0; iTOB < totalTobs; iTOB++) {
570 if (iTOB >= numTobs) {
571 fexTobSource = L1CaloRdoFexTob::TobSource::EfexXtob;
572 fexTobType = (iTOB < (numTobs + numEmXtobs))
576 this->
decodeOneEfexTob ( &payload[sliceIndex], shelfNumber, efexNumber, fpgaNumber,
577 errorMask, numSlices, sliceNumber, fexTobType, fexTobSource,
580 sliceIndex += (fexTobSource == L1CaloRdoFexTob::TobSource::EfexTob) ? 1 : 2;
600 std::list<L1CaloRdoEfexTob>& tob,
601 std::list<L1CaloRdoRodInfo>::const_iterator rodInfo )
const
604 const uint32_t isolInfo = (tobWord ) & 0xffc000;
605 const uint32_t tobPhi = (tobWord >> 24) & 0x7;
606 const uint32_t tobEta = (tobWord >> 27) & 0x7;
607 const uint32_t tobFpga = (tobWord >> 30) & 0x3;
610 if (tobSource == L1CaloRdoFexTob::TobSource::EfexXtob) {
612 etValue = word[1] & 0xffff;
616 etValue = tobWord & 0xfff;
619 if ( sliceNum >= numSlices ) {
620 LOG_ERROR(
"decodeOneEfexTob s" << shelfNumber <<
"e" << efexNumber <<
"f" << fpgaNumber,
621 "excessive sliceNum",
622 "TOB slice " << sliceNum <<
" exceeds number of slices " << numSlices <<
" in processor trailer");
624 else if ( etValue ) {
636 const uint32_t moduleEta = 1 + (tobEta - 1) + 4 * tobFpga;
637 const uint32_t flagMask = isolInfo | errorMask;
639 numSlices, tobType, tobSource );
643 rdo.
setFlag( flagMask, sliceNum );
644 #ifdef OFFLINE_DECODER
646 rdo.setWord0( word[0], sliceNum );
647 if(tobSource == L1CaloRdoFexTob::TobSource::EfexXtob) rdo.setWord1(word[1], sliceNum);
651 std::cout <<
"L1CaloBsDecoderRun3::decodeOneEfexTob: tobType=" << tobType
652 <<
", tobSource=" << tobSource <<
", slice=" << sliceNum
653 <<
", shelf=" << shelfNumber <<
", module=" << efexNumber
654 <<
", eta=" << moduleEta <<
", phi=" << tobPhi
655 << std::hex <<
", Et=0x" << etValue <<
", flag=0x" << flagMask
656 << std::dec <<
", numSlices=" << numSlices << std::endl;
672 if (
data.size() != numWords ) {
676 const size_t numPayloadBits = ( 32 * numWords ) - 9;
677 unsigned int actualCRC = (
data[numWords-1] >> 23 ) & 0x1ff;
678 data[0] &= 0xffffff00;
679 unsigned int expectCRC = crc.
crc9fibre(
data, numPayloadBits );
681 return (actualCRC == expectCRC);
684 #ifndef OFFLINE_DECODER
696 std::list<L1CaloRdoJfexTower>& tower,
697 std::list<L1CaloRdoRodInfo>::const_iterator rodInfo )
700 const size_t fragmentSize =
end -
beg;
707 size_t numTowers = tower.size();
708 size_t index = fragmentSize;
711 while (
index > 0 ) {
714 <<
" is too small for the jFEX FPGA trailer");
720 const uint32_t fpgaErrors = fpgaTrailer2 & 0x3f;
721 const uint32_t jfexNumber = (fpgaTrailer1 >> 20) & 0x7;
722 const uint32_t fpgaNumber = (fpgaTrailer1 >> 18) & 0x3;
723 const size_t payloadSize = (fpgaTrailer1 & 0xffff);
725 if ( payloadSize >
index ) {
726 LOG_ERROR(
"decodeJfexData",
"",
"remaining jFEX block size "
727 <<
index <<
" is too small for the claimed payload size "
734 index -= payloadSize;
735 size_t chanIndex = 0;
736 while ( chanIndex < payloadSize ) {
737 if ( (payloadSize - chanIndex) < 8 ) {
738 LOG_ERROR(
"decodeJfexData",
"",
"decodeJfexData: remaining jFEX block size "
739 << (payloadSize - chanIndex)
740 <<
" is too small for one jFEX input fibre block (8)");
744 fpgaErrors, tower, rodInfo );
750 std::cout <<
"L1CaloBsDecoderRun3::decodeJfexData: n.towers added="
751 << tower.size() - numTowers << std::endl;
769 std::list<L1CaloRdoJfexTower>& tower,
770 std::list<L1CaloRdoRodInfo>::const_iterator rodInfo )
783 if (chanNumber >= 24 &&
788 if (jfexNumber == 0 ||
796 int moduleEta = -24 + (jfexNumber % 6) * 8;
799 std::vector<FibrePackerBase::myDataWord> encodedData;
800 for (
size_t i = 0;
i < 7;
i++ ) {
801 encodedData.push_back(
payload[
i] );
812 std::vector<FibrePackerBase::myDataWord>
towers;
814 JfexTrexFibrePacker packer;
815 towers = packer.getUnpackedData( encodedData, frameType );
819 JfexLatomeFibrePacker packer;
820 towers = packer.getUnpackedData( encodedData, frameType );
824 for (
size_t iTower = 0; iTower <
towers.size(); iTower++ ) {
827 if ( towerEt || errorMask ) {
842 int unitNumber = fpgaNumber + 1;
843 int procNumber = JfexDefs::processorNumberToUnitNumber(unitNumber) - 1;
844 JfexHardwareInfo hwInfoFpga( JfexCellMapping( unitNumber, chanNumber+60 ).getHardwareInfo() );
845 int mgtFibreNumber = hwInfoFpga.getFibreNumber();
846 JfexCellMapping
mapping( jfexNumber, unitNumber, mgtFibreNumber, iTower );
848 JfexHardwareInfo hwInfo(
mapping.getHardwareInfo() );
849 JfexTriggerTowerInfo ttInfo(
mapping.getTriggerTowerInfo() );
851 if ( region.
getValidity() && hwInfo.getValidity() ) {
856 L1CaloRdoJfexTower newOne( shelfNumber, jfexNumber, localEta, localPhi,
layer, region );
857 newOne.setRodInfo( rodInfo );
860 rdo.setHardwareInfo( procNumber, chanNumber, iTower,
861 hwInfo.getAvr(), hwInfo.getFibreNumber(),
863 rdo.setValue( towerEt );
864 rdo.setFlag( errorMask );
868 std::cout <<
"L1CaloBsDecoderRun3::decodeJfexDataChan: "
869 <<
"module=" << jfexNumber
870 << std::hex <<
", Et=0x" << towerEt <<
", flag=0x" << errorMask
871 << std::dec << std::endl;
906 std::list<L1CaloRdoJfexTob>& tob,
907 std::list<L1CaloRdoRodInfo>::const_iterator rodInfo )
910 const size_t fragmentSize =
end -
beg;
916 if ( fragmentSize < 2 ) {
917 LOG_ERROR(
"decodeJfexTobs",
"",
": fragment size " << fragmentSize
918 <<
" is too small for the ROD trailer");
922 size_t index = fragmentSize;
926 const uint32_t rodErrors = rodTrailer2 & 0x7f;
927 const size_t payloadSize = rodTrailer1 & 0xffff;
928 if ( (payloadSize + 2) != fragmentSize ) {
930 LOG_ERROR(
"decodeJfexTobs",
"",
"payload size " << payloadSize
931 <<
" inconsistent with ROD fragment size " << fragmentSize);
937 while (
index > 0 ) {
940 <<
" is too small for the jFEX trailer");
943 size_t fpgaIndex =
index;
946 const size_t fpgaBlockSize = fpgaTrailer1 & 0xffff;
947 const uint32_t jfexNumber = (fpgaTrailer1 >> 20) & 0x7;
948 const uint32_t fpgaNumber = (fpgaTrailer1 >> 18) & 0x3;
949 const uint32_t numSlices = (fpgaTrailer1 >> 24) & 0xf;
950 const uint32_t sliceNumber = (fpgaTrailer1 >> 28) & 0xf;
951 const uint32_t fpgaErrors = fpgaTrailer2 & 0x3f;
952 if ( fpgaBlockSize >
index ) {
953 LOG_ERROR(
"decodeJfexTobs",
"",
"jFEX FPGA block size " <<
954 fpgaBlockSize <<
" exceeds remaining data size " <<
index
955 <<
" (jFEX " << jfexNumber <<
" FPGA " << fpgaNumber <<
")");
959 index = fpgaIndex - fpgaBlockSize;
962 const uint32_t errorMask = fpgaErrors | (rodErrors << 6);
964 bool ret = this->
decodeJfexTobSlice ( payload, fpgaBlockSize, fpgaIndex, jfexNumber, fpgaNumber,
965 sliceNumber, numSlices, errorMask, tob, rodInfo );
992 std::list<L1CaloRdoJfexTob>& tob,
993 std::list<L1CaloRdoRodInfo>::const_iterator rodInfo )
1000 if ( jfexNumber == 0 || jfexNumber == 5 ) {
1013 const uint32_t safeMode = (countTrailer1 ) & 0
x1;
1014 const uint32_t numSJetTobs = (countTrailer1 >> 1) & 0x3f;
1015 const uint32_t numLJetTobs = (countTrailer1 >> 7) & 0x3f;
1016 const uint32_t numTauTobs = (countTrailer1 >> 13) & 0x3f;
1017 const uint32_t numElecTobs = (countTrailer1 >> 19) & 0x3f;
1018 const uint32_t numSumEtTobs = (countTrailer1 >> 25) & 0
x1;
1019 const uint32_t numMissEtTobs = (countTrailer1 >> 26) & 0
x1;
1020 const uint32_t numSJetXtobs = (countTrailer2 >> 1) & 0x3f;
1021 const uint32_t numLJetXtobs = (countTrailer2 >> 7) & 0x3f;
1022 const uint32_t numTauXtobs = (countTrailer2 >> 13) & 0x3f;
1023 const uint32_t numElecXtobs = (countTrailer2 >> 19) & 0x3f;
1035 std::vector<size_t>
end;
1036 end.push_back( 0 ) ;
1038 end.push_back(
end.back() + numSJetTobs );
1039 end.push_back(
end.back() + numLJetTobs );
1040 end.push_back(
end.back() + numTauTobs );
1041 end.push_back(
end.back() + numElecTobs );
1042 end.push_back(
end.back() + numSumEtTobs );
1043 end.push_back(
end.back() + numMissEtTobs );
1044 end.push_back(
end.back() + numSJetXtobs );
1045 end.push_back(
end.back() + numLJetXtobs );
1046 end.push_back(
end.back() + numTauXtobs );
1047 end.push_back(
end.back() + numElecXtobs );
1050 size_t tobSize =
end.back();
1051 tobSize += (tobSize % 2);
1054 if ( tobSize != blockSize ) {
1055 LOG_ERROR(
"decodeJfexTobSlice",
"",
": TOB slice " << sliceNumber
1056 <<
" has block size " << blockSize <<
" expected TOBs+counts " << tobSize
1057 <<
" (jFEX " << jfexNumber <<
" FPGA " << fpgaNumber <<
")");
1059 if ( tobSize >
index ) {
1060 LOG_ERROR(
"decodeJfexTobSlice",
"",
": TOB size " << tobSize
1061 <<
" is larger than index " <<
index);
1065 size_t numTobs = (safeMode) ? 0 :
end[6];
1066 size_t totalTobs = (safeMode) ? 0 :
end.back();
1072 size_t sliceIndex =
index;
1075 for (
size_t iTOB = 0; iTOB < totalTobs; iTOB++) {
1083 uint32_t flagInfo = (tobWord >> 21) & 0xfff;
1084 uint32_t etValue = (tobWord >> 10) & 0x7ff;
1085 uint32_t tobPhi = (tobWord >> 1) & 0xf;
1086 uint32_t tobEta = (tobWord >> 5) & 0x1f;
1087 fexTobSource = (iTOB < numTobs)
1088 ? L1CaloRdoFexTob::TobSource::JfexTob
1089 : L1CaloRdoFexTob::TobSource::JfexXtob;
1090 if (iTOB <
end[1]) {
1091 fexTobType = L1CaloRdoFexTob::TobType::SmallJet;
1092 }
else if (iTOB <
end[2]) {
1093 fexTobType = L1CaloRdoFexTob::TobType::LargeJet;
1094 }
else if (iTOB <
end[3]) {
1096 }
else if (iTOB <
end[4]) {
1098 }
else if (iTOB <
end[6]) {
1100 }
else if (iTOB <
end[7]) {
1101 fexTobType = L1CaloRdoFexTob::TobType::SmallJet;
1102 }
else if (iTOB <
end[8]) {
1103 fexTobType = L1CaloRdoFexTob::TobType::LargeJet;
1104 }
else if (iTOB <
end[9]) {
1106 }
else if (iTOB <
end[10]) {
1113 if (fexTobType == L1CaloRdoFexTob::TobType::SmallJet) {
1115 }
else if (fexTobType == L1CaloRdoFexTob::TobType::LargeJet) {
1117 etValue = (tobWord >> 10) & 0x1fff;
1120 flagInfo = (tobWord & 0x1) | (tobWord & 0x1000) >> 15;
1121 etValue = (tobWord & 0x7ffffffe) >> 1;
1128 uint32_t sliceNumberHacked = sliceNumber;
1129 if (numSlices == 1 && sliceNumber == 2) {
1130 sliceNumberHacked = 0;
1133 if ( sliceNumberHacked >= numSlices ) {
1134 LOG_ERROR(
"decodeJfexTobSlice",
"",
": TOB slice " << sliceNumber
1135 <<
" exceeds number of slices " << numSlices <<
" in processor trailer");
1137 else if ( etValue || flagInfo ) {
1147 const uint32_t procNumber = JfexDefs::processorNumberToUnitNumber(fpgaNumber+1) - 1;
1148 const uint32_t modulePhi = tobPhi + 16 * procNumber;
1149 const uint32_t flagMask = (flagInfo << 16) | errorMask;
1151 L1CaloRdoJfexTob newOne( shelfNumber, jfexNumber, tobEta, modulePhi,
1152 numSlices, fexTobType, fexTobSource );
1153 newOne.setRodInfo( rodInfo );
1157 rdo.setValue( etValue, sliceNumberHacked );
1158 rdo.setFlag( flagMask, sliceNumberHacked );
1161 std::cout <<
"L1CaloBsDecoderRun3::decodeJfexTobSlice: tobType=" << fexTobType
1162 <<
", tobSource=" << fexTobSource <<
", slice=" << sliceNumberHacked
1163 <<
", module=" << jfexNumber <<
", fpga=" << fpgaNumber
1164 <<
", proc=" << procNumber <<
", eta=" << tobEta <<
", phi=" << modulePhi
1165 << std::hex <<
", Et=0x" << etValue <<
", flag=0x" << flagMask
1166 << std::dec <<
", numSlices=" << numSlices << std::endl;
1185 std::list<L1CaloRdoGfexTower>& tower,
1186 std::list<L1CaloRdoRodInfo>::const_iterator rodInfo )
1194 size_t numTowers = tower.size();
1202 const uint32_t fpgaCode = ( word >> 28 ) & 0xf;
1203 if ( fpgaCode < 0xa || fpgaCode > 0xc ) {
1204 LOG_ERROR(
"decodeGfexData",
"",
"invalid FPGA code 0x"
1205 << std::hex << fpgaCode << std::dec);
1208 const uint32_t fpgaNumber = fpgaCode - 0xa;
1209 const uint32_t headerVer = ( word >> 24 ) & 0xf;
1210 const uint32_t headerLen = ( word >> 22 ) & 0x3;
1211 if ( headerVer > 1 || headerLen > 1 ) {
1212 LOG_ERROR(
"decodeGfexData",
"",
": header version " << headerVer
1213 <<
" or length " << headerLen <<
" is not yet supported");
1216 const uint32_t truncatedFlag = (word >> 12) & 0
x1;
1217 if ( truncatedFlag ) {
1218 LOG_ERROR(
"decodeGfexData",
"",
"WARNING data truncated");
1220 const uint32_t numFpgaWords = word & 0xfff;
1221 if ( ( numFpgaWords % 7 ) != 0 ) {
1222 LOG_ERROR(
"decodeGfexData",
"",
"input data size " << numFpgaWords
1223 <<
" is not a multiple of 7");
1226 const uint32_t numInputFibres = numFpgaWords / 7;
1234 for (
size_t chanNumber = 0; chanNumber < numInputFibres; chanNumber++ ) {
1236 if ( chanNumber < 48 || chanNumber >= 52 ) {
1238 fpgaErrors, tower, rodInfo );
1245 std::cout <<
"L1CaloBsDecoderRun3::decodeGfexData: n.towers added="
1246 << tower.size() - numTowers << std::endl;
1264 std::list<L1CaloRdoGfexTower>& tower,
1265 std::list<L1CaloRdoRodInfo>::const_iterator rodInfo )
1271 if ( chanNumber >= 48 && chanNumber < 52 ) {
1276 if ( fpgaNumber >= 2 ) {
1281 std::vector<FibrePackerBase::myDataWord> encodedData;
1282 for (
size_t i = 0;
i < 7;
i++ ) {
1283 encodedData.push_back(
payload[
i] );
1296 GfexTrexFibrePacker trexPacker;
1297 GfexLatomeCentralFibrePacker clarPacker;
1298 GfexLatomeForwardFibrePacker flarPacker;
1299 std::vector<FibrePackerBase::myDataWord> trexTowers = trexPacker.getUnpackedData( encodedData, frameType );
1300 std::vector<FibrePackerBase::myDataWord> clarTowers = clarPacker.getUnpackedData( encodedData, frameType );
1301 std::vector<FibrePackerBase::myDataWord> flarTowers = flarPacker.getUnpackedData( encodedData, frameType );
1302 size_t numTowers = GfexDefs::maxGTowersPerFibre();
1303 size_t numCentral = numTowers / 2;
1306 for (
size_t iTower = 0; iTower < numTowers; iTower++ ) {
1307 GfexCellMapping
mapping( 0, fpgaNumber, chanNumber, iTower );
1309 GfexHardwareInfo hwInfo(
mapping.getHardwareInfo() );
1310 if ( !region.
getValidity() || !hwInfo.getValidity() ) {
1316 int globalEta = GfexDefs::localToGlobalEta(fpgaNumber,region.
getEtaIndex());
1317 if (globalEta < -49 || globalEta >= 49) {
1327 if (
layer == 1 && std::abs(globalEta) < 14 ) {
1329 towerEt = trexTowers[iTower];
1331 else if (
layer == 1 && std::abs(globalEta) >= 16 && std::abs(globalEta) < 24 ) {
1333 towerEt = flarTowers[iTower];
1335 else if (
layer == 0 && std::abs(globalEta) < 14 && iTower < numCentral ) {
1337 towerEt = clarTowers[iTower];
1339 else if (
layer == 0 && std::abs(globalEta) >= 16 && std::abs(globalEta) < 24 && iTower < numCentral ) {
1341 towerEt = clarTowers[iTower];
1347 if ( towerEt || errorMask ) {
1349 L1CaloRdoGfexTower newOne( shelfNumber, gfexNumber, globalEta,
globalPhi,
layer, region );
1350 newOne.setRodInfo( rodInfo );
1353 rdo.setHardwareInfo( hwInfo.getFpgaNumber(), chanNumber, iTower,
1354 GfexDefs::minipodNumFromName(hwInfo.getMpodName()),
1355 hwInfo.getMpodChannel() );
1356 rdo.setValue( towerEt );
1357 rdo.setFlag( errorMask );
1361 std::cout <<
"L1CaloBsDecoderRun3::decodeGfexDataChan: "
1362 <<
"FPGA=" << fpgaNumber
1363 << std::hex <<
", Et=0x" << towerEt <<
", flag=0x" << errorMask
1364 << std::dec << std::endl;
1394 std::list<L1CaloRdoGfexTob>& tob,
1395 std::list<L1CaloRdoRodInfo>::const_iterator rodInfo )
1399 const size_t fragmentSize =
end -
beg;
1410 while (
index < fragmentSize ) {
1414 const uint32_t headerSize = (headerWord >> 22) & 0x3;
1415 const uint32_t errorFlags = (headerWord >> 12) & 0
x1;
1419 if ( (
index + blockSize) > fragmentSize ) {
1420 LOG_ERROR(
"decodeGfexTobs",
"",
"remaining block size "
1421 << (fragmentSize -
index)
1422 <<
" is too small for subblock of type " <<
blockType
1423 <<
" with headerSize " << headerSize
1427 index += headerSize;
1431 if ( numSlices * wordsPerSlice !=
dataSize ) {
1434 <<
" is not a multiple of " << wordsPerSlice <<
" words");
1439 for (
size_t sliceNumber = 0; sliceNumber < numSlices; sliceNumber++) {
1441 errorFlags, tob, rodInfo );
1445 index += wordsPerSlice;
1466 std::list<L1CaloRdoGfexTob>& tob,
1467 std::list<L1CaloRdoRodInfo>::const_iterator rodInfo )
1473 if ( !isJet && !isMet ) {
1474 LOG_ERROR(
"decodeGfexTobSlice",
"",
": invalid block type "
1482 for (
size_t iFibre = 0; iFibre < 2; iFibre++ ) {
1495 if ( tobID >= 1 && tobID <= 4 ) {
1496 fexTobType = L1CaloRdoFexTob::TobType::SmallJet;
1498 else if ( tobID >= 5 && tobID <= 6 ) {
1499 fexTobType = L1CaloRdoFexTob::TobType::LargeJet;
1502 if ( ( etValue ||
saturated || errorMask ) && tobID ) {
1510 L1CaloRdoGfexTob newOne( shelfNumber, moduleNumber, tobEta, tobPhi,
1511 numSlices, fexTobType, fexTobSource );
1512 newOne.setRodInfo( rodInfo );
1514 rdo.setValue( etValue, sliceNumber );
1515 rdo.setFlag( flagMask, sliceNumber );
1518 std::cout <<
"L1CaloBsDecoderRun3::decodeGfexTobSlice: tobType=" << fexTobType
1519 <<
", tobSource=" << fexTobSource <<
", slice=" << sliceNumber
1520 <<
", fpga=" << fpgaNumber <<
", eta=" << tobEta <<
", phi=" << tobPhi
1521 << std::hex <<
", Et=0x" << etValue <<
", flag=0x" << flagMask
1522 << std::dec <<
", numSlices=" << numSlices << std::endl;
1550 std::list<L1CaloRdoEfexTob>& etob,
1551 std::list<L1CaloRdoJfexTob>& jtob,
1552 std::list<L1CaloRdoGfexTob>& gtob,
1553 std::list<L1CaloRdoMuonTob>& mtob,
1554 std::list<L1CaloRdoRodInfo>::const_iterator rodInfo )
1557 const size_t fragmentSize =
end -
beg;
1563 enum TopoInputFibreTypes {
Unknown=0x00, IPB=0x01, TTC=0x02,
EM1=0x03,
EM2=0x04,
1564 G1=0x05, G2=0x06, J1=0x07, J2=0x08, JF=0x09, JFXE=0x0a,
1565 M0A=0x0b, M0C=0x0c, M1A=0x0d, M1C=0x0e, M2A=0x0f, M2C=0x10,
1566 TAU1=0x11, TAU2=0x12, gJ1=0x13, gJ2=0x14 };
1574 size_t index = fragmentSize;
1577 while (
index > 0 ) {
1579 LOG_ERROR(
"decodePh1TopoData",
"",
"remaining block size " <<
index
1580 <<
" is too small for the Ph1Topo FPGA trailer");
1586 const uint32_t fpgaErrors = fpgaTrailer2 & 0x3f;
1594 const size_t payloadSize = (fpgaTrailer1 & 0xffff);
1596 if ( payloadSize >
index ) {
1597 LOG_ERROR(
"decodePh1TopoData",
"",
"remaining Ph1Topo block size "
1598 <<
index <<
" is too small for the claimed payload size "
1610 index -= payloadSize;
1611 size_t chanIndex = 0;
1615 while ( chanIndex < payloadSize ) {
1616 if ( (payloadSize - chanIndex) < 8 ) {
1617 LOG_ERROR(
"decodePh1TopoData",
"",
"remaining Ph1Topo block size "
1618 << (payloadSize - chanIndex)
1619 <<
" is too small for one Ph1Topo input fibre block (8)");
1631 if (fibreType == TopoInputFibreTypes::J1 || fibreType == TopoInputFibreTypes::JF ||
1632 fibreType == TopoInputFibreTypes::J2 || fibreType == TopoInputFibreTypes::JFXE) {
1636 for (
size_t iTob = 0; iTob < numTobs; iTob++) {
1645 fpgaErrors, numSlices, sliceNum, tobType, tobSource,
1675 std::list<L1CaloRdoPh1TopoHit>& hit,
1676 std::list<L1CaloRdoRodInfo>::const_iterator rodInfo )
1679 const size_t fragmentSize =
end -
beg;
1685 if ( fragmentSize < 2 ) {
1686 LOG_ERROR(
"decodePh1TopoHits",
"",
"fragment size " << fragmentSize
1687 <<
" is too small for the ROD trailer");
1691 size_t index = fragmentSize;
1695 const uint32_t rodErrors = rodTrailer2 & 0x7f;
1696 const size_t payloadSize = rodTrailer1 & 0xffff;
1697 if ( (payloadSize + 2) != fragmentSize ) {
1699 LOG_ERROR(
"decodePh1TopoHits",
"",
"payload size " << payloadSize
1700 <<
" inconsistent with ROD fragment size " << fragmentSize);
1705 while (
index > 0 ) {
1707 LOG_ERROR(
"decodePh1TopoHits",
"",
"remaining block size " <<
index
1708 <<
" is too small for the Ph1Topo trailer");
1711 size_t fpgaIndex =
index;
1714 const size_t fpgaBlockSize = fpgaTrailer1 & 0xffff;
1715 const uint32_t topoNumber = (fpgaTrailer1 >> 20) & 0x7;
1716 const uint32_t fpgaNumber = (fpgaTrailer1 >> 18) & 0x3;
1717 const uint32_t numSlices = (fpgaTrailer1 >> 24) & 0xf;
1718 const uint32_t sliceNumber = (fpgaTrailer1 >> 28) & 0xf;
1719 const uint32_t fpgaErrors = fpgaTrailer2 & 0x3f;
1720 if ( fpgaBlockSize >
index ) {
1721 LOG_ERROR(
"decodePh1TopoHits",
"",
"Ph1Topo FPGA block size "
1722 << fpgaBlockSize <<
" exceeds remaining data size " <<
index
1723 <<
" (Ph1Topo " << topoNumber <<
" FPGA " << fpgaNumber <<
")");
1727 index = fpgaIndex - fpgaBlockSize;
1730 const uint32_t errorMask = fpgaErrors | (rodErrors << 6);
1736 const size_t expectedBlockSize = 6;
1737 if ( fpgaBlockSize != expectedBlockSize ) {
1738 LOG_ERROR(
"decodePh1TopoHits",
"",
"Ph1Topo FPGA block size "
1739 << fpgaBlockSize <<
" is not the expected " << expectedBlockSize);
1743 const int idFlag = 0;
1745 size_t numWordsUsedPerFPGA = (topoNumber == 1) ? 6 : 2;
1746 size_t numHitWordsPerFPGA = (topoNumber == 1) ? 6 : 1;
1747 size_t numHitWordsPerModule = numHitWordsPerFPGA * 2;
1749 L1CaloRdoPh1TopoHit newOne( shelfNumber, topoNumber, idFlag, hitSource, numHitWordsPerModule, numSlices );
1750 newOne.setRodInfo( rodInfo );
1752 rdo.setFlag( errorMask, sliceNumber );
1754 size_t sliceIndex =
index;
1755 for (
size_t k = 0;
k < numWordsUsedPerFPGA;
k++ ) {
1757 size_t wordNum = ( topoNumber == 1 ) ?
k : 0;
1758 wordNum += fpgaNumber * numHitWordsPerFPGA;
1760 bool isOverflow = ( topoNumber != 1 ) && (
k != 0 );
1762 rdo.setOverflows( resultWord, wordNum, sliceNumber );
1765 rdo.setHits( resultWord, wordNum, sliceNumber );
1770 std::cout <<
"L1CaloBsDecoderRun3::decodePh1TopoHits: slice=" << sliceNumber
1771 <<
", module=" << topoNumber <<
", fpga=" << fpgaNumber
1772 << std::hex <<
", result=0x" << resultWord <<
", errors=0x" << errorMask
1773 << std::dec <<
", numSlices=" << numSlices <<
", numWords=" << numHitWordsPerModule
1774 <<
", isOverflow=" << isOverflow << std::endl;
1783 #endif // ndef OFFLINE_DECODER