436 bool pedestalSubtracted)
439 B2DEBUG(22,
"Unpacking InterimFEVer01 to TOPRawDigits and TOPRawWaveforms, "
440 "dataSize = " << bufferSize);
447 map<unsigned short, int> evtNumCounter;
448 std::vector<unsigned short> channelCounter(128, 0);
450 unsigned word = array.getWord();
451 unsigned short scrodID = word & 0x0FFF;
454 word = array.getWord();
457 while (array.getRemainingWords() > 0) {
459 unsigned header = array.getWord();
461 if ((header & 0xFF) == 0xBE) {
464 unsigned short scrodID_SSFE;
465 unsigned short carrier_SSFE;
466 unsigned short asic_SSFE;
467 unsigned short channel_SSFE;
468 unsigned short evtNum_SSFE;
470 evtNum_SSFE = (header >> 8) & 0xFF;
471 scrodID_SSFE = (header >> 16) & 0x7F;
472 channel_SSFE = (header >> 24) & 0x07;
473 asic_SSFE = (header >> 27) & 0x03;
474 carrier_SSFE = (header >> 29) & 0x03;
476 const auto* feemap =
m_topgp->getFrontEndMapper().getMap(scrodID_SSFE);
478 moduleID = feemap->getModuleID();
479 boardstack = feemap->getBoardstackNumber();
481 B2ERROR(
"TOPUnpacker: no front-end map available."
482 <<
LogVar(
"SCROD ID", scrodID_SSFE));
486 if (scrodID_SSFE != scrodID) {
487 B2ERROR(
"TOPUnpacker: corrupted data - "
488 <<
"different scrodID's in HLSB and super short FE header."
489 <<
LogVar(
"SCROD", scrodID_SSFE)
490 <<
LogVar(
"slot", moduleID)
491 <<
LogVar(
"BS", boardstack));
492 B2DEBUG(21,
"Different scrodID's in HLSB and FE header: " << scrodID <<
" " << scrodID_SSFE <<
" word = 0x" << std::hex << word);
494 return array.getRemainingWords();
497 B2DEBUG(21, scrodID_SSFE <<
"\t" << carrier_SSFE <<
"\t" << asic_SSFE <<
"\t" << channel_SSFE <<
"\t" << evtNum_SSFE);
499 int channelID = carrier_SSFE * 32 + asic_SSFE * 8 + channel_SSFE;
500 channelCounter[channelID] += 1;
501 evtNumCounter[evtNum_SSFE] += 1;
503 info->incrementFEHeadersCount();
504 info->incrementEmptyFEHeadersCount();
509 if (header != 0xaaaa0104 and header != 0xaaaa0103 and header != 0xaaaa0100) {
510 B2ERROR(
"TOPUnpacker: corrupted data - invalid FE header word");
511 B2DEBUG(21,
"Invalid FE header word: " << std::hex << header <<
" 0b" << std::bitset<32>(header));
512 B2DEBUG(21,
"SCROD ID: " << scrodID <<
" " << std::hex << scrodID);
515 return array.getRemainingWords();
519 word = array.getWord();
520 unsigned short scrodID_FE = word >> 25;
521 unsigned short convertedAddr = (word >> 16) & 0x1FF;
522 unsigned short evtNum_numWin_trigPat_FEheader = word & 0xFFFF;
523 unsigned short evtNum_FEheader = evtNum_numWin_trigPat_FEheader & 0xFF;
524 evtNumCounter[evtNum_FEheader] += 1;
526 if (scrodID_FE != scrodID) {
527 B2ERROR(
"TOPUnpacker: different scrodID's in HLSB and FE header."
528 <<
LogVar(
"scrodID (HSLB)", scrodID)
529 <<
LogVar(
"scrodID (FE)", scrodID_FE));
532 return array.getRemainingWords();
535 word = array.getWord();
537 unsigned lastWrAddr = (word & 0x0FF) << 1;
539 unsigned short asicChannelFE = (word >> 8) & 0x07;
540 unsigned short asicFE = (word >> 12) & 0x03;
541 unsigned short carrierFE = (word >> 14) & 0x03;
542 unsigned short channelID = carrierFE * 32 + asicFE * 8 + asicChannelFE;
545 B2DEBUG(21, scrodID_FE <<
"\t" << carrierFE <<
"\t" << asicFE <<
"\t" << asicChannelFE <<
"\t" << evtNum_FEheader);
547 channelCounter[channelID] += 1;
549 std::vector<TOPRawDigit*> digits;
551 if (header != 0xaaaa0104) {
554 word = array.getWord();
555 short samplePeak_p = word & 0xFFFF;
556 short valuePeak_p = (word >> 16) & 0xFFFF;
558 word = array.getWord();
559 short sampleRise_p = word & 0xFFFF;
560 short valueRise0_p = (word >> 16) & 0xFFFF;
562 word = array.getWord();
563 short valueRise1_p = word & 0xFFFF;
564 short sampleFall_p = (word >> 16) & 0xFFFF;
566 word = array.getWord();
567 short valueFall0_p = word & 0xFFFF;
568 short valueFall1_p = (word >> 16) & 0xFFFF;
570 word = array.getWord();
571 short integral_p = word & 0xFFFF;
578 word = array.getWord();
579 short samplePeak_n = word & 0xFFFF;
580 short valuePeak_n = (word >> 16) & 0xFFFF;
597 word = array.getWord();
598 short integral_n = word & 0xFFFF;
599 short qualityFlags_n = (word >> 16) & 0xFFFF;
601 if (abs(valuePeak_p) != 9999) {
603 digit->setCarrierNumber(carrierFE);
604 digit->setASICNumber(asicFE);
605 digit->setASICChannel(asicChannelFE);
606 digit->setASICWindow(convertedAddr);
607 digit->setLastWriteAddr(lastWrAddr);
608 digit->setSampleRise(sampleRise_p);
609 digit->setDeltaSamplePeak(samplePeak_p - sampleRise_p);
610 digit->setDeltaSampleFall(sampleFall_p - sampleRise_p);
611 digit->setValueRise0(valueRise0_p);
612 digit->setValueRise1(valueRise1_p);
613 digit->setValuePeak(valuePeak_p);
614 digit->setValueFall0(valueFall0_p);
615 digit->setValueFall1(valueFall1_p);
616 digit->setIntegral(integral_p);
618 digit->addRelationTo(info);
619 digits.push_back(digit);
621 if (valuePeak_p < 150) {
623 tlpfResult->setBackgroundOffset(samplePeak_n);
624 tlpfResult->setAmplitude(valuePeak_n);
625 tlpfResult->setChisquare(qualityFlags_n);
626 tlpfResult->setRisingEdgeAndConvert(integral_n);
627 digit->addRelationTo(tlpfResult);
653 word = array.getWord();
654 if (word != 0x7473616c) {
664 info->incrementFEHeadersCount();
665 if (digits.empty()) info->incrementEmptyFEHeadersCount();
667 if (header != 0xaaaa0103)
continue;
670 word = array.getWord();
671 unsigned long evtNum_numWaves_refWin_WFheader = word;
672 unsigned short evtNum_WFheader = (evtNum_numWaves_refWin_WFheader >> 24) & 0xFF;
674 if (evtNum_WFheader != evtNum_FEheader) {
675 B2ERROR(
"TOPUnpacker: different carrier event number in WF and FE header."
676 <<
LogVar(
"Event number (FE header)", evtNum_FEheader)
677 <<
LogVar(
"Event number (WF header)", evtNum_WFheader));
682 word = array.getWord();
684 unsigned short carrier = (word >> 14) & 0x03;
685 unsigned short asic = (word >> 12) & 0x03;
687 unsigned short window = word & 0x1FF;
690 if (carrier != carrierFE) {
691 B2ERROR(
"TOPUnpacker: different carrier numbers in FE and WF header");
692 B2DEBUG(21,
"Different carrier numbers in FE and WF header: "
693 << carrierFE <<
" " << carrier);
696 if (asic != asicFE) {
697 B2ERROR(
"TOPUnpacker: different ASIC numbers in FE and WF header");
698 B2DEBUG(21,
"Different ASIC numbers in FE and WF header: "
699 << asicFE <<
" " << asic);
703 B2ERROR(
"TOPUnpacker: different ASIC channel numbers in FE and WF header");
704 B2DEBUG(21,
"Different ASIC channel numbers in FE and WF header: "
708 if (window != convertedAddr) {
709 B2ERROR(
"TOPUnpacker: different window numbers in FE and WF header");
710 B2DEBUG(21,
"Different window numbers in FE and WF header: "
711 << convertedAddr <<
" " << window);
717 std::vector<unsigned short> windows;
718 windows.push_back(window);
720 word = array.getWord();
721 windows.push_back(word & 0x1FF);
723 word = array.getWord();
724 windows.push_back(word & 0x1FF);
726 word = array.getWord();
727 windows.push_back(word & 0x1FF);
729 int numWords = 4 * 32;
730 if (array.getRemainingWords() < numWords) {
731 B2ERROR(
"TOPUnpacker: too few words for waveform data."
732 <<
LogVar(
"needed", numWords)
733 <<
LogVar(
"available", array.getRemainingWords()));
735 return array.getRemainingWords();
739 std::vector<short> adcData;
740 for (
int i = 0; i < numWords; i++) {
741 word = array.getWord();
742 adcData.push_back(word & 0xFFFF);
743 adcData.push_back((word >> 16) & 0xFFFF);
750 const auto* feemap =
m_topgp->getFrontEndMapper().getMap(scrodID);
752 moduleID = feemap->getModuleID();
753 boardstack = feemap->getBoardstackNumber();
755 B2ERROR(
"TOPUnpacker: no front-end map available."
756 <<
LogVar(
"SCROD ID", scrodID));
761 const auto& mapper =
m_topgp->getChannelMapper();
762 unsigned channel = mapper.getChannel(boardstack, carrier, asic,
asicChannel);
763 int pixelID = mapper.getPixelID(channel);
766 auto* waveform =
m_waveforms.appendNew(moduleID, pixelID, channel, scrodID,
768 waveform->setLastWriteAddr(lastWrAddr);
769 waveform->setStorageWindows(windows);
770 waveform->setPedestalSubtractedFlag(pedestalSubtracted);
771 waveform->addRelationTo(info);
772 info->incrementWaveformsCount();
775 for (
const auto* digit : digits) digit->addRelationTo(waveform);
779 if (evtNumCounter.size() != 1) {
780 B2ERROR(
"TOPUnpacker: Possible frame shift detected "
781 <<
"(More than one unique carrier event number in this readout event)."
782 <<
LogVar(
"SCROD", scrodID)
783 <<
LogVar(
"slot", moduleID)
784 <<
LogVar(
"BS", boardstack));
789 string evtNumOutputString;
790 evtNumOutputString +=
"Carrier event numbers and their counts for SCROD ID " + std::to_string(scrodID) +
":\n";
791 for (
auto const& it : evtNumCounter) {
793 evtNumOutputString += std::to_string(it.first) +
":\t" + std::to_string(it.second) +
"\n";
795 evtNumOutputString +=
"Total:\t" + std::to_string(nASICs);
796 B2DEBUG(21, evtNumOutputString);
799 int nChannelsDiff = 0;
801 string channelOutputString;
802 channelOutputString +=
"Detected channels and their counts for SCROD ID (channels with count == 1 are omitted)" + std::to_string(
806 for (
auto const& it : channelCounter) {
813 int channelID = channelIndex;
814 int carrier = channelID / 32;
815 int asic = (channelID % 32) / 8;
816 int chn = channelID % 8;
817 channelOutputString +=
"carrier: " + std::to_string(carrier) +
" asic: " + std::to_string(asic) +
" chn: " + std::to_string(
818 chn) +
" occurrence: " + std::to_string(it) +
"\n";
819 B2WARNING(
"TOPUnpacker: interim FE - ASIC channel seen more than once"
820 <<
LogVar(
"ScrodID", scrodID)
821 <<
LogVar(
"carrier", carrier)
824 <<
LogVar(
"times seen", it));
831 channelOutputString +=
"Total:\t" + std::to_string(nChannels) +
" " + std::to_string(nChannelsDiff);
832 B2DEBUG(21, channelOutputString);
834 return array.getRemainingWords();
841 bool pedestalSubtracted,
int expNo)
844 B2DEBUG(22,
"Unpacking Production firmware debug data format to TOPRawDigits "
845 "dataSize = " << bufferSize);
850 word = array.getWord();
851 unsigned int evtType = word >> 24;
852 unsigned int evtVersion = (word >> 16) & 0xFF;
853 unsigned int evtMagicHeader = (word >> 12) & 0xF;
854 unsigned int evtScrodID = word & 0xFFF;
859 const auto* feemap =
m_topgp->getFrontEndMapper().getMap(evtScrodID);
861 moduleID = feemap->getModuleID();
862 boardstack = feemap->getBoardstackNumber();
863 m_BS = (moduleID - 1) * 4 + boardstack;
866 B2WARNING(
"TOPUnpacker: no front-end map available."
867 <<
LogVar(
"SCROD ID", evtScrodID)
871 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
872 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
873 <<
"\tevtType = " << evtType
874 <<
", evtVersion = " << evtVersion
875 <<
", evtMagicHeader = " << evtMagicHeader
876 <<
", evtScrodID = " << evtScrodID);
878 if (evtMagicHeader != 0xA) {
880 B2WARNING(
"TOPUnpacker: event header magic word mismatch. should be 0xA."
881 <<
LogVar(
"Magic word", evtMagicHeader));
882 return array.getRemainingWords();
885 word = array.getWord();
886 unsigned int evtExtra = word >> 29;
887 unsigned int evtNumWordsBonus = (word >> 16) & 0x1FFF;
888 unsigned int evtPhase = (word >> 12) & 0xF;
889 unsigned int evtNumWordsCore = word & 0xFFF;
891 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
892 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
893 <<
"\tevtExtra = " << evtExtra
894 <<
", evtNumWordsBonus = " << evtNumWordsBonus
895 <<
", evtPhase = " << evtPhase
896 <<
", numWordsCore = " << evtNumWordsCore);
898 word = array.getWord();
899 bool evtSkipHit = word >> 31;
900 bool injVetoFlag = (word >> 30) & 0x1;
901 unsigned int PSBypass = (word >> 27) & 0x7;
902 unsigned int evtCtime = (word >> 16) & 0x7FF;
903 unsigned int evtRevo9Counter = word & 0xFFFF;
907 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
908 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
909 <<
"\tevtSkipHit = " << evtSkipHit
910 <<
", injVetoFlag = " << injVetoFlag
911 <<
", PSBypass = " << PSBypass
912 <<
", evtCtime = " << evtCtime
913 <<
", evtRevo9Counter = " << evtRevo9Counter);
915 word = array.getWord();
916 unsigned int evtAsicMask = word >> 16;
917 unsigned int evtEventQueueDepth = (word >> 8) & 0xFF;
918 unsigned int evtEventNumberByte = word & 0xFF;
920 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
921 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
922 <<
"\tevtAsicMask = " << evtAsicMask
923 <<
", evtEventQueueDepth = " << evtEventQueueDepth
924 <<
", evtEventNumberByte = " << evtEventNumberByte);
938 B2DEBUG(22,
"end of event header, start of hits:");
940 const int numWordsPerHit = 4 + evtExtra;
941 unsigned int numHitsFound = 0;
942 unsigned int numExpectedWaveforms = 0;
944 std::vector<TOPRawDigit*> digitsWithWaveform;
946 while (array.getRemainingWords() > numWordsPerHit
947 && array.getIndex() < evtNumWordsCore - 2) {
948 array.resetChecksum();
952 unsigned int hitCarrier = 0;
953 unsigned int hitAsic = 0;
954 unsigned int hitChannel = 0;
955 unsigned int hitWindow = 0;
956 unsigned int hitMagicHeader = 0;
957 unsigned int hitTFine = 0;
958 bool hitHasWaveform =
false;
959 bool hitIsOnHeap =
false;
960 unsigned int hitHeapWindow = 0;
961 bool hitIsOnHeapStraddle =
false;
962 unsigned int hitHeapWindowStraddle = 0;
963 bool hitIsWindowStraddle =
false;
964 short hitIntegral = 0;
967 if (dataFormat == TOP::RawDataType::c_ProductionDebug01) {
968 word = array.getWord();
969 hitCarrier = word >> 30;
970 hitAsic = (word >> 28) & 0x3;
971 hitChannel = (word >> 25) & 0x7;
972 hitWindow = (word >> 16) & 0x1FF;
973 hitMagicHeader = (word >> 12) & 0xF;
974 hitTFine = (word >> 8) & 0xF;
975 hitHasWaveform = (word >> 7) & 0x1;
976 hitIsOnHeap = (word >> 6) & 0x1;
977 hitHeapWindow = word & 0x3F;
980 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
981 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
982 <<
"\thitCarrier = " << hitCarrier
983 <<
", hitAsic = " << hitAsic
984 <<
", hitChannel = " << hitChannel
985 <<
", hitWindow = " << hitWindow
988 <<
", hitHasWaveform = " << hitHasWaveform
994 word = array.getWord();
996 hitIntegral = word & 0xFFFF;
997 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
998 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
999 <<
"\thitVPeak = " << hitVPeak
1000 <<
", hitIntegral = " << hitIntegral);
1002 }
else if (dataFormat == TOP::RawDataType::c_ProductionDebug02) {
1003 word = array.getWord();
1004 hitCarrier = word >> 30;
1005 hitAsic = (word >> 28) & 0x3;
1006 hitChannel = (word >> 25) & 0x7;
1007 hitWindow = (word >> 16) & 0x1FF;
1008 hitMagicHeader = (word >> 12) & 0xF;
1009 hitTFine = (word >> 8) & 0xF;
1010 hitHasWaveform = (word >> 7) & 0x1;
1011 hitIsWindowStraddle = (word >> 6) & 0x1;
1012 hitIntegral = word & 0x3F;
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 <<
"\thitCarrier = " << hitCarrier
1018 <<
", hitAsic = " << hitAsic
1019 <<
", hitChannel = " << hitChannel
1020 <<
", hitWindow = " << hitWindow
1023 <<
", hitHasWaveform = " << hitHasWaveform
1024 <<
", hitIsWindowStraddle = " << hitHasWaveform
1025 <<
", hitIntegral = " << hitIntegral
1029 word = array.getWord();
1031 hitIsOnHeapStraddle = (word >> 15) & 0x1;
1032 hitHeapWindowStraddle = (word >> 8) & 0x7F;
1033 hitIsOnHeap = (word >> 7) & 0x1;
1034 hitHeapWindow = word & 0x1;
1036 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1037 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1038 <<
"\thitVPeak = " << hitVPeak
1039 <<
", hitIsOnHeapStraddle = " << hitIsOnHeapStraddle
1040 <<
", hitHeapWindowStraddle = " << hitHeapWindowStraddle
1041 <<
", hitIsOnHeap = " << hitIsOnHeap
1042 <<
", hitHeapWindow = " << hitHeapWindow);
1045 B2WARNING(
"TOPUnpacker: could not match data type inside unpackProdDebug()"
1046 <<
LogVar(
"evtType", evtType) <<
LogVar(
"evtVersion", evtVersion));
1047 return array.getRemainingWords();
1051 if (hitHasWaveform) {
1052 numExpectedWaveforms += 1;
1055 if (hitMagicHeader != 0xB) {
1057 B2WARNING(
"TOPUnpacker: hit header magic word mismatch. should be 0xB."
1058 <<
LogVar(
"Magic word", hitMagicHeader));
1059 return array.getRemainingWords();
1062 word = array.getWord();
1065 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1066 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1067 <<
"\thitVRise0 = " << hitVRise0
1068 <<
", hitVRise1 = " << hitVRise1);
1070 word = array.getWord();
1073 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1074 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1075 <<
"\thitVFall0 = " << hitVFall0
1076 <<
", hitVFall1 = " << hitVFall1);
1078 word = array.getWord();
1079 unsigned short hitSampleRise = (word >> 24);
1080 short hitDSampPeak = (word >> 20) & 0xF;
1081 short hitDSampFall = (word >> 16) & 0xF;
1082 unsigned short hitHeaderChecksum = word & 0xFFFF;
1083 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1084 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1085 <<
"\thitSampleRise = " << hitSampleRise
1086 <<
", hitDSampPeak = " << hitDSampPeak
1087 <<
", hitDSampFall = " << hitDSampFall
1088 <<
", hitheaderChecksum = " << hitHeaderChecksum
1089 <<
", checksum " << (array.validateChecksum() ?
"OK" :
"NOT OK"));
1091 if (!array.validateChecksum()) {
1093 B2WARNING(
"TOPUnpacker: hit checksum invalid.");
1094 return array.getRemainingWords();
1099 digit->setCarrierNumber(hitCarrier);
1100 digit->setASICNumber(hitAsic);
1101 digit->setASICChannel(hitChannel);
1102 digit->setASICWindow(hitWindow);
1103 digit->setLastWriteAddr(0);
1104 digit->setSampleRise(hitSampleRise);
1105 digit->setDeltaSamplePeak(hitDSampPeak);
1106 digit->setDeltaSampleFall(hitDSampFall);
1107 digit->setValueRise0(hitVRise0);
1108 digit->setValueRise1(hitVRise1);
1109 digit->setValuePeak(hitVPeak);
1110 digit->setValueFall0(hitVFall0);
1111 digit->setValueFall1(hitVFall1);
1112 digit->setTFine(hitTFine);
1113 digit->setIntegral(hitIntegral);
1114 digit->setRevo9Counter(evtRevo9Counter);
1115 digit->setPhase(evtPhase);
1118 if (hitHasWaveform) {
1119 digitsWithWaveform.push_back(digit);
1123 if (dataFormat == TOP::RawDataType::c_ProductionDebug01) {
1127 hitIsOnHeap ? 428 + hitHeapWindow : hitWindow,
1128 hitIsWindowStraddle);
1129 }
else if (dataFormat == TOP::RawDataType::c_ProductionDebug02) {
1133 hitIsOnHeap ? 428 + hitHeapWindow : hitWindow,
1134 hitIsWindowStraddle,
1136 hitIsOnHeapStraddle ? 428 + hitHeapWindowStraddle : hitWindow +
1141 for (
unsigned int i = 0; i < evtExtra; ++i) {
1142 word = array.getWord();
1143 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1144 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1145 <<
"\thit extra word " << i <<
" (" << evtExtra <<
")");
1150 digit->addRelationTo(hitDebug);
1156 word = array.getWord();
1157 unsigned int evtSdType = (word >> 24);
1158 unsigned int evtSdData = (word >> 12) & 0xFFF;
1159 unsigned int evtMagicFooter = (word >> 9) & 0x7;
1160 unsigned int evtNHits = word & 0x1FF;
1161 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1162 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1163 <<
"\tevtSdType = " << evtSdType
1164 <<
", evtSdData = " << evtSdData
1165 <<
", evtMagicFooter = " << evtMagicFooter
1166 <<
", evtNHits = " << evtNHits <<
" (" << numHitsFound <<
")");
1168 if (evtSdType != 0) {
1169 m_slowData.appendNew(evtScrodID, evtSdType, evtSdData);
1172 if (evtMagicFooter != 0x5) {
1174 B2WARNING(
"TOPUnpacker: event footer magic word mismatch. should be 0x5."
1175 <<
LogVar(
"Magic word", evtMagicFooter));
1176 return array.getRemainingWords();
1179 B2DEBUG(22,
"the rest:");
1181 unsigned int numParsedWaveforms = 0;
1182 while (array.peekWord() != 0x6c617374
1183 && array.getRemainingWords() > 0) {
1185 word = array.getWord();
1186 unsigned int wfNSamples = (word >> 16);
1187 unsigned int wfNWindows = (word >> 8) & 0x7;
1188 unsigned int wfCarrier = (word >> 5) & 0x3;
1189 unsigned int wfAsic = (word >> 3) & 0x3;
1190 unsigned int wfChannel = word & 0x7;
1193 const auto& mapper =
m_topgp->getChannelMapper();
1194 unsigned channel = mapper.getChannel(boardstack, wfCarrier, wfAsic, wfChannel);
1195 int pixelID = mapper.getPixelID(channel);
1197 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1198 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1199 <<
"\twfNSamples = " << wfNSamples
1200 <<
", wfNWindows = " << wfNWindows
1201 <<
", wfCarrier = " << wfCarrier
1202 <<
", wfAsic = " << wfAsic
1203 <<
", wfChannel " << wfChannel);
1205 if (wfNSamples != 32 && wfNSamples != 16) {
1207 B2WARNING(
"TOPUnpacker: suspicious value for wfNSamples."
1208 <<
LogVar(
"wfNSamples", wfNSamples));
1209 return array.getRemainingWords();
1212 word = array.getWord();
1213 unsigned int wfStartSample = (word >> 25) & 0x3F;
1214 unsigned int wfWindowLogic = (word >> 16) & 0x1FF;
1215 unsigned int wfEventNumber = (word >> 9) & 0x7F;
1216 unsigned int wfWindowPhysical = word & 0x1FF;
1218 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1219 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1220 <<
"\twfStartSample = " << wfStartSample
1221 <<
", wfWindowLogic = " << wfWindowLogic
1222 <<
", wfEventNumber = " << wfEventNumber
1223 <<
", wfWindowPhysical = " << wfWindowPhysical);
1225 std::vector<short> wfSamples;
1227 for (
unsigned int i = 0; i < wfNSamples / 2; ++i) {
1228 short wfSampleLast = 0;
1229 short wfSampleFirst = 0;
1232 word = array.getWord();
1233 if (pedestalSubtracted) {
1234 wfSampleLast = (word >> 16);
1235 wfSampleFirst = word & 0xFFFF;
1237 wfSampleLast = (word >> 16) & 0xFFF;
1238 wfSampleFirst = word & 0xFFF;
1242 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1243 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1244 <<
"\twfSample" << 2 * i + 1 <<
" = " << wfSampleLast
1245 <<
", wfSample" << 2 * i <<
" = " << wfSampleFirst);
1247 wfSamples.push_back(wfSampleFirst);
1248 wfSamples.push_back(wfSampleLast);
1252 auto* waveform =
m_waveforms.appendNew(moduleID, pixelID, channel, evtScrodID,
1253 wfWindowLogic, wfStartSample, wfSamples);
1254 waveform->setPedestalSubtractedFlag(pedestalSubtracted);
1255 waveform->setPhysicalWindow(wfWindowPhysical);
1256 if (numParsedWaveforms < digitsWithWaveform.size()) {
1257 const auto* digit = digitsWithWaveform[numParsedWaveforms];
1258 if (digit->getScrodChannel() == channel % 128) {
1259 digit->addRelationTo(waveform);
1262 B2WARNING(
"TOPUnpacker: hit and its waveform have different channel number."
1263 <<
LogVar(
"channel (hit)", digit->getScrodChannel())
1264 <<
LogVar(
"channel (waveform)", channel % 128));
1267 numParsedWaveforms += 1;
1271 if (numExpectedWaveforms != numParsedWaveforms) {
1273 B2WARNING(
"TOPUnpacker: number of expected and parsed waveforms does not match."
1274 <<
LogVar(
"expected", numExpectedWaveforms)
1275 <<
LogVar(
"parsed", numParsedWaveforms));
1278 return array.getRemainingWords();