420 bool pedestalSubtracted)
423 B2DEBUG(22,
"Unpacking InterimFEVer01 to TOPRawDigits and TOPRawWaveforms, "
424 "dataSize = " << bufferSize);
431 map<unsigned short, int> evtNumCounter;
432 std::vector<unsigned short> channelCounter(128, 0);
434 unsigned word = array.getWord();
435 unsigned short scrodID = word & 0x0FFF;
438 word = array.getWord();
441 while (array.getRemainingWords() > 0) {
443 unsigned header = array.getWord();
445 if ((header & 0xFF) == 0xBE) {
448 unsigned short scrodID_SSFE;
449 unsigned short carrier_SSFE;
450 unsigned short asic_SSFE;
451 unsigned short channel_SSFE;
452 unsigned short evtNum_SSFE;
454 evtNum_SSFE = (header >> 8) & 0xFF;
455 scrodID_SSFE = (header >> 16) & 0x7F;
456 channel_SSFE = (header >> 24) & 0x07;
457 asic_SSFE = (header >> 27) & 0x03;
458 carrier_SSFE = (header >> 29) & 0x03;
460 const auto* feemap =
m_topgp->getFrontEndMapper().getMap(scrodID_SSFE);
462 moduleID = feemap->getModuleID();
463 boardstack = feemap->getBoardstackNumber();
465 B2ERROR(
"TOPUnpacker: no front-end map available."
466 <<
LogVar(
"SCROD ID", scrodID_SSFE));
470 if (scrodID_SSFE != scrodID) {
471 B2ERROR(
"TOPUnpacker: corrupted data - "
472 <<
"different scrodID's in HLSB and super short FE header."
473 <<
LogVar(
"SCROD", scrodID_SSFE)
474 <<
LogVar(
"slot", moduleID)
475 <<
LogVar(
"BS", boardstack));
476 B2DEBUG(21,
"Different scrodID's in HLSB and FE header: " << scrodID <<
" " << scrodID_SSFE <<
" word = 0x" << std::hex << word);
478 return array.getRemainingWords();
481 B2DEBUG(21, scrodID_SSFE <<
"\t" << carrier_SSFE <<
"\t" << asic_SSFE <<
"\t" << channel_SSFE <<
"\t" << evtNum_SSFE);
483 int channelID = carrier_SSFE * 32 + asic_SSFE * 8 + channel_SSFE;
484 channelCounter[channelID] += 1;
485 evtNumCounter[evtNum_SSFE] += 1;
487 info->incrementFEHeadersCount();
488 info->incrementEmptyFEHeadersCount();
493 if (header != 0xaaaa0104 and header != 0xaaaa0103 and header != 0xaaaa0100) {
494 B2ERROR(
"TOPUnpacker: corrupted data - invalid FE header word");
495 B2DEBUG(21,
"Invalid FE header word: " << std::hex << header <<
" 0b" << std::bitset<32>(header));
496 B2DEBUG(21,
"SCROD ID: " << scrodID <<
" " << std::hex << scrodID);
499 return array.getRemainingWords();
503 word = array.getWord();
504 unsigned short scrodID_FE = word >> 25;
505 unsigned short convertedAddr = (word >> 16) & 0x1FF;
506 unsigned short evtNum_numWin_trigPat_FEheader = word & 0xFFFF;
507 unsigned short evtNum_FEheader = evtNum_numWin_trigPat_FEheader & 0xFF;
508 evtNumCounter[evtNum_FEheader] += 1;
510 if (scrodID_FE != scrodID) {
511 B2ERROR(
"TOPUnpacker: different scrodID's in HLSB and FE header."
512 <<
LogVar(
"scrodID (HSLB)", scrodID)
513 <<
LogVar(
"scrodID (FE)", scrodID_FE));
516 return array.getRemainingWords();
519 word = array.getWord();
521 unsigned lastWrAddr = (word & 0x0FF) << 1;
523 unsigned short asicChannelFE = (word >> 8) & 0x07;
524 unsigned short asicFE = (word >> 12) & 0x03;
525 unsigned short carrierFE = (word >> 14) & 0x03;
526 unsigned short channelID = carrierFE * 32 + asicFE * 8 + asicChannelFE;
529 B2DEBUG(21, scrodID_FE <<
"\t" << carrierFE <<
"\t" << asicFE <<
"\t" << asicChannelFE <<
"\t" << evtNum_FEheader);
531 channelCounter[channelID] += 1;
533 std::vector<TOPRawDigit*> digits;
535 if (header != 0xaaaa0104) {
538 word = array.getWord();
539 short samplePeak_p = word & 0xFFFF;
540 short valuePeak_p = (word >> 16) & 0xFFFF;
542 word = array.getWord();
543 short sampleRise_p = word & 0xFFFF;
544 short valueRise0_p = (word >> 16) & 0xFFFF;
546 word = array.getWord();
547 short valueRise1_p = word & 0xFFFF;
548 short sampleFall_p = (word >> 16) & 0xFFFF;
550 word = array.getWord();
551 short valueFall0_p = word & 0xFFFF;
552 short valueFall1_p = (word >> 16) & 0xFFFF;
554 word = array.getWord();
555 short integral_p = word & 0xFFFF;
562 word = array.getWord();
563 short samplePeak_n = word & 0xFFFF;
564 short valuePeak_n = (word >> 16) & 0xFFFF;
581 word = array.getWord();
582 short integral_n = word & 0xFFFF;
583 short qualityFlags_n = (word >> 16) & 0xFFFF;
585 if (abs(valuePeak_p) != 9999) {
587 digit->setCarrierNumber(carrierFE);
588 digit->setASICNumber(asicFE);
589 digit->setASICChannel(asicChannelFE);
590 digit->setASICWindow(convertedAddr);
591 digit->setLastWriteAddr(lastWrAddr);
592 digit->setSampleRise(sampleRise_p);
593 digit->setDeltaSamplePeak(samplePeak_p - sampleRise_p);
594 digit->setDeltaSampleFall(sampleFall_p - sampleRise_p);
595 digit->setValueRise0(valueRise0_p);
596 digit->setValueRise1(valueRise1_p);
597 digit->setValuePeak(valuePeak_p);
598 digit->setValueFall0(valueFall0_p);
599 digit->setValueFall1(valueFall1_p);
600 digit->setIntegral(integral_p);
602 digit->addRelationTo(info);
603 digits.push_back(digit);
605 if (valuePeak_p < 150) {
607 tlpfResult->setBackgroundOffset(samplePeak_n);
608 tlpfResult->setAmplitude(valuePeak_n);
609 tlpfResult->setChisquare(qualityFlags_n);
610 tlpfResult->setRisingEdgeAndConvert(integral_n);
611 digit->addRelationTo(tlpfResult);
637 word = array.getWord();
638 if (word != 0x7473616c) {
648 info->incrementFEHeadersCount();
649 if (digits.empty()) info->incrementEmptyFEHeadersCount();
651 if (header != 0xaaaa0103)
continue;
654 word = array.getWord();
655 unsigned long evtNum_numWaves_refWin_WFheader = word;
656 unsigned short evtNum_WFheader = (evtNum_numWaves_refWin_WFheader >> 24) & 0xFF;
658 if (evtNum_WFheader != evtNum_FEheader) {
659 B2ERROR(
"TOPUnpacker: different carrier event number in WF and FE header."
660 <<
LogVar(
"Event number (FE header)", evtNum_FEheader)
661 <<
LogVar(
"Event number (WF header)", evtNum_WFheader));
666 word = array.getWord();
668 unsigned short carrier = (word >> 14) & 0x03;
669 unsigned short asic = (word >> 12) & 0x03;
671 unsigned short window = word & 0x1FF;
674 if (carrier != carrierFE) {
675 B2ERROR(
"TOPUnpacker: different carrier numbers in FE and WF header");
676 B2DEBUG(21,
"Different carrier numbers in FE and WF header: "
677 << carrierFE <<
" " << carrier);
680 if (asic != asicFE) {
681 B2ERROR(
"TOPUnpacker: different ASIC numbers in FE and WF header");
682 B2DEBUG(21,
"Different ASIC numbers in FE and WF header: "
683 << asicFE <<
" " << asic);
687 B2ERROR(
"TOPUnpacker: different ASIC channel numbers in FE and WF header");
688 B2DEBUG(21,
"Different ASIC channel numbers in FE and WF header: "
692 if (window != convertedAddr) {
693 B2ERROR(
"TOPUnpacker: different window numbers in FE and WF header");
694 B2DEBUG(21,
"Different window numbers in FE and WF header: "
695 << convertedAddr <<
" " << window);
701 std::vector<unsigned short> windows;
702 windows.push_back(window);
704 word = array.getWord();
705 windows.push_back(word & 0x1FF);
707 word = array.getWord();
708 windows.push_back(word & 0x1FF);
710 word = array.getWord();
711 windows.push_back(word & 0x1FF);
713 int numWords = 4 * 32;
714 if (array.getRemainingWords() < numWords) {
715 B2ERROR(
"TOPUnpacker: too few words for waveform data."
716 <<
LogVar(
"needed", numWords)
717 <<
LogVar(
"available", array.getRemainingWords()));
719 return array.getRemainingWords();
723 std::vector<short> adcData;
724 for (
int i = 0; i < numWords; i++) {
725 word = array.getWord();
726 adcData.push_back(word & 0xFFFF);
727 adcData.push_back((word >> 16) & 0xFFFF);
734 const auto* feemap =
m_topgp->getFrontEndMapper().getMap(scrodID);
736 moduleID = feemap->getModuleID();
737 boardstack = feemap->getBoardstackNumber();
739 B2ERROR(
"TOPUnpacker: no front-end map available."
740 <<
LogVar(
"SCROD ID", scrodID));
745 const auto& mapper =
m_topgp->getChannelMapper();
746 unsigned channel = mapper.getChannel(boardstack, carrier, asic,
asicChannel);
747 int pixelID = mapper.getPixelID(channel);
750 auto* waveform =
m_waveforms.appendNew(moduleID, pixelID, channel, scrodID,
752 waveform->setLastWriteAddr(lastWrAddr);
753 waveform->setStorageWindows(windows);
754 waveform->setPedestalSubtractedFlag(pedestalSubtracted);
755 waveform->addRelationTo(info);
756 info->incrementWaveformsCount();
759 for (
auto& digit : digits) digit->addRelationTo(waveform);
763 if (evtNumCounter.size() != 1) {
764 B2ERROR(
"TOPUnpacker: Possible frame shift detected "
765 <<
"(More than one unique carrier event number in this readout event)."
766 <<
LogVar(
"SCROD", scrodID)
767 <<
LogVar(
"slot", moduleID)
768 <<
LogVar(
"BS", boardstack));
773 string evtNumOutputString;
774 evtNumOutputString +=
"Carrier event numbers and their counts for SCROD ID " + std::to_string(scrodID) +
":\n";
775 for (
auto const& it : evtNumCounter) {
777 evtNumOutputString += std::to_string(it.first) +
":\t" + std::to_string(it.second) +
"\n";
779 evtNumOutputString +=
"Total:\t" + std::to_string(nASICs);
780 B2DEBUG(21, evtNumOutputString);
783 int nChannelsDiff = 0;
785 string channelOutputString;
786 channelOutputString +=
"Detected channels and their counts for SCROD ID (channels with count == 1 are omitted)" + std::to_string(
790 for (
auto const& it : channelCounter) {
796 int channelID = channelIndex;
797 int carrier = channelID / 32;
798 int asic = (channelID % 32) / 8;
799 int chn = channelID % 8;
802 channelOutputString +=
"carrier: " + std::to_string(carrier) +
" asic: " + std::to_string(asic) +
" chn: " + std::to_string(
803 chn) +
" occurrence: " + std::to_string(it) +
"\n";
804 B2WARNING(
"TOPUnpacker: interim FE - ASIC channel seen more than once"
805 <<
LogVar(
"ScrodID", scrodID)
806 <<
LogVar(
"carrier", carrier)
809 <<
LogVar(
"times seen", it));
816 channelOutputString +=
"Total:\t" + std::to_string(nChannels) +
" " + std::to_string(nChannelsDiff);
817 B2DEBUG(21, channelOutputString);
819 return array.getRemainingWords();
826 bool pedestalSubtracted,
int expNo)
829 B2DEBUG(22,
"Unpacking Production firmware debug data format to TOPRawDigits "
830 "dataSize = " << bufferSize);
835 word = array.getWord();
836 unsigned int evtType = word >> 24;
837 unsigned int evtVersion = (word >> 16) & 0xFF;
838 unsigned int evtMagicHeader = (word >> 12) & 0xF;
839 unsigned int evtScrodID = word & 0xFFF;
844 const auto* feemap =
m_topgp->getFrontEndMapper().getMap(evtScrodID);
846 moduleID = feemap->getModuleID();
847 boardstack = feemap->getBoardstackNumber();
849 B2WARNING(
"TOPUnpacker: no front-end map available."
850 <<
LogVar(
"SCROD ID", evtScrodID));
854 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
855 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
856 <<
"\tevtType = " << evtType
857 <<
", evtVersion = " << evtVersion
858 <<
", evtMagicHeader = " << evtMagicHeader
859 <<
", evtScrodID = " << evtScrodID);
861 if (evtMagicHeader != 0xA) {
862 B2WARNING(
"TOPUnpacker: event header magic word mismatch. should be 0xA."
863 <<
LogVar(
"Magic word", evtMagicHeader));
864 return array.getRemainingWords();
867 word = array.getWord();
868 unsigned int evtExtra = word >> 29;
869 unsigned int evtNumWordsBonus = (word >> 16) & 0x1FFF;
870 unsigned int evtPhase = (word >> 12) & 0xF;
871 unsigned int evtNumWordsCore = word & 0xFFF;
873 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
874 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
875 <<
"\tevtExtra = " << evtExtra
876 <<
", evtNumWordsBonus = " << evtNumWordsBonus
877 <<
", evtPhase = " << evtPhase
878 <<
", numWordsCore = " << evtNumWordsCore);
880 word = array.getWord();
881 bool evtSkipHit = word >> 31;
882 bool injVetoFlag = (word >> 30) & 0x1;
883 unsigned int PSBypass = (word >> 27) & 0x7;
884 unsigned int evtCtime = (word >> 16) & 0x7FF;
885 unsigned int evtRevo9Counter = word & 0xFFFF;
889 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
890 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
891 <<
"\tevtSkipHit = " << evtSkipHit
892 <<
", injVetoFlag = " << injVetoFlag
893 <<
", PSBypass = " << PSBypass
894 <<
", evtCtime = " << evtCtime
895 <<
", evtRevo9Counter = " << evtRevo9Counter);
897 word = array.getWord();
898 unsigned int evtAsicMask = word >> 16;
899 unsigned int evtEventQueueDepth = (word >> 8) & 0xFF;
900 unsigned int evtEventNumberByte = word & 0xFF;
902 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
903 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
904 <<
"\tevtAsicMask = " << evtAsicMask
905 <<
", evtEventQueueDepth = " << evtEventQueueDepth
906 <<
", evtEventNumberByte = " << evtEventNumberByte);
920 B2DEBUG(22,
"end of event header, start of hits:");
922 const int numWordsPerHit = 4 + evtExtra;
923 unsigned int numHitsFound = 0;
924 unsigned int numExpectedWaveforms = 0;
926 std::vector<TOPRawDigit*> digitsWithWaveform;
928 while (array.getRemainingWords() > numWordsPerHit
929 && array.getIndex() < evtNumWordsCore - 2) {
930 array.resetChecksum();
934 unsigned int hitCarrier = 0;
935 unsigned int hitAsic = 0;
936 unsigned int hitChannel = 0;
937 unsigned int hitWindow = 0;
938 unsigned int hitMagicHeader = 0;
939 unsigned int hitTFine = 0;
940 bool hitHasWaveform =
false;
941 bool hitIsOnHeap =
false;
942 unsigned int hitHeapWindow = 0;
943 bool hitIsOnHeapStraddle =
false;
944 unsigned int hitHeapWindowStraddle = 0;
945 bool hitIsWindowStraddle =
false;
946 short hitIntegral = 0;
949 if (dataFormat == TOP::RawDataType::c_ProductionDebug01) {
950 word = array.getWord();
951 hitCarrier = word >> 30;
952 hitAsic = (word >> 28) & 0x3;
953 hitChannel = (word >> 25) & 0x7;
954 hitWindow = (word >> 16) & 0x1FF;
955 hitMagicHeader = (word >> 12) & 0xF;
956 hitTFine = (word >> 8) & 0xF;
957 hitHasWaveform = (word >> 7) & 0x1;
958 hitIsOnHeap = (word >> 6) & 0x1;
959 hitHeapWindow = word & 0x3F;
962 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
963 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
964 <<
"\thitCarrier = " << hitCarrier
965 <<
", hitAsic = " << hitAsic
966 <<
", hitChannel = " << hitChannel
967 <<
", hitWindow = " << hitWindow
970 <<
", hitHasWaveform = " << hitHasWaveform
976 word = array.getWord();
978 hitIntegral = word & 0xFFFF;
979 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
980 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
981 <<
"\thitVPeak = " << hitVPeak
982 <<
", hitIntegral = " << hitIntegral);
984 }
else if (dataFormat == TOP::RawDataType::c_ProductionDebug02) {
985 word = array.getWord();
986 hitCarrier = word >> 30;
987 hitAsic = (word >> 28) & 0x3;
988 hitChannel = (word >> 25) & 0x7;
989 hitWindow = (word >> 16) & 0x1FF;
990 hitMagicHeader = (word >> 12) & 0xF;
991 hitTFine = (word >> 8) & 0xF;
992 hitHasWaveform = (word >> 7) & 0x1;
993 hitIsWindowStraddle = (word >> 6) & 0x1;
994 hitIntegral = word & 0x3F;
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 <<
"\thitCarrier = " << hitCarrier
1000 <<
", hitAsic = " << hitAsic
1001 <<
", hitChannel = " << hitChannel
1002 <<
", hitWindow = " << hitWindow
1005 <<
", hitHasWaveform = " << hitHasWaveform
1006 <<
", hitIsWindowStraddle = " << hitHasWaveform
1007 <<
", hitIntegral = " << hitIntegral
1011 word = array.getWord();
1013 hitIsOnHeapStraddle = (word >> 15) & 0x1;
1014 hitHeapWindowStraddle = (word >> 8) & 0x7F;
1015 hitIsOnHeap = (word >> 7) & 0x1;
1016 hitHeapWindow = word & 0x1;
1018 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1019 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1020 <<
"\thitVPeak = " << hitVPeak
1021 <<
", hitIsOnHeapStraddle = " << hitIsOnHeapStraddle
1022 <<
", hitHeapWindowStraddle = " << hitHeapWindowStraddle
1023 <<
", hitIsOnHeap = " << hitIsOnHeap
1024 <<
", hitHeapWindow = " << hitHeapWindow);
1026 B2WARNING(
"TOPUnpacker: could not match data type inside unpackProdDebug()"
1027 <<
LogVar(
"evtType", evtType) <<
LogVar(
"evtVersion", evtVersion));
1028 return array.getRemainingWords();
1032 if (hitHasWaveform) {
1033 numExpectedWaveforms += 1;
1036 if (hitMagicHeader != 0xB) {
1037 B2WARNING(
"TOPUnpacker: hit header magic word mismatch. should be 0xB."
1038 <<
LogVar(
"Magic word", hitMagicHeader));
1039 return array.getRemainingWords();
1042 word = array.getWord();
1045 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1046 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1047 <<
"\thitVRise0 = " << hitVRise0
1048 <<
", hitVRise1 = " << hitVRise1);
1050 word = array.getWord();
1053 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1054 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1055 <<
"\thitVFall0 = " << hitVFall0
1056 <<
", hitVFall1 = " << hitVFall1);
1058 word = array.getWord();
1059 unsigned short hitSampleRise = (word >> 24);
1060 short hitDSampPeak = (word >> 20) & 0xF;
1061 short hitDSampFall = (word >> 16) & 0xF;
1062 unsigned short hitHeaderChecksum = word & 0xFFFF;
1063 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1064 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1065 <<
"\thitSampleRise = " << hitSampleRise
1066 <<
", hitDSampPeak = " << hitDSampPeak
1067 <<
", hitDSampFall = " << hitDSampFall
1068 <<
", hitheaderChecksum = " << hitHeaderChecksum
1069 <<
", checksum " << (array.validateChecksum() ?
"OK" :
"NOT OK"));
1071 if (!array.validateChecksum()) {
1072 B2WARNING(
"TOPUnpacker: hit checksum invalid.");
1073 return array.getRemainingWords();
1078 digit->setCarrierNumber(hitCarrier);
1079 digit->setASICNumber(hitAsic);
1080 digit->setASICChannel(hitChannel);
1081 digit->setASICWindow(hitWindow);
1082 digit->setLastWriteAddr(0);
1083 digit->setSampleRise(hitSampleRise);
1084 digit->setDeltaSamplePeak(hitDSampPeak);
1085 digit->setDeltaSampleFall(hitDSampFall);
1086 digit->setValueRise0(hitVRise0);
1087 digit->setValueRise1(hitVRise1);
1088 digit->setValuePeak(hitVPeak);
1089 digit->setValueFall0(hitVFall0);
1090 digit->setValueFall1(hitVFall1);
1091 digit->setTFine(hitTFine);
1092 digit->setIntegral(hitIntegral);
1093 digit->setRevo9Counter(evtRevo9Counter);
1094 digit->setPhase(evtPhase);
1097 if (hitHasWaveform) {
1098 digitsWithWaveform.push_back(digit);
1102 if (dataFormat == TOP::RawDataType::c_ProductionDebug01) {
1106 hitIsOnHeap ? 428 + hitHeapWindow : hitWindow,
1107 hitIsWindowStraddle);
1108 }
else if (dataFormat == TOP::RawDataType::c_ProductionDebug02) {
1112 hitIsOnHeap ? 428 + hitHeapWindow : hitWindow,
1113 hitIsWindowStraddle,
1115 hitIsOnHeapStraddle ? 428 + hitHeapWindowStraddle : hitWindow +
1120 for (
unsigned int i = 0; i < evtExtra; ++i) {
1121 word = array.getWord();
1122 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1123 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1124 <<
"\thit extra word " << i <<
" (" << evtExtra <<
")");
1129 digit->addRelationTo(hitDebug);
1135 word = array.getWord();
1136 unsigned int evtSdType = (word >> 24);
1137 unsigned int evtSdData = (word >> 12) & 0xFFF;
1138 unsigned int evtMagicFooter = (word >> 9) & 0x7;
1139 unsigned int evtNHits = word & 0x1FF;
1140 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1141 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1142 <<
"\tevtSdType = " << evtSdType
1143 <<
", evtSdData = " << evtSdData
1144 <<
", evtMagicFooter = " << evtMagicFooter
1145 <<
", evtNHits = " << evtNHits <<
" (" << numHitsFound <<
")");
1147 if (evtSdType != 0) {
1148 m_slowData.appendNew(evtScrodID, evtSdType, evtSdData);
1151 if (evtMagicFooter != 0x5) {
1152 B2WARNING(
"TOPUnpacker: event footer magic word mismatch. should be 0x5."
1153 <<
LogVar(
"Magic word", evtMagicFooter));
1154 return array.getRemainingWords();
1157 B2DEBUG(22,
"the rest:");
1159 unsigned int numParsedWaveforms = 0;
1160 while (array.peekWord() != 0x6c617374
1161 && array.getRemainingWords() > 0) {
1163 word = array.getWord();
1164 unsigned int wfNSamples = (word >> 16);
1165 unsigned int wfNWindows = (word >> 8) & 0x7;
1166 unsigned int wfCarrier = (word >> 5) & 0x3;
1167 unsigned int wfAsic = (word >> 3) & 0x3;
1168 unsigned int wfChannel = word & 0x7;
1171 const auto& mapper =
m_topgp->getChannelMapper();
1172 unsigned channel = mapper.getChannel(boardstack, wfCarrier, wfAsic, wfChannel);
1173 int pixelID = mapper.getPixelID(channel);
1175 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1176 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1177 <<
"\twfNSamples = " << wfNSamples
1178 <<
", wfNWindows = " << wfNWindows
1179 <<
", wfCarrier = " << wfCarrier
1180 <<
", wfAsic = " << wfAsic
1181 <<
", wfChannel " << wfChannel);
1183 if (wfNSamples != 32 && wfNSamples != 16) {
1184 B2WARNING(
"TOPUnpacker: suspicious value for wfNSamples."
1185 <<
LogVar(
"wfNSamples", wfNSamples));
1186 return array.getRemainingWords();
1189 word = array.getWord();
1190 unsigned int wfStartSample = (word >> 25) & 0x3F;
1191 unsigned int wfWindowLogic = (word >> 16) & 0x1FF;
1192 unsigned int wfEventNumber = (word >> 9) & 0x7F;
1193 unsigned int wfWindowPhysical = word & 0x1FF;
1195 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1196 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1197 <<
"\twfStartSample = " << wfStartSample
1198 <<
", wfWindowLogic = " << wfWindowLogic
1199 <<
", wfEventNumber = " << wfEventNumber
1200 <<
", wfWindowPhysical = " << wfWindowPhysical);
1202 std::vector<short> wfSamples;
1204 for (
unsigned int i = 0; i < wfNSamples / 2; ++i) {
1205 short wfSampleLast = 0;
1206 short wfSampleFirst = 0;
1209 word = array.getWord();
1210 if (pedestalSubtracted) {
1211 wfSampleLast = (word >> 16);
1212 wfSampleFirst = word & 0xFFFF;
1214 wfSampleLast = (word >> 16) & 0xFFF;
1215 wfSampleFirst = word & 0xFFF;
1219 B2DEBUG(22, std::dec << array.getIndex() <<
":\t" << setfill(
'0') << setw(4) << std::hex <<
1220 (word >> 16) <<
" " << setfill(
'0') << setw(4) << (word & 0xFFFF) << std::dec
1221 <<
"\twfSample" << 2 * i + 1 <<
" = " << wfSampleLast
1222 <<
", wfSample" << 2 * i <<
" = " << wfSampleFirst);
1224 wfSamples.push_back(wfSampleFirst);
1225 wfSamples.push_back(wfSampleLast);
1229 auto* waveform =
m_waveforms.appendNew(moduleID, pixelID, channel, evtScrodID,
1230 wfWindowLogic, wfStartSample, wfSamples);
1231 waveform->setPedestalSubtractedFlag(pedestalSubtracted);
1232 waveform->setPhysicalWindow(wfWindowPhysical);
1233 if (numParsedWaveforms < digitsWithWaveform.size()) {
1234 const auto* digit = digitsWithWaveform[numParsedWaveforms];
1235 if (digit->getScrodChannel() == channel % 128) {
1236 digit->addRelationTo(waveform);
1238 B2WARNING(
"TOPUnpacker: hit and its waveform have different channel number."
1239 <<
LogVar(
"channel (hit)", digit->getScrodChannel())
1240 <<
LogVar(
"channel (waveform)", channel % 128));
1243 numParsedWaveforms += 1;
1247 if (numExpectedWaveforms != numParsedWaveforms) {
1248 B2WARNING(
"TOPUnpacker: number of expected and parsed waveforms does not match."
1249 <<
LogVar(
"expected", numExpectedWaveforms)
1250 <<
LogVar(
"parsed", numParsedWaveforms));
1253 return array.getRemainingWords();