416 bool pedestalSubtracted)
419 B2DEBUG(22,
"Unpacking InterimFEVer01 to TOPRawDigits and TOPRawWaveforms, "
420 "dataSize = " << bufferSize);
427 map<unsigned short, int> evtNumCounter;
428 std::vector<unsigned short> channelCounter(128, 0);
430 unsigned word = array.getWord();
431 unsigned short scrodID = word & 0x0FFF;
434 word = array.getWord();
437 while (array.getRemainingWords() > 0) {
439 unsigned header = array.getWord();
441 if ((header & 0xFF) == 0xBE) {
444 unsigned short scrodID_SSFE;
445 unsigned short carrier_SSFE;
446 unsigned short asic_SSFE;
447 unsigned short channel_SSFE;
448 unsigned short evtNum_SSFE;
450 evtNum_SSFE = (header >> 8) & 0xFF;
451 scrodID_SSFE = (header >> 16) & 0x7F;
452 channel_SSFE = (header >> 24) & 0x07;
453 asic_SSFE = (header >> 27) & 0x03;
454 carrier_SSFE = (header >> 29) & 0x03;
456 const auto* feemap =
m_topgp->getFrontEndMapper().getMap(scrodID_SSFE);
458 moduleID = feemap->getModuleID();
459 boardstack = feemap->getBoardstackNumber();
461 B2ERROR(
"TOPUnpacker: no front-end map available."
462 <<
LogVar(
"SCROD ID", scrodID_SSFE));
466 if (scrodID_SSFE != scrodID) {
467 B2ERROR(
"TOPUnpacker: corrupted data - "
468 <<
"different scrodID's in HLSB and super short FE header."
469 <<
LogVar(
"SCROD", scrodID_SSFE)
470 <<
LogVar(
"slot", moduleID)
471 <<
LogVar(
"BS", boardstack));
472 B2DEBUG(21,
"Different scrodID's in HLSB and FE header: " << scrodID <<
" " << scrodID_SSFE <<
" word = 0x" << std::hex << word);
474 return array.getRemainingWords();
477 B2DEBUG(21, scrodID_SSFE <<
"\t" << carrier_SSFE <<
"\t" << asic_SSFE <<
"\t" << channel_SSFE <<
"\t" << evtNum_SSFE);
479 int channelID = carrier_SSFE * 32 + asic_SSFE * 8 + channel_SSFE;
480 channelCounter[channelID] += 1;
481 evtNumCounter[evtNum_SSFE] += 1;
483 info->incrementFEHeadersCount();
484 info->incrementEmptyFEHeadersCount();
489 if (header != 0xaaaa0104 and header != 0xaaaa0103 and header != 0xaaaa0100) {
490 B2ERROR(
"TOPUnpacker: corrupted data - invalid FE header word");
491 B2DEBUG(21,
"Invalid FE header word: " << std::hex << header <<
" 0b" << std::bitset<32>(header));
492 B2DEBUG(21,
"SCROD ID: " << scrodID <<
" " << std::hex << scrodID);
495 return array.getRemainingWords();
499 word = array.getWord();
500 unsigned short scrodID_FE = word >> 25;
501 unsigned short convertedAddr = (word >> 16) & 0x1FF;
502 unsigned short evtNum_numWin_trigPat_FEheader = word & 0xFFFF;
503 unsigned short evtNum_FEheader = evtNum_numWin_trigPat_FEheader & 0xFF;
504 evtNumCounter[evtNum_FEheader] += 1;
506 if (scrodID_FE != scrodID) {
507 B2ERROR(
"TOPUnpacker: different scrodID's in HLSB and FE header."
508 <<
LogVar(
"scrodID (HSLB)", scrodID)
509 <<
LogVar(
"scrodID (FE)", scrodID_FE));
512 return array.getRemainingWords();
515 word = array.getWord();
517 unsigned lastWrAddr = (word & 0x0FF) << 1;
519 unsigned short asicChannelFE = (word >> 8) & 0x07;
520 unsigned short asicFE = (word >> 12) & 0x03;
521 unsigned short carrierFE = (word >> 14) & 0x03;
522 unsigned short channelID = carrierFE * 32 + asicFE * 8 + asicChannelFE;
525 B2DEBUG(21, scrodID_FE <<
"\t" << carrierFE <<
"\t" << asicFE <<
"\t" << asicChannelFE <<
"\t" << evtNum_FEheader);
527 channelCounter[channelID] += 1;
529 std::vector<TOPRawDigit*> digits;
531 if (header != 0xaaaa0104) {
534 word = array.getWord();
535 short samplePeak_p = word & 0xFFFF;
536 short valuePeak_p = (word >> 16) & 0xFFFF;
538 word = array.getWord();
539 short sampleRise_p = word & 0xFFFF;
540 short valueRise0_p = (word >> 16) & 0xFFFF;
542 word = array.getWord();
543 short valueRise1_p = word & 0xFFFF;
544 short sampleFall_p = (word >> 16) & 0xFFFF;
546 word = array.getWord();
547 short valueFall0_p = word & 0xFFFF;
548 short valueFall1_p = (word >> 16) & 0xFFFF;
550 word = array.getWord();
551 short integral_p = word & 0xFFFF;
558 word = array.getWord();
559 short samplePeak_n = word & 0xFFFF;
560 short valuePeak_n = (word >> 16) & 0xFFFF;
577 word = array.getWord();
578 short integral_n = word & 0xFFFF;
579 short qualityFlags_n = (word >> 16) & 0xFFFF;
581 if (abs(valuePeak_p) != 9999) {
583 digit->setCarrierNumber(carrierFE);
584 digit->setASICNumber(asicFE);
585 digit->setASICChannel(asicChannelFE);
586 digit->setASICWindow(convertedAddr);
587 digit->setLastWriteAddr(lastWrAddr);
588 digit->setSampleRise(sampleRise_p);
589 digit->setDeltaSamplePeak(samplePeak_p - sampleRise_p);
590 digit->setDeltaSampleFall(sampleFall_p - sampleRise_p);
591 digit->setValueRise0(valueRise0_p);
592 digit->setValueRise1(valueRise1_p);
593 digit->setValuePeak(valuePeak_p);
594 digit->setValueFall0(valueFall0_p);
595 digit->setValueFall1(valueFall1_p);
596 digit->setIntegral(integral_p);
598 digit->addRelationTo(info);
599 digits.push_back(digit);
601 if (valuePeak_p < 150) {
603 tlpfResult->setBackgroundOffset(samplePeak_n);
604 tlpfResult->setAmplitude(valuePeak_n);
605 tlpfResult->setChisquare(qualityFlags_n);
606 tlpfResult->setRisingEdgeAndConvert(integral_n);
607 digit->addRelationTo(tlpfResult);
633 word = array.getWord();
634 if (word != 0x7473616c) {
644 info->incrementFEHeadersCount();
645 if (digits.empty()) info->incrementEmptyFEHeadersCount();
647 if (header != 0xaaaa0103)
continue;
650 word = array.getWord();
651 unsigned long evtNum_numWaves_refWin_WFheader = word;
652 unsigned short evtNum_WFheader = (evtNum_numWaves_refWin_WFheader >> 24) & 0xFF;
654 if (evtNum_WFheader != evtNum_FEheader) {
655 B2ERROR(
"TOPUnpacker: different carrier event number in WF and FE header."
656 <<
LogVar(
"Event number (FE header)", evtNum_FEheader)
657 <<
LogVar(
"Event number (WF header)", evtNum_WFheader));
662 word = array.getWord();
664 unsigned short carrier = (word >> 14) & 0x03;
665 unsigned short asic = (word >> 12) & 0x03;
667 unsigned short window = word & 0x1FF;
670 if (carrier != carrierFE) {
671 B2ERROR(
"TOPUnpacker: different carrier numbers in FE and WF header");
672 B2DEBUG(21,
"Different carrier numbers in FE and WF header: "
673 << carrierFE <<
" " << carrier);
676 if (asic != asicFE) {
677 B2ERROR(
"TOPUnpacker: different ASIC numbers in FE and WF header");
678 B2DEBUG(21,
"Different ASIC numbers in FE and WF header: "
679 << asicFE <<
" " << asic);
683 B2ERROR(
"TOPUnpacker: different ASIC channel numbers in FE and WF header");
684 B2DEBUG(21,
"Different ASIC channel numbers in FE and WF header: "
688 if (window != convertedAddr) {
689 B2ERROR(
"TOPUnpacker: different window numbers in FE and WF header");
690 B2DEBUG(21,
"Different window numbers in FE and WF header: "
691 << convertedAddr <<
" " << window);
697 std::vector<unsigned short> windows;
698 windows.push_back(window);
700 word = array.getWord();
701 windows.push_back(word & 0x1FF);
703 word = array.getWord();
704 windows.push_back(word & 0x1FF);
706 word = array.getWord();
707 windows.push_back(word & 0x1FF);
709 int numWords = 4 * 32;
710 if (array.getRemainingWords() < numWords) {
711 B2ERROR(
"TOPUnpacker: too few words for waveform data."
712 <<
LogVar(
"needed", numWords)
713 <<
LogVar(
"available", array.getRemainingWords()));
715 return array.getRemainingWords();
719 std::vector<short> adcData;
720 for (
int i = 0; i < numWords; i++) {
721 word = array.getWord();
722 adcData.push_back(word & 0xFFFF);
723 adcData.push_back((word >> 16) & 0xFFFF);
730 const auto* feemap =
m_topgp->getFrontEndMapper().getMap(scrodID);
732 moduleID = feemap->getModuleID();
733 boardstack = feemap->getBoardstackNumber();
735 B2ERROR(
"TOPUnpacker: no front-end map available."
736 <<
LogVar(
"SCROD ID", scrodID));
741 const auto& mapper =
m_topgp->getChannelMapper();
742 unsigned channel = mapper.getChannel(boardstack, carrier, asic,
asicChannel);
743 int pixelID = mapper.getPixelID(channel);
746 auto* waveform =
m_waveforms.appendNew(moduleID, pixelID, channel, scrodID,
748 waveform->setLastWriteAddr(lastWrAddr);
749 waveform->setStorageWindows(windows);
750 waveform->setPedestalSubtractedFlag(pedestalSubtracted);
751 waveform->addRelationTo(info);
752 info->incrementWaveformsCount();
755 for (
auto& digit : digits) digit->addRelationTo(waveform);
759 if (evtNumCounter.size() != 1) {
760 B2ERROR(
"TOPUnpacker: Possible frame shift detected "
761 <<
"(More than one unique carrier event number in this readout event)."
762 <<
LogVar(
"SCROD", scrodID)
763 <<
LogVar(
"slot", moduleID)
764 <<
LogVar(
"BS", boardstack));
769 string evtNumOutputString;
770 evtNumOutputString +=
"Carrier event numbers and their counts for SCROD ID " + std::to_string(scrodID) +
":\n";
771 for (
auto const& it : evtNumCounter) {
773 evtNumOutputString += std::to_string(it.first) +
":\t" + std::to_string(it.second) +
"\n";
775 evtNumOutputString +=
"Total:\t" + std::to_string(nASICs);
776 B2DEBUG(21, evtNumOutputString);
779 int nChannelsDiff = 0;
781 string channelOutputString;
782 channelOutputString +=
"Detected channels and their counts for SCROD ID (channels with count == 1 are omitted)" + std::to_string(
786 for (
auto const& it : channelCounter) {
792 int channelID = channelIndex;
793 int carrier = channelID / 32;
794 int asic = (channelID % 32) / 8;
795 int chn = channelID % 8;
798 channelOutputString +=
"carrier: " + std::to_string(carrier) +
" asic: " + std::to_string(asic) +
" chn: " + std::to_string(
799 chn) +
" occurence: " + std::to_string(it) +
"\n";
800 B2WARNING(
"TOPUnpacker: interim FE - ASIC channel seen more than once"
801 <<
LogVar(
"ScrodID", scrodID)
802 <<
LogVar(
"carrier", carrier)
805 <<
LogVar(
"times seen", it));
812 channelOutputString +=
"Total:\t" + std::to_string(nChannels) +
" " + std::to_string(nChannelsDiff);
813 B2DEBUG(21, channelOutputString);
815 return array.getRemainingWords();
822 bool pedestalSubtracted)
825 B2DEBUG(22,
"Unpacking Production firmware debug data format to TOPRawDigits "
826 "dataSize = " << bufferSize);
831 word = array.getWord();
832 unsigned int evtType = word >> 24;
833 unsigned int evtVersion = (word >> 16) & 0xFF;
834 unsigned int evtMagicHeader = (word >> 12) & 0xF;
835 unsigned int evtScrodID = word & 0xFFF;
840 const auto* feemap =
m_topgp->getFrontEndMapper().getMap(evtScrodID);
842 moduleID = feemap->getModuleID();
843 boardstack = feemap->getBoardstackNumber();
845 B2WARNING(
"TOPUnpacker: no front-end map available."
846 <<
LogVar(
"SCROD ID", evtScrodID));
850 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
851 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
852 <<
"\tevtType = " << evtType
853 <<
", evtVersion = " << evtVersion
854 <<
", evtMagicHeader = " << evtMagicHeader
855 <<
", evtScrodID = " << evtScrodID);
857 if (evtMagicHeader != 0xA) {
858 B2WARNING(
"TOPUnpacker: event header magic word mismatch. should be 0xA."
859 <<
LogVar(
"Magic word", evtMagicHeader));
860 return array.getRemainingWords();
863 word = array.getWord();
864 unsigned int evtExtra = word >> 29;
865 unsigned int evtNumWordsBonus = (word >> 16) & 0x1FFF;
866 unsigned int evtPhase = (word >> 12) & 0xF;
867 unsigned int evtNumWordsCore = word & 0xFFF;
869 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
870 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
871 <<
"\tevtExtra = " << evtExtra
872 <<
", evtNumWordsBonus = " << evtNumWordsBonus
873 <<
", evtPhase = " << evtPhase
874 <<
", numWordsCore = " << evtNumWordsCore);
876 word = array.getWord();
877 bool evtSkipHit = word >> 29;
878 unsigned int evtCtime = (word >> 16) & 0x7FF;
879 unsigned int evtRevo9Counter = word & 0xFFFF;
881 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
882 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
883 <<
"\tevtSkipHit = " << evtSkipHit
884 <<
", evtCtime = " << evtCtime
885 <<
", evtRevo9Counter = " << evtRevo9Counter);
887 word = array.getWord();
888 unsigned int evtAsicMask = word >> 16;
889 unsigned int evtEventQueueDepth = (word >> 8) & 0xFF;
890 unsigned int evtEventNumberByte = word & 0xFF;
892 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
893 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
894 <<
"\tevtAsicMask = " << evtAsicMask
895 <<
", evtEventQueueDepth = " << evtEventQueueDepth
896 <<
", evtEventNumberByte = " << evtEventNumberByte);
908 B2DEBUG(22,
"end of event header, start of hits:");
910 const int numWordsPerHit = 4 + evtExtra;
911 unsigned int numHitsFound = 0;
912 unsigned int numExpectedWaveforms = 0;
914 std::vector<TOPRawDigit*> digitsWithWaveform;
916 while (array.getRemainingWords() > numWordsPerHit
917 && array.getIndex() < evtNumWordsCore - 2) {
918 array.resetChecksum();
922 unsigned int hitCarrier = 0;
923 unsigned int hitAsic = 0;
924 unsigned int hitChannel = 0;
925 unsigned int hitWindow = 0;
926 unsigned int hitMagicHeader = 0;
927 unsigned int hitTFine = 0;
928 bool hitHasWaveform =
false;
929 bool hitIsOnHeap =
false;
930 unsigned int hitHeapWindow = 0;
931 bool hitIsOnHeapStraddle =
false;
932 unsigned int hitHeapWindowStraddle = 0;
933 bool hitIsWindowStraddle =
false;
934 short hitIntegral = 0;
937 if (dataFormat == TOP::RawDataType::c_ProductionDebug01) {
938 word = array.getWord();
939 hitCarrier = word >> 30;
940 hitAsic = (word >> 28) & 0x3;
941 hitChannel = (word >> 25) & 0x7;
942 hitWindow = (word >> 16) & 0x1FF;
943 hitMagicHeader = (word >> 12) & 0xF;
944 hitTFine = (word >> 8) & 0xF;
945 hitHasWaveform = (word >> 7) & 0x1;
946 hitIsOnHeap = (word >> 6) & 0x1;
947 hitHeapWindow = word & 0x3F;
950 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
951 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
952 <<
"\thitCarrier = " << hitCarrier
953 <<
", hitAsic = " << hitAsic
954 <<
", hitChannel = " << hitChannel
955 <<
", hitWindow = " << hitWindow
958 <<
", hitHasWaveform = " << hitHasWaveform
964 word = array.getWord();
966 hitIntegral = word & 0xFFFF;
967 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
968 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
969 <<
"\thitVPeak = " << hitVPeak
970 <<
", hitIntegral = " << hitIntegral);
972 }
else if (dataFormat == TOP::RawDataType::c_ProductionDebug02) {
973 word = array.getWord();
974 hitCarrier = word >> 30;
975 hitAsic = (word >> 28) & 0x3;
976 hitChannel = (word >> 25) & 0x7;
977 hitWindow = (word >> 16) & 0x1FF;
978 hitMagicHeader = (word >> 12) & 0xF;
979 hitTFine = (word >> 8) & 0xF;
980 hitHasWaveform = (word >> 7) & 0x1;
981 hitIsWindowStraddle = (word >> 6) & 0x1;
982 hitIntegral = word & 0x3F;
985 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
986 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
987 <<
"\thitCarrier = " << hitCarrier
988 <<
", hitAsic = " << hitAsic
989 <<
", hitChannel = " << hitChannel
990 <<
", hitWindow = " << hitWindow
993 <<
", hitHasWaveform = " << hitHasWaveform
994 <<
", hitIsWindowStraddle = " << hitHasWaveform
995 <<
", hitIntegral = " << hitIntegral
999 word = array.getWord();
1001 hitIsOnHeapStraddle = (word >> 15) & 0x1;
1002 hitHeapWindowStraddle = (word >> 8) & 0x7F;
1003 hitIsOnHeap = (word >> 7) & 0x1;
1004 hitHeapWindow = word & 0x1;
1006 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1007 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1008 <<
"\thitVPeak = " << hitVPeak
1009 <<
", hitIsOnHeapStraddle = " << hitIsOnHeapStraddle
1010 <<
", hitHeapWindowStraddle = " << hitHeapWindowStraddle
1011 <<
", hitIsOnHeap = " << hitIsOnHeap
1012 <<
", hitHeapWindow = " << hitHeapWindow);
1014 B2WARNING(
"TOPUnpacker: could not match data type inside unpackProdDebug()"
1015 <<
LogVar(
"evtType", evtType) <<
LogVar(
"evtVersion", evtVersion));
1016 return array.getRemainingWords();
1020 if (hitHasWaveform) {
1021 numExpectedWaveforms += 1;
1024 if (hitMagicHeader != 0xB) {
1025 B2WARNING(
"TOPUnpacker: hit header magic word mismatch. should be 0xB."
1026 <<
LogVar(
"Magic word", hitMagicHeader));
1027 return array.getRemainingWords();
1030 word = array.getWord();
1033 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1034 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1035 <<
"\thitVRise0 = " << hitVRise0
1036 <<
", hitVRise1 = " << hitVRise1);
1038 word = array.getWord();
1041 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1042 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1043 <<
"\thitVFall0 = " << hitVFall0
1044 <<
", hitVFall1 = " << hitVFall1);
1046 word = array.getWord();
1047 unsigned short hitSampleRise = (word >> 24);
1048 short hitDSampPeak = (word >> 20) & 0xF;
1049 short hitDSampFall = (word >> 16) & 0xF;
1050 unsigned short hitHeaderChecksum = word & 0xFFFF;
1051 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1052 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1053 <<
"\thitSampleRise = " << hitSampleRise
1054 <<
", hitDSampPeak = " << hitDSampPeak
1055 <<
", hitDSampFall = " << hitDSampFall
1056 <<
", hitheaderChecksum = " << hitHeaderChecksum
1057 <<
", checksum " << (array.validateChecksum() ?
"OK" :
"NOT OK"));
1059 if (!array.validateChecksum()) {
1060 B2WARNING(
"TOPUnpacker: hit checksum invalid.");
1061 return array.getRemainingWords();
1066 digit->setCarrierNumber(hitCarrier);
1067 digit->setASICNumber(hitAsic);
1068 digit->setASICChannel(hitChannel);
1069 digit->setASICWindow(hitWindow);
1070 digit->setLastWriteAddr(0);
1071 digit->setSampleRise(hitSampleRise);
1072 digit->setDeltaSamplePeak(hitDSampPeak);
1073 digit->setDeltaSampleFall(hitDSampFall);
1074 digit->setValueRise0(hitVRise0);
1075 digit->setValueRise1(hitVRise1);
1076 digit->setValuePeak(hitVPeak);
1077 digit->setValueFall0(hitVFall0);
1078 digit->setValueFall1(hitVFall1);
1079 digit->setTFine(hitTFine);
1080 digit->setIntegral(hitIntegral);
1081 digit->setRevo9Counter(evtRevo9Counter);
1082 digit->setPhase(evtPhase);
1085 if (hitHasWaveform) {
1086 digitsWithWaveform.push_back(digit);
1090 if (dataFormat == TOP::RawDataType::c_ProductionDebug01) {
1094 hitIsOnHeap ? 428 + hitHeapWindow : hitWindow,
1095 hitIsWindowStraddle);
1096 }
else if (dataFormat == TOP::RawDataType::c_ProductionDebug02) {
1100 hitIsOnHeap ? 428 + hitHeapWindow : hitWindow,
1101 hitIsWindowStraddle,
1103 hitIsOnHeapStraddle ? 428 + hitHeapWindowStraddle : hitWindow +
1108 for (
unsigned int i = 0; i < evtExtra; ++i) {
1109 word = array.getWord();
1110 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1111 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1112 <<
"\thit extra word " << i <<
" (" << evtExtra <<
")");
1117 digit->addRelationTo(hitDebug);
1123 word = array.getWord();
1124 unsigned int evtSdType = (word >> 24);
1125 unsigned int evtSdData = (word >> 12) & 0xFFF;
1126 unsigned int evtMagicFooter = (word >> 9) & 0x7;
1127 unsigned int evtNHits = word & 0x1FF;
1128 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1129 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1130 <<
"\tevtSdType = " << evtSdType
1131 <<
", evtSdData = " << evtSdData
1132 <<
", evtMagicFooter = " << evtMagicFooter
1133 <<
", evtNHits = " << evtNHits <<
" (" << numHitsFound <<
")");
1135 if (evtSdType != 0) {
1136 m_slowData.appendNew(evtScrodID, evtSdType, evtSdData);
1139 if (evtMagicFooter != 0x5) {
1140 B2WARNING(
"TOPUnpacker: event footer magic word mismatch. should be 0x5."
1141 <<
LogVar(
"Magic word", evtMagicFooter));
1142 return array.getRemainingWords();
1145 B2DEBUG(22,
"the rest:");
1147 unsigned int numParsedWaveforms = 0;
1148 while (array.peekWord() != 0x6c617374
1149 && array.getRemainingWords() > 0) {
1151 word = array.getWord();
1152 unsigned int wfNSamples = (word >> 16);
1153 unsigned int wfNWindows = (word >> 8) & 0x7;
1154 unsigned int wfCarrier = (word >> 5) & 0x3;
1155 unsigned int wfAsic = (word >> 3) & 0x3;
1156 unsigned int wfChannel = word & 0x7;
1159 const auto& mapper =
m_topgp->getChannelMapper();
1160 unsigned channel = mapper.getChannel(boardstack, wfCarrier, wfAsic, wfChannel);
1161 int pixelID = mapper.getPixelID(channel);
1163 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1164 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1165 <<
"\twfNSamples = " << wfNSamples
1166 <<
", wfNWindows = " << wfNWindows
1167 <<
", wfCarrier = " << wfCarrier
1168 <<
", wfAsic = " << wfAsic
1169 <<
", wfChannel " << wfChannel);
1171 if (wfNSamples != 32 && wfNSamples != 16) {
1172 B2WARNING(
"TOPUnpacker: suspicious value for wfNSamples."
1173 <<
LogVar(
"wfNSamples", wfNSamples));
1174 return array.getRemainingWords();
1177 word = array.getWord();
1178 unsigned int wfStartSample = (word >> 25) & 0x3F;
1179 unsigned int wfWindowLogic = (word >> 16) & 0x1FF;
1180 unsigned int wfEventNumber = (word >> 9) & 0x7F;
1181 unsigned int wfWindowPhysical = word & 0x1FF;
1183 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1184 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1185 <<
"\twfStartSample = " << wfStartSample
1186 <<
", wfWindowLogic = " << wfWindowLogic
1187 <<
", wfEventNumber = " << wfEventNumber
1188 <<
", wfWindowPhysical = " << wfWindowPhysical);
1190 std::vector<short> wfSamples;
1192 for (
unsigned int i = 0; i < wfNSamples / 2; ++i) {
1193 short wfSampleLast = 0;
1194 short wfSampleFirst = 0;
1197 word = array.getWord();
1198 if (pedestalSubtracted) {
1199 wfSampleLast = (word >> 16);
1200 wfSampleFirst = word & 0xFFFF;
1202 wfSampleLast = (word >> 16) & 0xFFF;
1203 wfSampleFirst = word & 0xFFF;
1207 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1208 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1209 <<
"\twfSample" << 2 * i + 1 <<
" = " << wfSampleLast
1210 <<
", wfSample" << 2 * i <<
" = " << wfSampleFirst);
1212 wfSamples.push_back(wfSampleFirst);
1213 wfSamples.push_back(wfSampleLast);
1217 auto* waveform =
m_waveforms.appendNew(moduleID, pixelID, channel, evtScrodID,
1218 wfWindowLogic, wfStartSample, wfSamples);
1219 waveform->setPedestalSubtractedFlag(pedestalSubtracted);
1220 waveform->setPhysicalWindow(wfWindowPhysical);
1221 if (numParsedWaveforms < digitsWithWaveform.size()) {
1222 const auto* digit = digitsWithWaveform[numParsedWaveforms];
1223 if (digit->getScrodChannel() == channel % 128) {
1224 digit->addRelationTo(waveform);
1226 B2WARNING(
"TOPUnpacker: hit and its waveform have different channel number."
1227 <<
LogVar(
"channel (hit)", digit->getScrodChannel())
1228 <<
LogVar(
"channel (waveform)", channel % 128));
1231 numParsedWaveforms += 1;
1235 if (numExpectedWaveforms != numParsedWaveforms) {
1236 B2WARNING(
"TOPUnpacker: number of expected and parsed waveforms does not match."
1237 <<
LogVar(
"expected", numExpectedWaveforms)
1238 <<
LogVar(
"parsed", numParsedWaveforms));
1241 return array.getRemainingWords();