424 bool pedestalSubtracted)
427 B2DEBUG(22,
"Unpacking InterimFEVer01 to TOPRawDigits and TOPRawWaveforms, "
428 "dataSize = " << bufferSize);
435 map<unsigned short, int> evtNumCounter;
436 std::vector<unsigned short> channelCounter(128, 0);
438 unsigned word = array.getWord();
439 unsigned short scrodID = word & 0x0FFF;
442 word = array.getWord();
445 while (array.getRemainingWords() > 0) {
447 unsigned header = array.getWord();
449 if ((header & 0xFF) == 0xBE) {
452 unsigned short scrodID_SSFE;
453 unsigned short carrier_SSFE;
454 unsigned short asic_SSFE;
455 unsigned short channel_SSFE;
456 unsigned short evtNum_SSFE;
458 evtNum_SSFE = (header >> 8) & 0xFF;
459 scrodID_SSFE = (header >> 16) & 0x7F;
460 channel_SSFE = (header >> 24) & 0x07;
461 asic_SSFE = (header >> 27) & 0x03;
462 carrier_SSFE = (header >> 29) & 0x03;
464 const auto* feemap =
m_topgp->getFrontEndMapper().getMap(scrodID_SSFE);
466 moduleID = feemap->getModuleID();
467 boardstack = feemap->getBoardstackNumber();
469 B2ERROR(
"TOPUnpacker: no front-end map available."
470 <<
LogVar(
"SCROD ID", scrodID_SSFE));
474 if (scrodID_SSFE != scrodID) {
475 B2ERROR(
"TOPUnpacker: corrupted data - "
476 <<
"different scrodID's in HLSB and super short FE header."
477 <<
LogVar(
"SCROD", scrodID_SSFE)
478 <<
LogVar(
"slot", moduleID)
479 <<
LogVar(
"BS", boardstack));
480 B2DEBUG(21,
"Different scrodID's in HLSB and FE header: " << scrodID <<
" " << scrodID_SSFE <<
" word = 0x" << std::hex << word);
482 return array.getRemainingWords();
485 B2DEBUG(21, scrodID_SSFE <<
"\t" << carrier_SSFE <<
"\t" << asic_SSFE <<
"\t" << channel_SSFE <<
"\t" << evtNum_SSFE);
487 int channelID = carrier_SSFE * 32 + asic_SSFE * 8 + channel_SSFE;
488 channelCounter[channelID] += 1;
489 evtNumCounter[evtNum_SSFE] += 1;
491 info->incrementFEHeadersCount();
492 info->incrementEmptyFEHeadersCount();
497 if (header != 0xaaaa0104 and header != 0xaaaa0103 and header != 0xaaaa0100) {
498 B2ERROR(
"TOPUnpacker: corrupted data - invalid FE header word");
499 B2DEBUG(21,
"Invalid FE header word: " << std::hex << header <<
" 0b" << std::bitset<32>(header));
500 B2DEBUG(21,
"SCROD ID: " << scrodID <<
" " << std::hex << scrodID);
503 return array.getRemainingWords();
507 word = array.getWord();
508 unsigned short scrodID_FE = word >> 25;
509 unsigned short convertedAddr = (word >> 16) & 0x1FF;
510 unsigned short evtNum_numWin_trigPat_FEheader = word & 0xFFFF;
511 unsigned short evtNum_FEheader = evtNum_numWin_trigPat_FEheader & 0xFF;
512 evtNumCounter[evtNum_FEheader] += 1;
514 if (scrodID_FE != scrodID) {
515 B2ERROR(
"TOPUnpacker: different scrodID's in HLSB and FE header."
516 <<
LogVar(
"scrodID (HSLB)", scrodID)
517 <<
LogVar(
"scrodID (FE)", scrodID_FE));
520 return array.getRemainingWords();
523 word = array.getWord();
525 unsigned lastWrAddr = (word & 0x0FF) << 1;
527 unsigned short asicChannelFE = (word >> 8) & 0x07;
528 unsigned short asicFE = (word >> 12) & 0x03;
529 unsigned short carrierFE = (word >> 14) & 0x03;
530 unsigned short channelID = carrierFE * 32 + asicFE * 8 + asicChannelFE;
533 B2DEBUG(21, scrodID_FE <<
"\t" << carrierFE <<
"\t" << asicFE <<
"\t" << asicChannelFE <<
"\t" << evtNum_FEheader);
535 channelCounter[channelID] += 1;
537 std::vector<TOPRawDigit*> digits;
539 if (header != 0xaaaa0104) {
542 word = array.getWord();
543 short samplePeak_p = word & 0xFFFF;
544 short valuePeak_p = (word >> 16) & 0xFFFF;
546 word = array.getWord();
547 short sampleRise_p = word & 0xFFFF;
548 short valueRise0_p = (word >> 16) & 0xFFFF;
550 word = array.getWord();
551 short valueRise1_p = word & 0xFFFF;
552 short sampleFall_p = (word >> 16) & 0xFFFF;
554 word = array.getWord();
555 short valueFall0_p = word & 0xFFFF;
556 short valueFall1_p = (word >> 16) & 0xFFFF;
558 word = array.getWord();
559 short integral_p = word & 0xFFFF;
566 word = array.getWord();
567 short samplePeak_n = word & 0xFFFF;
568 short valuePeak_n = (word >> 16) & 0xFFFF;
585 word = array.getWord();
586 short integral_n = word & 0xFFFF;
587 short qualityFlags_n = (word >> 16) & 0xFFFF;
589 if (abs(valuePeak_p) != 9999) {
591 digit->setCarrierNumber(carrierFE);
592 digit->setASICNumber(asicFE);
593 digit->setASICChannel(asicChannelFE);
594 digit->setASICWindow(convertedAddr);
595 digit->setLastWriteAddr(lastWrAddr);
596 digit->setSampleRise(sampleRise_p);
597 digit->setDeltaSamplePeak(samplePeak_p - sampleRise_p);
598 digit->setDeltaSampleFall(sampleFall_p - sampleRise_p);
599 digit->setValueRise0(valueRise0_p);
600 digit->setValueRise1(valueRise1_p);
601 digit->setValuePeak(valuePeak_p);
602 digit->setValueFall0(valueFall0_p);
603 digit->setValueFall1(valueFall1_p);
604 digit->setIntegral(integral_p);
606 digit->addRelationTo(info);
607 digits.push_back(digit);
609 if (valuePeak_p < 150) {
611 tlpfResult->setBackgroundOffset(samplePeak_n);
612 tlpfResult->setAmplitude(valuePeak_n);
613 tlpfResult->setChisquare(qualityFlags_n);
614 tlpfResult->setRisingEdgeAndConvert(integral_n);
615 digit->addRelationTo(tlpfResult);
641 word = array.getWord();
642 if (word != 0x7473616c) {
652 info->incrementFEHeadersCount();
653 if (digits.empty()) info->incrementEmptyFEHeadersCount();
655 if (header != 0xaaaa0103)
continue;
658 word = array.getWord();
659 unsigned long evtNum_numWaves_refWin_WFheader = word;
660 unsigned short evtNum_WFheader = (evtNum_numWaves_refWin_WFheader >> 24) & 0xFF;
662 if (evtNum_WFheader != evtNum_FEheader) {
663 B2ERROR(
"TOPUnpacker: different carrier event number in WF and FE header."
664 <<
LogVar(
"Event number (FE header)", evtNum_FEheader)
665 <<
LogVar(
"Event number (WF header)", evtNum_WFheader));
670 word = array.getWord();
672 unsigned short carrier = (word >> 14) & 0x03;
673 unsigned short asic = (word >> 12) & 0x03;
675 unsigned short window = word & 0x1FF;
678 if (carrier != carrierFE) {
679 B2ERROR(
"TOPUnpacker: different carrier numbers in FE and WF header");
680 B2DEBUG(21,
"Different carrier numbers in FE and WF header: "
681 << carrierFE <<
" " << carrier);
684 if (asic != asicFE) {
685 B2ERROR(
"TOPUnpacker: different ASIC numbers in FE and WF header");
686 B2DEBUG(21,
"Different ASIC numbers in FE and WF header: "
687 << asicFE <<
" " << asic);
691 B2ERROR(
"TOPUnpacker: different ASIC channel numbers in FE and WF header");
692 B2DEBUG(21,
"Different ASIC channel numbers in FE and WF header: "
696 if (window != convertedAddr) {
697 B2ERROR(
"TOPUnpacker: different window numbers in FE and WF header");
698 B2DEBUG(21,
"Different window numbers in FE and WF header: "
699 << convertedAddr <<
" " << window);
705 std::vector<unsigned short> windows;
706 windows.push_back(window);
708 word = array.getWord();
709 windows.push_back(word & 0x1FF);
711 word = array.getWord();
712 windows.push_back(word & 0x1FF);
714 word = array.getWord();
715 windows.push_back(word & 0x1FF);
717 int numWords = 4 * 32;
718 if (array.getRemainingWords() < numWords) {
719 B2ERROR(
"TOPUnpacker: too few words for waveform data."
720 <<
LogVar(
"needed", numWords)
721 <<
LogVar(
"available", array.getRemainingWords()));
723 return array.getRemainingWords();
727 std::vector<short> adcData;
728 for (
int i = 0; i < numWords; i++) {
729 word = array.getWord();
730 adcData.push_back(word & 0xFFFF);
731 adcData.push_back((word >> 16) & 0xFFFF);
738 const auto* feemap =
m_topgp->getFrontEndMapper().getMap(scrodID);
740 moduleID = feemap->getModuleID();
741 boardstack = feemap->getBoardstackNumber();
743 B2ERROR(
"TOPUnpacker: no front-end map available."
744 <<
LogVar(
"SCROD ID", scrodID));
749 const auto& mapper =
m_topgp->getChannelMapper();
750 unsigned channel = mapper.getChannel(boardstack, carrier, asic,
asicChannel);
751 int pixelID = mapper.getPixelID(channel);
754 auto* waveform =
m_waveforms.appendNew(moduleID, pixelID, channel, scrodID,
756 waveform->setLastWriteAddr(lastWrAddr);
757 waveform->setStorageWindows(windows);
758 waveform->setPedestalSubtractedFlag(pedestalSubtracted);
759 waveform->addRelationTo(info);
760 info->incrementWaveformsCount();
763 for (
auto& digit : digits) digit->addRelationTo(waveform);
767 if (evtNumCounter.size() != 1) {
768 B2ERROR(
"TOPUnpacker: Possible frame shift detected "
769 <<
"(More than one unique carrier event number in this readout event)."
770 <<
LogVar(
"SCROD", scrodID)
771 <<
LogVar(
"slot", moduleID)
772 <<
LogVar(
"BS", boardstack));
777 string evtNumOutputString;
778 evtNumOutputString +=
"Carrier event numbers and their counts for SCROD ID " + std::to_string(scrodID) +
":\n";
779 for (
auto const& it : evtNumCounter) {
781 evtNumOutputString += std::to_string(it.first) +
":\t" + std::to_string(it.second) +
"\n";
783 evtNumOutputString +=
"Total:\t" + std::to_string(nASICs);
784 B2DEBUG(21, evtNumOutputString);
787 int nChannelsDiff = 0;
789 string channelOutputString;
790 channelOutputString +=
"Detected channels and their counts for SCROD ID (channels with count == 1 are omitted)" + std::to_string(
794 for (
auto const& it : channelCounter) {
800 int channelID = channelIndex;
801 int carrier = channelID / 32;
802 int asic = (channelID % 32) / 8;
803 int chn = channelID % 8;
806 channelOutputString +=
"carrier: " + std::to_string(carrier) +
" asic: " + std::to_string(asic) +
" chn: " + std::to_string(
807 chn) +
" occurrence: " + std::to_string(it) +
"\n";
808 B2WARNING(
"TOPUnpacker: interim FE - ASIC channel seen more than once"
809 <<
LogVar(
"ScrodID", scrodID)
810 <<
LogVar(
"carrier", carrier)
813 <<
LogVar(
"times seen", it));
820 channelOutputString +=
"Total:\t" + std::to_string(nChannels) +
" " + std::to_string(nChannelsDiff);
821 B2DEBUG(21, channelOutputString);
823 return array.getRemainingWords();
830 bool pedestalSubtracted,
int expNo)
833 B2DEBUG(22,
"Unpacking Production firmware debug data format to TOPRawDigits "
834 "dataSize = " << bufferSize);
839 word = array.getWord();
840 unsigned int evtType = word >> 24;
841 unsigned int evtVersion = (word >> 16) & 0xFF;
842 unsigned int evtMagicHeader = (word >> 12) & 0xF;
843 unsigned int evtScrodID = word & 0xFFF;
848 const auto* feemap =
m_topgp->getFrontEndMapper().getMap(evtScrodID);
850 moduleID = feemap->getModuleID();
851 boardstack = feemap->getBoardstackNumber();
853 B2WARNING(
"TOPUnpacker: no front-end map available."
854 <<
LogVar(
"SCROD ID", evtScrodID));
858 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
859 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
860 <<
"\tevtType = " << evtType
861 <<
", evtVersion = " << evtVersion
862 <<
", evtMagicHeader = " << evtMagicHeader
863 <<
", evtScrodID = " << evtScrodID);
865 if (evtMagicHeader != 0xA) {
866 B2WARNING(
"TOPUnpacker: event header magic word mismatch. should be 0xA."
867 <<
LogVar(
"Magic word", evtMagicHeader));
868 return array.getRemainingWords();
871 word = array.getWord();
872 unsigned int evtExtra = word >> 29;
873 unsigned int evtNumWordsBonus = (word >> 16) & 0x1FFF;
874 unsigned int evtPhase = (word >> 12) & 0xF;
875 unsigned int evtNumWordsCore = word & 0xFFF;
877 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
878 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
879 <<
"\tevtExtra = " << evtExtra
880 <<
", evtNumWordsBonus = " << evtNumWordsBonus
881 <<
", evtPhase = " << evtPhase
882 <<
", numWordsCore = " << evtNumWordsCore);
884 word = array.getWord();
885 bool evtSkipHit = word >> 31;
886 bool injVetoFlag = (word >> 30) & 0x1;
887 unsigned int PSBypass = (word >> 27) & 0x7;
888 unsigned int evtCtime = (word >> 16) & 0x7FF;
889 unsigned int evtRevo9Counter = word & 0xFFFF;
893 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
894 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
895 <<
"\tevtSkipHit = " << evtSkipHit
896 <<
", injVetoFlag = " << injVetoFlag
897 <<
", PSBypass = " << PSBypass
898 <<
", evtCtime = " << evtCtime
899 <<
", evtRevo9Counter = " << evtRevo9Counter);
901 word = array.getWord();
902 unsigned int evtAsicMask = word >> 16;
903 unsigned int evtEventQueueDepth = (word >> 8) & 0xFF;
904 unsigned int evtEventNumberByte = word & 0xFF;
906 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
907 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
908 <<
"\tevtAsicMask = " << evtAsicMask
909 <<
", evtEventQueueDepth = " << evtEventQueueDepth
910 <<
", evtEventNumberByte = " << evtEventNumberByte);
924 B2DEBUG(22,
"end of event header, start of hits:");
926 const int numWordsPerHit = 4 + evtExtra;
927 unsigned int numHitsFound = 0;
928 unsigned int numExpectedWaveforms = 0;
930 std::vector<TOPRawDigit*> digitsWithWaveform;
932 while (array.getRemainingWords() > numWordsPerHit
933 && array.getIndex() < evtNumWordsCore - 2) {
934 array.resetChecksum();
938 unsigned int hitCarrier = 0;
939 unsigned int hitAsic = 0;
940 unsigned int hitChannel = 0;
941 unsigned int hitWindow = 0;
942 unsigned int hitMagicHeader = 0;
943 unsigned int hitTFine = 0;
944 bool hitHasWaveform =
false;
945 bool hitIsOnHeap =
false;
946 unsigned int hitHeapWindow = 0;
947 bool hitIsOnHeapStraddle =
false;
948 unsigned int hitHeapWindowStraddle = 0;
949 bool hitIsWindowStraddle =
false;
950 short hitIntegral = 0;
953 if (dataFormat == TOP::RawDataType::c_ProductionDebug01) {
954 word = array.getWord();
955 hitCarrier = word >> 30;
956 hitAsic = (word >> 28) & 0x3;
957 hitChannel = (word >> 25) & 0x7;
958 hitWindow = (word >> 16) & 0x1FF;
959 hitMagicHeader = (word >> 12) & 0xF;
960 hitTFine = (word >> 8) & 0xF;
961 hitHasWaveform = (word >> 7) & 0x1;
962 hitIsOnHeap = (word >> 6) & 0x1;
963 hitHeapWindow = word & 0x3F;
966 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
967 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
968 <<
"\thitCarrier = " << hitCarrier
969 <<
", hitAsic = " << hitAsic
970 <<
", hitChannel = " << hitChannel
971 <<
", hitWindow = " << hitWindow
974 <<
", hitHasWaveform = " << hitHasWaveform
980 word = array.getWord();
982 hitIntegral = word & 0xFFFF;
983 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
984 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
985 <<
"\thitVPeak = " << hitVPeak
986 <<
", hitIntegral = " << hitIntegral);
988 }
else if (dataFormat == TOP::RawDataType::c_ProductionDebug02) {
989 word = array.getWord();
990 hitCarrier = word >> 30;
991 hitAsic = (word >> 28) & 0x3;
992 hitChannel = (word >> 25) & 0x7;
993 hitWindow = (word >> 16) & 0x1FF;
994 hitMagicHeader = (word >> 12) & 0xF;
995 hitTFine = (word >> 8) & 0xF;
996 hitHasWaveform = (word >> 7) & 0x1;
997 hitIsWindowStraddle = (word >> 6) & 0x1;
998 hitIntegral = word & 0x3F;
1001 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1002 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1003 <<
"\thitCarrier = " << hitCarrier
1004 <<
", hitAsic = " << hitAsic
1005 <<
", hitChannel = " << hitChannel
1006 <<
", hitWindow = " << hitWindow
1009 <<
", hitHasWaveform = " << hitHasWaveform
1010 <<
", hitIsWindowStraddle = " << hitHasWaveform
1011 <<
", hitIntegral = " << hitIntegral
1015 word = array.getWord();
1017 hitIsOnHeapStraddle = (word >> 15) & 0x1;
1018 hitHeapWindowStraddle = (word >> 8) & 0x7F;
1019 hitIsOnHeap = (word >> 7) & 0x1;
1020 hitHeapWindow = word & 0x1;
1022 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1023 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1024 <<
"\thitVPeak = " << hitVPeak
1025 <<
", hitIsOnHeapStraddle = " << hitIsOnHeapStraddle
1026 <<
", hitHeapWindowStraddle = " << hitHeapWindowStraddle
1027 <<
", hitIsOnHeap = " << hitIsOnHeap
1028 <<
", hitHeapWindow = " << hitHeapWindow);
1030 B2WARNING(
"TOPUnpacker: could not match data type inside unpackProdDebug()"
1031 <<
LogVar(
"evtType", evtType) <<
LogVar(
"evtVersion", evtVersion));
1032 return array.getRemainingWords();
1036 if (hitHasWaveform) {
1037 numExpectedWaveforms += 1;
1040 if (hitMagicHeader != 0xB) {
1041 B2WARNING(
"TOPUnpacker: hit header magic word mismatch. should be 0xB."
1042 <<
LogVar(
"Magic word", hitMagicHeader));
1043 return array.getRemainingWords();
1046 word = array.getWord();
1049 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1050 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1051 <<
"\thitVRise0 = " << hitVRise0
1052 <<
", hitVRise1 = " << hitVRise1);
1054 word = array.getWord();
1057 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1058 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1059 <<
"\thitVFall0 = " << hitVFall0
1060 <<
", hitVFall1 = " << hitVFall1);
1062 word = array.getWord();
1063 unsigned short hitSampleRise = (word >> 24);
1064 short hitDSampPeak = (word >> 20) & 0xF;
1065 short hitDSampFall = (word >> 16) & 0xF;
1066 unsigned short hitHeaderChecksum = word & 0xFFFF;
1067 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1068 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1069 <<
"\thitSampleRise = " << hitSampleRise
1070 <<
", hitDSampPeak = " << hitDSampPeak
1071 <<
", hitDSampFall = " << hitDSampFall
1072 <<
", hitheaderChecksum = " << hitHeaderChecksum
1073 <<
", checksum " << (array.validateChecksum() ?
"OK" :
"NOT OK"));
1075 if (!array.validateChecksum()) {
1076 B2WARNING(
"TOPUnpacker: hit checksum invalid.");
1077 return array.getRemainingWords();
1082 digit->setCarrierNumber(hitCarrier);
1083 digit->setASICNumber(hitAsic);
1084 digit->setASICChannel(hitChannel);
1085 digit->setASICWindow(hitWindow);
1086 digit->setLastWriteAddr(0);
1087 digit->setSampleRise(hitSampleRise);
1088 digit->setDeltaSamplePeak(hitDSampPeak);
1089 digit->setDeltaSampleFall(hitDSampFall);
1090 digit->setValueRise0(hitVRise0);
1091 digit->setValueRise1(hitVRise1);
1092 digit->setValuePeak(hitVPeak);
1093 digit->setValueFall0(hitVFall0);
1094 digit->setValueFall1(hitVFall1);
1095 digit->setTFine(hitTFine);
1096 digit->setIntegral(hitIntegral);
1097 digit->setRevo9Counter(evtRevo9Counter);
1098 digit->setPhase(evtPhase);
1101 if (hitHasWaveform) {
1102 digitsWithWaveform.push_back(digit);
1106 if (dataFormat == TOP::RawDataType::c_ProductionDebug01) {
1110 hitIsOnHeap ? 428 + hitHeapWindow : hitWindow,
1111 hitIsWindowStraddle);
1112 }
else if (dataFormat == TOP::RawDataType::c_ProductionDebug02) {
1116 hitIsOnHeap ? 428 + hitHeapWindow : hitWindow,
1117 hitIsWindowStraddle,
1119 hitIsOnHeapStraddle ? 428 + hitHeapWindowStraddle : hitWindow +
1124 for (
unsigned int i = 0; i < evtExtra; ++i) {
1125 word = array.getWord();
1126 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1127 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1128 <<
"\thit extra word " << i <<
" (" << evtExtra <<
")");
1133 digit->addRelationTo(hitDebug);
1139 word = array.getWord();
1140 unsigned int evtSdType = (word >> 24);
1141 unsigned int evtSdData = (word >> 12) & 0xFFF;
1142 unsigned int evtMagicFooter = (word >> 9) & 0x7;
1143 unsigned int evtNHits = word & 0x1FF;
1144 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1145 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1146 <<
"\tevtSdType = " << evtSdType
1147 <<
", evtSdData = " << evtSdData
1148 <<
", evtMagicFooter = " << evtMagicFooter
1149 <<
", evtNHits = " << evtNHits <<
" (" << numHitsFound <<
")");
1151 if (evtSdType != 0) {
1152 m_slowData.appendNew(evtScrodID, evtSdType, evtSdData);
1155 if (evtMagicFooter != 0x5) {
1156 B2WARNING(
"TOPUnpacker: event footer magic word mismatch. should be 0x5."
1157 <<
LogVar(
"Magic word", evtMagicFooter));
1158 return array.getRemainingWords();
1161 B2DEBUG(22,
"the rest:");
1163 unsigned int numParsedWaveforms = 0;
1164 while (array.peekWord() != 0x6c617374
1165 && array.getRemainingWords() > 0) {
1167 word = array.getWord();
1168 unsigned int wfNSamples = (word >> 16);
1169 unsigned int wfNWindows = (word >> 8) & 0x7;
1170 unsigned int wfCarrier = (word >> 5) & 0x3;
1171 unsigned int wfAsic = (word >> 3) & 0x3;
1172 unsigned int wfChannel = word & 0x7;
1175 const auto& mapper =
m_topgp->getChannelMapper();
1176 unsigned channel = mapper.getChannel(boardstack, wfCarrier, wfAsic, wfChannel);
1177 int pixelID = mapper.getPixelID(channel);
1179 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1180 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1181 <<
"\twfNSamples = " << wfNSamples
1182 <<
", wfNWindows = " << wfNWindows
1183 <<
", wfCarrier = " << wfCarrier
1184 <<
", wfAsic = " << wfAsic
1185 <<
", wfChannel " << wfChannel);
1187 if (wfNSamples != 32 && wfNSamples != 16) {
1188 B2WARNING(
"TOPUnpacker: suspicious value for wfNSamples."
1189 <<
LogVar(
"wfNSamples", wfNSamples));
1190 return array.getRemainingWords();
1193 word = array.getWord();
1194 unsigned int wfStartSample = (word >> 25) & 0x3F;
1195 unsigned int wfWindowLogic = (word >> 16) & 0x1FF;
1196 unsigned int wfEventNumber = (word >> 9) & 0x7F;
1197 unsigned int wfWindowPhysical = word & 0x1FF;
1199 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1200 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1201 <<
"\twfStartSample = " << wfStartSample
1202 <<
", wfWindowLogic = " << wfWindowLogic
1203 <<
", wfEventNumber = " << wfEventNumber
1204 <<
", wfWindowPhysical = " << wfWindowPhysical);
1206 std::vector<short> wfSamples;
1208 for (
unsigned int i = 0; i < wfNSamples / 2; ++i) {
1209 short wfSampleLast = 0;
1210 short wfSampleFirst = 0;
1213 word = array.getWord();
1214 if (pedestalSubtracted) {
1215 wfSampleLast = (word >> 16);
1216 wfSampleFirst = word & 0xFFFF;
1218 wfSampleLast = (word >> 16) & 0xFFF;
1219 wfSampleFirst = word & 0xFFF;
1223 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1224 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1225 <<
"\twfSample" << 2 * i + 1 <<
" = " << wfSampleLast
1226 <<
", wfSample" << 2 * i <<
" = " << wfSampleFirst);
1228 wfSamples.push_back(wfSampleFirst);
1229 wfSamples.push_back(wfSampleLast);
1233 auto* waveform =
m_waveforms.appendNew(moduleID, pixelID, channel, evtScrodID,
1234 wfWindowLogic, wfStartSample, wfSamples);
1235 waveform->setPedestalSubtractedFlag(pedestalSubtracted);
1236 waveform->setPhysicalWindow(wfWindowPhysical);
1237 if (numParsedWaveforms < digitsWithWaveform.size()) {
1238 const auto* digit = digitsWithWaveform[numParsedWaveforms];
1239 if (digit->getScrodChannel() == channel % 128) {
1240 digit->addRelationTo(waveform);
1242 B2WARNING(
"TOPUnpacker: hit and its waveform have different channel number."
1243 <<
LogVar(
"channel (hit)", digit->getScrodChannel())
1244 <<
LogVar(
"channel (waveform)", channel % 128));
1247 numParsedWaveforms += 1;
1251 if (numExpectedWaveforms != numParsedWaveforms) {
1252 B2WARNING(
"TOPUnpacker: number of expected and parsed waveforms does not match."
1253 <<
LogVar(
"expected", numExpectedWaveforms)
1254 <<
LogVar(
"parsed", numParsedWaveforms));
1257 return array.getRemainingWords();