418 bool pedestalSubtracted)
421 B2DEBUG(22,
"Unpacking InterimFEVer01 to TOPRawDigits and TOPRawWaveforms, "
422 "dataSize = " << bufferSize);
429 map<unsigned short, int> evtNumCounter;
430 std::vector<unsigned short> channelCounter(128, 0);
432 unsigned word = array.getWord();
433 unsigned short scrodID = word & 0x0FFF;
436 word = array.getWord();
439 while (array.getRemainingWords() > 0) {
441 unsigned header = array.getWord();
443 if ((header & 0xFF) == 0xBE) {
446 unsigned short scrodID_SSFE;
447 unsigned short carrier_SSFE;
448 unsigned short asic_SSFE;
449 unsigned short channel_SSFE;
450 unsigned short evtNum_SSFE;
452 evtNum_SSFE = (header >> 8) & 0xFF;
453 scrodID_SSFE = (header >> 16) & 0x7F;
454 channel_SSFE = (header >> 24) & 0x07;
455 asic_SSFE = (header >> 27) & 0x03;
456 carrier_SSFE = (header >> 29) & 0x03;
458 const auto* feemap =
m_topgp->getFrontEndMapper().getMap(scrodID_SSFE);
460 moduleID = feemap->getModuleID();
461 boardstack = feemap->getBoardstackNumber();
463 B2ERROR(
"TOPUnpacker: no front-end map available."
464 <<
LogVar(
"SCROD ID", scrodID_SSFE));
468 if (scrodID_SSFE != scrodID) {
469 B2ERROR(
"TOPUnpacker: corrupted data - "
470 <<
"different scrodID's in HLSB and super short FE header."
471 <<
LogVar(
"SCROD", scrodID_SSFE)
472 <<
LogVar(
"slot", moduleID)
473 <<
LogVar(
"BS", boardstack));
474 B2DEBUG(21,
"Different scrodID's in HLSB and FE header: " << scrodID <<
" " << scrodID_SSFE <<
" word = 0x" << std::hex << word);
476 return array.getRemainingWords();
479 B2DEBUG(21, scrodID_SSFE <<
"\t" << carrier_SSFE <<
"\t" << asic_SSFE <<
"\t" << channel_SSFE <<
"\t" << evtNum_SSFE);
481 int channelID = carrier_SSFE * 32 + asic_SSFE * 8 + channel_SSFE;
482 channelCounter[channelID] += 1;
483 evtNumCounter[evtNum_SSFE] += 1;
485 info->incrementFEHeadersCount();
486 info->incrementEmptyFEHeadersCount();
491 if (header != 0xaaaa0104 and header != 0xaaaa0103 and header != 0xaaaa0100) {
492 B2ERROR(
"TOPUnpacker: corrupted data - invalid FE header word");
493 B2DEBUG(21,
"Invalid FE header word: " << std::hex << header <<
" 0b" << std::bitset<32>(header));
494 B2DEBUG(21,
"SCROD ID: " << scrodID <<
" " << std::hex << scrodID);
497 return array.getRemainingWords();
501 word = array.getWord();
502 unsigned short scrodID_FE = word >> 25;
503 unsigned short convertedAddr = (word >> 16) & 0x1FF;
504 unsigned short evtNum_numWin_trigPat_FEheader = word & 0xFFFF;
505 unsigned short evtNum_FEheader = evtNum_numWin_trigPat_FEheader & 0xFF;
506 evtNumCounter[evtNum_FEheader] += 1;
508 if (scrodID_FE != scrodID) {
509 B2ERROR(
"TOPUnpacker: different scrodID's in HLSB and FE header."
510 <<
LogVar(
"scrodID (HSLB)", scrodID)
511 <<
LogVar(
"scrodID (FE)", scrodID_FE));
514 return array.getRemainingWords();
517 word = array.getWord();
519 unsigned lastWrAddr = (word & 0x0FF) << 1;
521 unsigned short asicChannelFE = (word >> 8) & 0x07;
522 unsigned short asicFE = (word >> 12) & 0x03;
523 unsigned short carrierFE = (word >> 14) & 0x03;
524 unsigned short channelID = carrierFE * 32 + asicFE * 8 + asicChannelFE;
527 B2DEBUG(21, scrodID_FE <<
"\t" << carrierFE <<
"\t" << asicFE <<
"\t" << asicChannelFE <<
"\t" << evtNum_FEheader);
529 channelCounter[channelID] += 1;
531 std::vector<TOPRawDigit*> digits;
533 if (header != 0xaaaa0104) {
536 word = array.getWord();
537 short samplePeak_p = word & 0xFFFF;
538 short valuePeak_p = (word >> 16) & 0xFFFF;
540 word = array.getWord();
541 short sampleRise_p = word & 0xFFFF;
542 short valueRise0_p = (word >> 16) & 0xFFFF;
544 word = array.getWord();
545 short valueRise1_p = word & 0xFFFF;
546 short sampleFall_p = (word >> 16) & 0xFFFF;
548 word = array.getWord();
549 short valueFall0_p = word & 0xFFFF;
550 short valueFall1_p = (word >> 16) & 0xFFFF;
552 word = array.getWord();
553 short integral_p = word & 0xFFFF;
560 word = array.getWord();
561 short samplePeak_n = word & 0xFFFF;
562 short valuePeak_n = (word >> 16) & 0xFFFF;
579 word = array.getWord();
580 short integral_n = word & 0xFFFF;
581 short qualityFlags_n = (word >> 16) & 0xFFFF;
583 if (abs(valuePeak_p) != 9999) {
585 digit->setCarrierNumber(carrierFE);
586 digit->setASICNumber(asicFE);
587 digit->setASICChannel(asicChannelFE);
588 digit->setASICWindow(convertedAddr);
589 digit->setLastWriteAddr(lastWrAddr);
590 digit->setSampleRise(sampleRise_p);
591 digit->setDeltaSamplePeak(samplePeak_p - sampleRise_p);
592 digit->setDeltaSampleFall(sampleFall_p - sampleRise_p);
593 digit->setValueRise0(valueRise0_p);
594 digit->setValueRise1(valueRise1_p);
595 digit->setValuePeak(valuePeak_p);
596 digit->setValueFall0(valueFall0_p);
597 digit->setValueFall1(valueFall1_p);
598 digit->setIntegral(integral_p);
600 digit->addRelationTo(info);
601 digits.push_back(digit);
603 if (valuePeak_p < 150) {
605 tlpfResult->setBackgroundOffset(samplePeak_n);
606 tlpfResult->setAmplitude(valuePeak_n);
607 tlpfResult->setChisquare(qualityFlags_n);
608 tlpfResult->setRisingEdgeAndConvert(integral_n);
609 digit->addRelationTo(tlpfResult);
635 word = array.getWord();
636 if (word != 0x7473616c) {
646 info->incrementFEHeadersCount();
647 if (digits.empty()) info->incrementEmptyFEHeadersCount();
649 if (header != 0xaaaa0103)
continue;
652 word = array.getWord();
653 unsigned long evtNum_numWaves_refWin_WFheader = word;
654 unsigned short evtNum_WFheader = (evtNum_numWaves_refWin_WFheader >> 24) & 0xFF;
656 if (evtNum_WFheader != evtNum_FEheader) {
657 B2ERROR(
"TOPUnpacker: different carrier event number in WF and FE header."
658 <<
LogVar(
"Event number (FE header)", evtNum_FEheader)
659 <<
LogVar(
"Event number (WF header)", evtNum_WFheader));
664 word = array.getWord();
666 unsigned short carrier = (word >> 14) & 0x03;
667 unsigned short asic = (word >> 12) & 0x03;
669 unsigned short window = word & 0x1FF;
672 if (carrier != carrierFE) {
673 B2ERROR(
"TOPUnpacker: different carrier numbers in FE and WF header");
674 B2DEBUG(21,
"Different carrier numbers in FE and WF header: "
675 << carrierFE <<
" " << carrier);
678 if (asic != asicFE) {
679 B2ERROR(
"TOPUnpacker: different ASIC numbers in FE and WF header");
680 B2DEBUG(21,
"Different ASIC numbers in FE and WF header: "
681 << asicFE <<
" " << asic);
685 B2ERROR(
"TOPUnpacker: different ASIC channel numbers in FE and WF header");
686 B2DEBUG(21,
"Different ASIC channel numbers in FE and WF header: "
690 if (window != convertedAddr) {
691 B2ERROR(
"TOPUnpacker: different window numbers in FE and WF header");
692 B2DEBUG(21,
"Different window numbers in FE and WF header: "
693 << convertedAddr <<
" " << window);
699 std::vector<unsigned short> windows;
700 windows.push_back(window);
702 word = array.getWord();
703 windows.push_back(word & 0x1FF);
705 word = array.getWord();
706 windows.push_back(word & 0x1FF);
708 word = array.getWord();
709 windows.push_back(word & 0x1FF);
711 int numWords = 4 * 32;
712 if (array.getRemainingWords() < numWords) {
713 B2ERROR(
"TOPUnpacker: too few words for waveform data."
714 <<
LogVar(
"needed", numWords)
715 <<
LogVar(
"available", array.getRemainingWords()));
717 return array.getRemainingWords();
721 std::vector<short> adcData;
722 for (
int i = 0; i < numWords; i++) {
723 word = array.getWord();
724 adcData.push_back(word & 0xFFFF);
725 adcData.push_back((word >> 16) & 0xFFFF);
732 const auto* feemap =
m_topgp->getFrontEndMapper().getMap(scrodID);
734 moduleID = feemap->getModuleID();
735 boardstack = feemap->getBoardstackNumber();
737 B2ERROR(
"TOPUnpacker: no front-end map available."
738 <<
LogVar(
"SCROD ID", scrodID));
743 const auto& mapper =
m_topgp->getChannelMapper();
744 unsigned channel = mapper.getChannel(boardstack, carrier, asic,
asicChannel);
745 int pixelID = mapper.getPixelID(channel);
748 auto* waveform =
m_waveforms.appendNew(moduleID, pixelID, channel, scrodID,
750 waveform->setLastWriteAddr(lastWrAddr);
751 waveform->setStorageWindows(windows);
752 waveform->setPedestalSubtractedFlag(pedestalSubtracted);
753 waveform->addRelationTo(info);
754 info->incrementWaveformsCount();
757 for (
const auto* digit : digits) digit->addRelationTo(waveform);
761 if (evtNumCounter.size() != 1) {
762 B2ERROR(
"TOPUnpacker: Possible frame shift detected "
763 <<
"(More than one unique carrier event number in this readout event)."
764 <<
LogVar(
"SCROD", scrodID)
765 <<
LogVar(
"slot", moduleID)
766 <<
LogVar(
"BS", boardstack));
771 string evtNumOutputString;
772 evtNumOutputString +=
"Carrier event numbers and their counts for SCROD ID " + std::to_string(scrodID) +
":\n";
773 for (
auto const& it : evtNumCounter) {
775 evtNumOutputString += std::to_string(it.first) +
":\t" + std::to_string(it.second) +
"\n";
777 evtNumOutputString +=
"Total:\t" + std::to_string(nASICs);
778 B2DEBUG(21, evtNumOutputString);
781 int nChannelsDiff = 0;
783 string channelOutputString;
784 channelOutputString +=
"Detected channels and their counts for SCROD ID (channels with count == 1 are omitted)" + std::to_string(
788 for (
auto const& it : channelCounter) {
795 int channelID = channelIndex;
796 int carrier = channelID / 32;
797 int asic = (channelID % 32) / 8;
798 int chn = channelID % 8;
799 channelOutputString +=
"carrier: " + std::to_string(carrier) +
" asic: " + std::to_string(asic) +
" chn: " + std::to_string(
800 chn) +
" occurrence: " + std::to_string(it) +
"\n";
801 B2WARNING(
"TOPUnpacker: interim FE - ASIC channel seen more than once"
802 <<
LogVar(
"ScrodID", scrodID)
803 <<
LogVar(
"carrier", carrier)
806 <<
LogVar(
"times seen", it));
813 channelOutputString +=
"Total:\t" + std::to_string(nChannels) +
" " + std::to_string(nChannelsDiff);
814 B2DEBUG(21, channelOutputString);
816 return array.getRemainingWords();
823 bool pedestalSubtracted,
int expNo)
826 B2DEBUG(22,
"Unpacking Production firmware debug data format to TOPRawDigits "
827 "dataSize = " << bufferSize);
832 word = array.getWord();
833 unsigned int evtType = word >> 24;
834 unsigned int evtVersion = (word >> 16) & 0xFF;
835 unsigned int evtMagicHeader = (word >> 12) & 0xF;
836 unsigned int evtScrodID = word & 0xFFF;
841 const auto* feemap =
m_topgp->getFrontEndMapper().getMap(evtScrodID);
843 moduleID = feemap->getModuleID();
844 boardstack = feemap->getBoardstackNumber();
846 B2WARNING(
"TOPUnpacker: no front-end map available."
847 <<
LogVar(
"SCROD ID", evtScrodID));
851 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
852 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
853 <<
"\tevtType = " << evtType
854 <<
", evtVersion = " << evtVersion
855 <<
", evtMagicHeader = " << evtMagicHeader
856 <<
", evtScrodID = " << evtScrodID);
858 if (evtMagicHeader != 0xA) {
859 B2WARNING(
"TOPUnpacker: event header magic word mismatch. should be 0xA."
860 <<
LogVar(
"Magic word", evtMagicHeader));
861 return array.getRemainingWords();
864 word = array.getWord();
865 unsigned int evtExtra = word >> 29;
866 unsigned int evtNumWordsBonus = (word >> 16) & 0x1FFF;
867 unsigned int evtPhase = (word >> 12) & 0xF;
868 unsigned int evtNumWordsCore = word & 0xFFF;
870 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
871 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
872 <<
"\tevtExtra = " << evtExtra
873 <<
", evtNumWordsBonus = " << evtNumWordsBonus
874 <<
", evtPhase = " << evtPhase
875 <<
", numWordsCore = " << evtNumWordsCore);
877 word = array.getWord();
878 bool evtSkipHit = word >> 31;
879 bool injVetoFlag = (word >> 30) & 0x1;
880 unsigned int PSBypass = (word >> 27) & 0x7;
881 unsigned int evtCtime = (word >> 16) & 0x7FF;
882 unsigned int evtRevo9Counter = word & 0xFFFF;
886 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
887 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
888 <<
"\tevtSkipHit = " << evtSkipHit
889 <<
", injVetoFlag = " << injVetoFlag
890 <<
", PSBypass = " << PSBypass
891 <<
", evtCtime = " << evtCtime
892 <<
", evtRevo9Counter = " << evtRevo9Counter);
894 word = array.getWord();
895 unsigned int evtAsicMask = word >> 16;
896 unsigned int evtEventQueueDepth = (word >> 8) & 0xFF;
897 unsigned int evtEventNumberByte = word & 0xFF;
899 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
900 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
901 <<
"\tevtAsicMask = " << evtAsicMask
902 <<
", evtEventQueueDepth = " << evtEventQueueDepth
903 <<
", evtEventNumberByte = " << evtEventNumberByte);
917 B2DEBUG(22,
"end of event header, start of hits:");
919 const int numWordsPerHit = 4 + evtExtra;
920 unsigned int numHitsFound = 0;
921 unsigned int numExpectedWaveforms = 0;
923 std::vector<TOPRawDigit*> digitsWithWaveform;
925 while (array.getRemainingWords() > numWordsPerHit
926 && array.getIndex() < evtNumWordsCore - 2) {
927 array.resetChecksum();
931 unsigned int hitCarrier = 0;
932 unsigned int hitAsic = 0;
933 unsigned int hitChannel = 0;
934 unsigned int hitWindow = 0;
935 unsigned int hitMagicHeader = 0;
936 unsigned int hitTFine = 0;
937 bool hitHasWaveform =
false;
938 bool hitIsOnHeap =
false;
939 unsigned int hitHeapWindow = 0;
940 bool hitIsOnHeapStraddle =
false;
941 unsigned int hitHeapWindowStraddle = 0;
942 bool hitIsWindowStraddle =
false;
943 short hitIntegral = 0;
946 if (dataFormat == TOP::RawDataType::c_ProductionDebug01) {
947 word = array.getWord();
948 hitCarrier = word >> 30;
949 hitAsic = (word >> 28) & 0x3;
950 hitChannel = (word >> 25) & 0x7;
951 hitWindow = (word >> 16) & 0x1FF;
952 hitMagicHeader = (word >> 12) & 0xF;
953 hitTFine = (word >> 8) & 0xF;
954 hitHasWaveform = (word >> 7) & 0x1;
955 hitIsOnHeap = (word >> 6) & 0x1;
956 hitHeapWindow = word & 0x3F;
959 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
960 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
961 <<
"\thitCarrier = " << hitCarrier
962 <<
", hitAsic = " << hitAsic
963 <<
", hitChannel = " << hitChannel
964 <<
", hitWindow = " << hitWindow
967 <<
", hitHasWaveform = " << hitHasWaveform
973 word = array.getWord();
975 hitIntegral = word & 0xFFFF;
976 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
977 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
978 <<
"\thitVPeak = " << hitVPeak
979 <<
", hitIntegral = " << hitIntegral);
981 }
else if (dataFormat == TOP::RawDataType::c_ProductionDebug02) {
982 word = array.getWord();
983 hitCarrier = word >> 30;
984 hitAsic = (word >> 28) & 0x3;
985 hitChannel = (word >> 25) & 0x7;
986 hitWindow = (word >> 16) & 0x1FF;
987 hitMagicHeader = (word >> 12) & 0xF;
988 hitTFine = (word >> 8) & 0xF;
989 hitHasWaveform = (word >> 7) & 0x1;
990 hitIsWindowStraddle = (word >> 6) & 0x1;
991 hitIntegral = word & 0x3F;
994 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
995 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
996 <<
"\thitCarrier = " << hitCarrier
997 <<
", hitAsic = " << hitAsic
998 <<
", hitChannel = " << hitChannel
999 <<
", hitWindow = " << hitWindow
1002 <<
", hitHasWaveform = " << hitHasWaveform
1003 <<
", hitIsWindowStraddle = " << hitHasWaveform
1004 <<
", hitIntegral = " << hitIntegral
1008 word = array.getWord();
1010 hitIsOnHeapStraddle = (word >> 15) & 0x1;
1011 hitHeapWindowStraddle = (word >> 8) & 0x7F;
1012 hitIsOnHeap = (word >> 7) & 0x1;
1013 hitHeapWindow = word & 0x1;
1015 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1016 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1017 <<
"\thitVPeak = " << hitVPeak
1018 <<
", hitIsOnHeapStraddle = " << hitIsOnHeapStraddle
1019 <<
", hitHeapWindowStraddle = " << hitHeapWindowStraddle
1020 <<
", hitIsOnHeap = " << hitIsOnHeap
1021 <<
", hitHeapWindow = " << hitHeapWindow);
1023 B2WARNING(
"TOPUnpacker: could not match data type inside unpackProdDebug()"
1024 <<
LogVar(
"evtType", evtType) <<
LogVar(
"evtVersion", evtVersion));
1025 return array.getRemainingWords();
1029 if (hitHasWaveform) {
1030 numExpectedWaveforms += 1;
1033 if (hitMagicHeader != 0xB) {
1034 B2WARNING(
"TOPUnpacker: hit header magic word mismatch. should be 0xB."
1035 <<
LogVar(
"Magic word", hitMagicHeader));
1036 return array.getRemainingWords();
1039 word = array.getWord();
1042 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1043 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1044 <<
"\thitVRise0 = " << hitVRise0
1045 <<
", hitVRise1 = " << hitVRise1);
1047 word = array.getWord();
1050 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1051 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1052 <<
"\thitVFall0 = " << hitVFall0
1053 <<
", hitVFall1 = " << hitVFall1);
1055 word = array.getWord();
1056 unsigned short hitSampleRise = (word >> 24);
1057 short hitDSampPeak = (word >> 20) & 0xF;
1058 short hitDSampFall = (word >> 16) & 0xF;
1059 unsigned short hitHeaderChecksum = word & 0xFFFF;
1060 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1061 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1062 <<
"\thitSampleRise = " << hitSampleRise
1063 <<
", hitDSampPeak = " << hitDSampPeak
1064 <<
", hitDSampFall = " << hitDSampFall
1065 <<
", hitheaderChecksum = " << hitHeaderChecksum
1066 <<
", checksum " << (array.validateChecksum() ?
"OK" :
"NOT OK"));
1068 if (!array.validateChecksum()) {
1069 B2WARNING(
"TOPUnpacker: hit checksum invalid.");
1070 return array.getRemainingWords();
1075 digit->setCarrierNumber(hitCarrier);
1076 digit->setASICNumber(hitAsic);
1077 digit->setASICChannel(hitChannel);
1078 digit->setASICWindow(hitWindow);
1079 digit->setLastWriteAddr(0);
1080 digit->setSampleRise(hitSampleRise);
1081 digit->setDeltaSamplePeak(hitDSampPeak);
1082 digit->setDeltaSampleFall(hitDSampFall);
1083 digit->setValueRise0(hitVRise0);
1084 digit->setValueRise1(hitVRise1);
1085 digit->setValuePeak(hitVPeak);
1086 digit->setValueFall0(hitVFall0);
1087 digit->setValueFall1(hitVFall1);
1088 digit->setTFine(hitTFine);
1089 digit->setIntegral(hitIntegral);
1090 digit->setRevo9Counter(evtRevo9Counter);
1091 digit->setPhase(evtPhase);
1094 if (hitHasWaveform) {
1095 digitsWithWaveform.push_back(digit);
1099 if (dataFormat == TOP::RawDataType::c_ProductionDebug01) {
1103 hitIsOnHeap ? 428 + hitHeapWindow : hitWindow,
1104 hitIsWindowStraddle);
1105 }
else if (dataFormat == TOP::RawDataType::c_ProductionDebug02) {
1109 hitIsOnHeap ? 428 + hitHeapWindow : hitWindow,
1110 hitIsWindowStraddle,
1112 hitIsOnHeapStraddle ? 428 + hitHeapWindowStraddle : hitWindow +
1117 for (
unsigned int i = 0; i < evtExtra; ++i) {
1118 word = array.getWord();
1119 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1120 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1121 <<
"\thit extra word " << i <<
" (" << evtExtra <<
")");
1126 digit->addRelationTo(hitDebug);
1132 word = array.getWord();
1133 unsigned int evtSdType = (word >> 24);
1134 unsigned int evtSdData = (word >> 12) & 0xFFF;
1135 unsigned int evtMagicFooter = (word >> 9) & 0x7;
1136 unsigned int evtNHits = word & 0x1FF;
1137 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1138 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1139 <<
"\tevtSdType = " << evtSdType
1140 <<
", evtSdData = " << evtSdData
1141 <<
", evtMagicFooter = " << evtMagicFooter
1142 <<
", evtNHits = " << evtNHits <<
" (" << numHitsFound <<
")");
1144 if (evtSdType != 0) {
1145 m_slowData.appendNew(evtScrodID, evtSdType, evtSdData);
1148 if (evtMagicFooter != 0x5) {
1149 B2WARNING(
"TOPUnpacker: event footer magic word mismatch. should be 0x5."
1150 <<
LogVar(
"Magic word", evtMagicFooter));
1151 return array.getRemainingWords();
1154 B2DEBUG(22,
"the rest:");
1156 unsigned int numParsedWaveforms = 0;
1157 while (array.peekWord() != 0x6c617374
1158 && array.getRemainingWords() > 0) {
1160 word = array.getWord();
1161 unsigned int wfNSamples = (word >> 16);
1162 unsigned int wfNWindows = (word >> 8) & 0x7;
1163 unsigned int wfCarrier = (word >> 5) & 0x3;
1164 unsigned int wfAsic = (word >> 3) & 0x3;
1165 unsigned int wfChannel = word & 0x7;
1168 const auto& mapper =
m_topgp->getChannelMapper();
1169 unsigned channel = mapper.getChannel(boardstack, wfCarrier, wfAsic, wfChannel);
1170 int pixelID = mapper.getPixelID(channel);
1172 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1173 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1174 <<
"\twfNSamples = " << wfNSamples
1175 <<
", wfNWindows = " << wfNWindows
1176 <<
", wfCarrier = " << wfCarrier
1177 <<
", wfAsic = " << wfAsic
1178 <<
", wfChannel " << wfChannel);
1180 if (wfNSamples != 32 && wfNSamples != 16) {
1181 B2WARNING(
"TOPUnpacker: suspicious value for wfNSamples."
1182 <<
LogVar(
"wfNSamples", wfNSamples));
1183 return array.getRemainingWords();
1186 word = array.getWord();
1187 unsigned int wfStartSample = (word >> 25) & 0x3F;
1188 unsigned int wfWindowLogic = (word >> 16) & 0x1FF;
1189 unsigned int wfEventNumber = (word >> 9) & 0x7F;
1190 unsigned int wfWindowPhysical = word & 0x1FF;
1192 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1193 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1194 <<
"\twfStartSample = " << wfStartSample
1195 <<
", wfWindowLogic = " << wfWindowLogic
1196 <<
", wfEventNumber = " << wfEventNumber
1197 <<
", wfWindowPhysical = " << wfWindowPhysical);
1199 std::vector<short> wfSamples;
1201 for (
unsigned int i = 0; i < wfNSamples / 2; ++i) {
1202 short wfSampleLast = 0;
1203 short wfSampleFirst = 0;
1206 word = array.getWord();
1207 if (pedestalSubtracted) {
1208 wfSampleLast = (word >> 16);
1209 wfSampleFirst = word & 0xFFFF;
1211 wfSampleLast = (word >> 16) & 0xFFF;
1212 wfSampleFirst = word & 0xFFF;
1216 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1217 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1218 <<
"\twfSample" << 2 * i + 1 <<
" = " << wfSampleLast
1219 <<
", wfSample" << 2 * i <<
" = " << wfSampleFirst);
1221 wfSamples.push_back(wfSampleFirst);
1222 wfSamples.push_back(wfSampleLast);
1226 auto* waveform =
m_waveforms.appendNew(moduleID, pixelID, channel, evtScrodID,
1227 wfWindowLogic, wfStartSample, wfSamples);
1228 waveform->setPedestalSubtractedFlag(pedestalSubtracted);
1229 waveform->setPhysicalWindow(wfWindowPhysical);
1230 if (numParsedWaveforms < digitsWithWaveform.size()) {
1231 const auto* digit = digitsWithWaveform[numParsedWaveforms];
1232 if (digit->getScrodChannel() == channel % 128) {
1233 digit->addRelationTo(waveform);
1235 B2WARNING(
"TOPUnpacker: hit and its waveform have different channel number."
1236 <<
LogVar(
"channel (hit)", digit->getScrodChannel())
1237 <<
LogVar(
"channel (waveform)", channel % 128));
1240 numParsedWaveforms += 1;
1244 if (numExpectedWaveforms != numParsedWaveforms) {
1245 B2WARNING(
"TOPUnpacker: number of expected and parsed waveforms does not match."
1246 <<
LogVar(
"expected", numExpectedWaveforms)
1247 <<
LogVar(
"parsed", numParsedWaveforms));
1250 return array.getRemainingWords();