10#include <top/modules/TOPUnpacker/TOPUnpackerModule.h>
13#include <top/RawDataTypes.h>
16#include <framework/datastore/DataStore.h>
17#include <framework/datastore/StoreArray.h>
18#include <framework/datastore/StoreObjPtr.h>
21#include <framework/logging/Logger.h>
24#include <framework/dataobjects/EventMetaData.h>
59 "name of RawTOP store array",
string(
""));
61 "name of TOPDigit store array",
string(
""));
63 "name of TOP(Raw/Production)Waveform store array",
string(
""));
65 "name of TOPRawDigit store array",
string(
""));
67 "name of TOPTemplateFitResult",
string(
""));
70 "data format as defined in top/include/RawDataTypes.h, 0 = auto detect", 0);
72 "if true, make relations to TOPProductionHitDebugs (production debug data format only)",
true);
74 "error messages suppression factor (0 = no suppression)", (
unsigned) 1000);
109 if (mapSize == 0) B2ERROR(
"TOPUnpacker: No front-end mapping available for TOP");
140 for (
int finesse = 0; finesse < raw.GetMaxNumOfCh(0); finesse++) {
141 const int* buffer = raw.GetDetectorBuffer(0, finesse);
142 int bufferSize = raw.GetDetectorNwords(0, finesse);
143 if (bufferSize < 1)
continue;
148 if (dataFormat == 0) {
150 unsigned word = array.
getWord();
151 dataFormat = (word >> 16);
152 bool isKnownDataFormat =
false;
153 for (
auto& t : TOP::membersRawDataType) {
154 if (
static_cast<int>(t) == dataFormat) {
155 isKnownDataFormat =
true;
160 if (!isKnownDataFormat) {
161 if (evtMetaData->getExperiment() == 1) {
166 B2DEBUG(22,
"Assuming interim FW data format");
170 B2WARNING(
"TOPUnpacker: Could not establish data format.");
177 switch (dataFormat) {
178 case static_cast<int>(TOP::RawDataType::c_Type0Ver16):
181 case static_cast<int>(TOP::RawDataType::c_Type2Ver1):
184 case static_cast<int>(TOP::RawDataType::c_Type3Ver1):
187 case static_cast<int>(TOP::RawDataType::c_Draft):
190 case static_cast<int>(TOP::RawDataType::c_ProductionDebug01):
191 err =
unpackProdDebug(buffer, bufferSize, TOP::RawDataType::c_ProductionDebug01,
true);
193 case static_cast<int>(TOP::RawDataType::c_ProductionDebug02):
194 err =
unpackProdDebug(buffer, bufferSize, TOP::RawDataType::c_ProductionDebug02,
true);
199 B2ERROR(
"TOPUnpacker: unknown data format, " <<
getFrontEndName(raw, finesse)
200 <<
LogVar(
"Type", (dataFormat >> 8))
201 <<
LogVar(
"Version", (dataFormat & 0xFF)));
208 B2ERROR(
"TOPUnpacker: error in unpacking data from " <<
getFrontEndName(raw, finesse)
209 <<
LogVar(
"words unused", err));
222 if (raw.GetMaxNumOfCh(0) <= 4) {
223 int copper = ((raw.GetNodeID(0) >> 24) * 1000 + (raw.GetNodeID(0) & 0x3FF));
224 name =
"frontend cpr" + std::to_string(copper) + char(
'a' + finesse);
226 int slot = (raw.GetNodeID(0) & 0xF) * 8 - 7 + finesse / 4;
227 name = (slot < 10) ?
"boardstack s0" :
"boardstack s";
228 name += std::to_string(slot) + char(
'a' + finesse % 4);
246 B2DEBUG(22,
"Unpacking ProductionDraft to TOPDigits, dataSize = " << bufferSize);
248 unsigned short scrodID = buffer[0] & 0xFFFF;
251 B2ERROR(
"TOPUnpacker: no front-end map available."
252 <<
LogVar(
"SCROD ID", scrodID));
255 int moduleID = feemap->getModuleID();
256 int boardstack = feemap->getBoardstackNumber();
261 int sampleDivisions = 0x1 << subBits;
263 for (
int i = 1; i < bufferSize; i++) {
264 int word = buffer[i];
265 int tdc = word & 0xFFFF;
266 double rawTime = double(tdc) / sampleDivisions;
267 unsigned chan = ((word >> 16) & 0x7F) + boardstack * 128;
268 unsigned flags = (word >> 24) & 0xFF;
269 int pixelID = mapper.getPixelID(chan);
270 auto* digit =
m_digits.appendNew(moduleID, pixelID, rawTime);
271 digit->setTime(geo->getNominalTDC().getTime(tdc));
272 digit->setChannel(chan);
282 B2DEBUG(22,
"Unpacking Type0Ver16 to TOPRawDigits, dataSize = " << bufferSize);
285 unsigned word = array.
getWord();
286 unsigned short scrodID = word & 0x0FFF;
289 int Nhits = last & 0x01FF;
290 if (bufferSize != 5 * Nhits + 2) {
291 B2ERROR(
"TOPUnpacker: corrupted data (feature-extraction format)."
292 <<
LogVar(
"SCROD ID", scrodID));
296 short SDType = last >> 24;
297 short SDValue = (last >> 12) & 0x0FFF;
298 if (SDType != 0)
m_slowData.appendNew(scrodID, SDType, SDValue);
300 unsigned short errorFlags = 0;
304 for (
int hit = 0; hit < Nhits; hit++) {
308 digit->setCarrierNumber((word >> 30) & 0x03);
309 digit->setASICNumber((word >> 28) & 0x03);
310 digit->setASICChannel((word >> 25) & 0x07);
311 digit->setASICWindow((word >> 16) & 0x1FF);
312 digit->setTFine((word >> 8) & 0x0F);
313 auto flags = errorFlags;
315 unsigned short checkSum =
sumShorts(word);
319 digit->setIntegral(word & 0xFFFF);
333 digit->setSampleRise(word >> 24);
334 digit->setDeltaSamplePeak((word >> 20) & 0x0F);
335 digit->setDeltaSampleFall((word >> 16) & 0x0F);
339 digit->setErrorFlags(flags);
347 B2DEBUG(22,
"Checking whether buffer unpacks as InterimFEVer01, dataSize = " << bufferSize);
349 DataArray array(buffer, bufferSize, swapBytes);
354 unsigned header = array.
getWord();
355 if ((header & 0xFF) == 0xBE) {
359 if (header != 0xaaaa0104 and header != 0xaaaa0103 and header != 0xaaaa0100) {
367 if (header != 0xaaaa0104) {
383 unsigned magicWord = array.
getWord();
384 if (magicWord != 0x7473616c) {
388 if (header != 0xaaaa0103)
continue;
401 int numWords = 4 * 32;
406 for (
int i = 0; i < numWords; i++) {
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;
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;
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);
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);
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));
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) {
535 short samplePeak_p = word & 0xFFFF;
536 short valuePeak_p = (word >> 16) & 0xFFFF;
539 short sampleRise_p = word & 0xFFFF;
540 short valueRise0_p = (word >> 16) & 0xFFFF;
543 short valueRise1_p = word & 0xFFFF;
544 short sampleFall_p = (word >> 16) & 0xFFFF;
547 short valueFall0_p = word & 0xFFFF;
548 short valueFall1_p = (word >> 16) & 0xFFFF;
551 short integral_p = word & 0xFFFF;
559 short samplePeak_n = word & 0xFFFF;
560 short valuePeak_n = (word >> 16) & 0xFFFF;
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);
634 if (word != 0x7473616c) {
644 info->incrementFEHeadersCount();
645 if (digits.empty()) info->incrementEmptyFEHeadersCount();
647 if (header != 0xaaaa0103)
continue;
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));
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);
701 windows.push_back(word & 0x1FF);
704 windows.push_back(word & 0x1FF);
707 windows.push_back(word & 0x1FF);
709 int numWords = 4 * 32;
711 B2ERROR(
"TOPUnpacker: too few words for waveform data."
712 <<
LogVar(
"needed", numWords)
719 std::vector<short> adcData;
720 for (
int i = 0; i < numWords; i++) {
722 adcData.push_back(word & 0xFFFF);
723 adcData.push_back((word >> 16) & 0xFFFF);
732 moduleID = feemap->getModuleID();
733 boardstack = feemap->getBoardstackNumber();
735 B2ERROR(
"TOPUnpacker: no front-end map available."
736 <<
LogVar(
"SCROD ID", scrodID));
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);
822 bool pedestalSubtracted)
825 B2DEBUG(22,
"Unpacking Production firmware debug data format to TOPRawDigits "
826 "dataSize = " << bufferSize);
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;
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));
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);
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);
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;
917 && array.
getIndex() < evtNumWordsCore - 2) {
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) {
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
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) {
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
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));
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));
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);
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);
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
1060 B2WARNING(
"TOPUnpacker: hit checksum invalid.");
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) {
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);
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));
1145 B2DEBUG(22,
"the rest:");
1147 unsigned int numParsedWaveforms = 0;
1148 while (array.
peekWord() != 0x6c617374
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;
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));
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;
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));
1247 B2INFO(
"TOPUnpacker: Channels seen per event statistics:");
1248 B2INFO(
"TOPUnpacker: nChn\tcount");
1250 B2INFO(
"TOPUnpacker: " << entry.first <<
"\t\t" << entry.second);
@ c_DontWriteOut
Object/array should be NOT saved by output modules.
@ c_Event
Different object in each event, all objects/arrays are invalidated after event() function has been ca...
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
The Raw TOP class Class for RawCOPPER class data taken by TOP Currently, this class is almost same as...
Type-safe access to single objects in the data store.
EHitQuality
hit quality enumerators
const TOPNominalTDC & getNominalTDC() const
Returns nominal time-to-digit conversion parameters.
@ c_DifferentChannels
in FE and WF header
@ c_DifferentScrodIDs
in HLSB and FE header
@ c_InvalidMagicWord
at the end of FE header
@ c_InvalidScrodID
no front-end map available
@ c_DifferentCarriers
in FE and WF header
@ c_DifferentWindows
in FE and WF header
@ c_InsufficientWFData
too few words for waveform data
@ c_InvalidFEHeader
invalid FE header word
@ c_DifferentAsics
in FE and WF header
unsigned getSubBits() const
Returns number of bits per sample.
Class to store debugging information about the hit headers in the TOP production debugging raw data f...
void appendExtraWord(unsigned int extraWord)
Appends extra word to vector of additional event words.
@ c_Interim
from interim feature extraction
@ c_ProductionDebug
from production debugging format
@ c_Production
from the future production format
@ c_HitMagic
if magic number not 0xB
@ c_TailMagic
if magic bits not '101' = 0x5
@ c_HitChecksum
if sum of 16-bit words not zero
@ c_HeadMagic
if magic number not 0xA
short expand13to16bits(unsigned short x) const
Expand 13-bit signed-word to 16-bit signed-word.
int m_dataFormat
data format
StoreArray< TOPRawWaveform > m_waveforms
collection of waveforms
StoreArray< TOPRawDigit > m_rawDigits
collection of raw digits
unsigned m_numErrors
number of error messages per event
unsigned m_errorCount
error messages count within single event
std::map< int, int > m_channelStatistics
counts how many different channels have been parsed in a given SCROD packet
StoreArray< TOPSlowData > m_slowData
collection of slow data
bool m_swapBytes
if true, swap bytes
StoreArray< TOPProductionEventDebug > m_productionEventDebugs
collection of event debug data
std::string m_outputRawDigitsName
name of TOPRawDigit store array
std::string m_outputWaveformsName
name of TOPRawWaveform store array
unsigned short sumShorts(unsigned int x) const
sum both 16-bit words of 32-bit integer
StoreArray< RawTOP > m_rawData
collection of raw data
StoreArray< TOPInterimFEInfo > m_interimFEInfos
collection of interim informations
bool m_resetEventCount
request for event count reset
StoreArray< TOPProductionHitDebug > m_productionHitDebugs
collection of hit debug data
std::string m_outputDigitsName
name of TOPDigit store array
StoreArray< TOPTemplateFitResult > m_templateFitResults
collection of template fit results
std::string m_inputRawDataName
name of RawTOP store array
unsigned m_errorSuppressFactor
error messages suppression factor
StoreArray< TOPDigit > m_digits
collection of digits
unsigned m_eventCount
event count since last printed error message
bool m_addRelations
switch ON/OFF relations to TOPProductionHitDebugs
std::string m_templateFitResultName
name of TOPTemplateFitResult store array
TOP::TOPGeometryPar * m_topgp
geometry param
Helper class for getting data words from a finesse buffer Keeps checksum counter for each extracted d...
int getRemainingWords() const
Returns number of remaining words in the buffer.
int getWord()
Returns consecutive data word Updates internal checksum counter for each extracted word.
void resetChecksum()
Resets internal checksum counter.
unsigned int getIndex() const
Returns index of last returned data word.
int peekWord()
Returns next data word without incrementing the memory pointer and without modifying the checksum cou...
bool validateChecksum()
Validates current checksum counter status.
int getLastWord()
Returns last data word.
const TOPFrontEndMap * getMap(int moduleID, int bs) const
Return map from TOP module side.
int getMapSize() const
Return size of the map.
const TOPGeometry * getGeometry() const
Returns pointer to geometry object using basf2 units.
const ChannelMapper & getChannelMapper() const
Returns default channel mapper (mapping of channels to pixels)
const FrontEndMapper & getFrontEndMapper() const
Returns front-end mapper (mapping of SCROD's to positions within TOP modules)
Class to store variables with their name which were sent to the logging service.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
int unpackProdDebug(const int *buffer, int bufferSize, TOP::RawDataType dataFormat, bool pedestalSubtracted)
Unpack raw data given in production debugging format.
void unpackProductionDraft(const int *buffer, int bufferSize)
Unpack raw data given in a tentative production format (will vanish in future)
std::string getFrontEndName(RawTOP &raw, int finesse) const
Returns the name of the front-end.
virtual void initialize() override
Initialize the Module.
virtual void event() override
Event processor.
virtual void endRun() override
End-of-run action.
void unpackType0Ver16(const int *buffer, int bufferSize)
Unpack raw data given in feature-extraction production format.
virtual void terminate() override
Termination action.
virtual void beginRun() override
Called when entering a new run.
bool unpackHeadersInterimFEVer01(const int *buffer, int bufferSize, bool swapBytes)
Tries to unpack raw data assuming it is in feature-extraction interim format.
TOPUnpackerModule()
Constructor.
virtual ~TOPUnpackerModule()
Destructor.
int unpackInterimFEVer01(const int *buffer, int bufferSize, bool pedestalSubtracted)
Unpack raw data given in feature-extraction interim format.
bool printTheError()
Error messages suppression logic.
Abstract base class for different kinds of events.
record to be used to store ASIC info