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);
110 if (mapSize == 0) B2ERROR(
"TOPUnpacker: No front-end mapping available for TOP");
144 for (
int finesse = 0; finesse < raw.GetMaxNumOfCh(0); finesse++) {
145 const int* buffer = raw.GetDetectorBuffer(0, finesse);
146 int bufferSize = raw.GetDetectorNwords(0, finesse);
147 if (bufferSize < 1)
continue;
152 if (dataFormat == 0) {
154 unsigned word = array.
getWord();
155 dataFormat = (word >> 16);
156 bool isKnownDataFormat =
false;
157 for (
auto& t : TOP::membersRawDataType) {
158 if (
static_cast<int>(t) == dataFormat) {
159 isKnownDataFormat =
true;
164 if (!isKnownDataFormat) {
165 if (evtMetaData->getExperiment() == 1) {
170 B2DEBUG(22,
"Assuming interim FW data format");
174 B2WARNING(
"TOPUnpacker: Could not establish data format.");
181 switch (dataFormat) {
182 case static_cast<int>(TOP::RawDataType::c_Type0Ver16):
185 case static_cast<int>(TOP::RawDataType::c_Type2Ver1):
188 case static_cast<int>(TOP::RawDataType::c_Type3Ver1):
191 case static_cast<int>(TOP::RawDataType::c_Draft):
194 case static_cast<int>(TOP::RawDataType::c_ProductionDebug01):
195 err =
unpackProdDebug(buffer, bufferSize, TOP::RawDataType::c_ProductionDebug01,
true, evtMetaData->getExperiment());
197 case static_cast<int>(TOP::RawDataType::c_ProductionDebug02):
198 err =
unpackProdDebug(buffer, bufferSize, TOP::RawDataType::c_ProductionDebug02,
true, evtMetaData->getExperiment());
204 B2ERROR(
"TOPUnpacker: unknown data format from " << boardstackName
205 <<
LogVar(
"boardstack name", boardstackName)
206 <<
LogVar(
"Type", (dataFormat >> 8))
207 <<
LogVar(
"Version", (dataFormat & 0xFF)));
215 B2ERROR(
"TOPUnpacker: error in unpacking data from " << boardstackName
216 <<
LogVar(
"boardstack name", boardstackName)
217 <<
LogVar(
"words unused", err));
230 if (raw.GetMaxNumOfCh(0) <= 4) {
231 int copper = ((raw.GetNodeID(0) >> 24) * 1000 + (raw.GetNodeID(0) & 0x3FF));
232 name =
"frontend cpr" + std::to_string(copper) + char(
'a' + finesse);
234 int slot = (raw.GetNodeID(0) & 0xF) * 8 - 7 + finesse / 4;
235 name = (slot < 10) ?
"boardstack s0" :
"boardstack s";
236 name += std::to_string(slot) + char(
'a' + finesse % 4);
254 B2DEBUG(22,
"Unpacking ProductionDraft to TOPDigits, dataSize = " << bufferSize);
256 unsigned short scrodID = buffer[0] & 0xFFFF;
259 B2ERROR(
"TOPUnpacker: no front-end map available."
260 <<
LogVar(
"SCROD ID", scrodID));
263 int moduleID = feemap->getModuleID();
264 int boardstack = feemap->getBoardstackNumber();
269 int sampleDivisions = 0x1 << subBits;
271 for (
int i = 1; i < bufferSize; i++) {
272 int word = buffer[i];
273 int tdc = word & 0xFFFF;
274 double rawTime = double(tdc) / sampleDivisions;
275 unsigned chan = ((word >> 16) & 0x7F) + boardstack * 128;
276 unsigned flags = (word >> 24) & 0xFF;
277 int pixelID = mapper.getPixelID(chan);
278 auto* digit =
m_digits.appendNew(moduleID, pixelID, rawTime);
279 digit->setTime(geo->getNominalTDC().getTime(tdc));
280 digit->setChannel(chan);
290 B2DEBUG(22,
"Unpacking Type0Ver16 to TOPRawDigits, dataSize = " << bufferSize);
293 unsigned word = array.
getWord();
294 unsigned short scrodID = word & 0x0FFF;
297 int Nhits = last & 0x01FF;
298 if (bufferSize != 5 * Nhits + 2) {
299 B2ERROR(
"TOPUnpacker: corrupted data (feature-extraction format)."
300 <<
LogVar(
"SCROD ID", scrodID));
304 short SDType = last >> 24;
305 short SDValue = (last >> 12) & 0x0FFF;
306 if (SDType != 0)
m_slowData.appendNew(scrodID, SDType, SDValue);
308 unsigned short errorFlags = 0;
312 for (
int hit = 0; hit < Nhits; hit++) {
316 digit->setCarrierNumber((word >> 30) & 0x03);
317 digit->setASICNumber((word >> 28) & 0x03);
318 digit->setASICChannel((word >> 25) & 0x07);
319 digit->setASICWindow((word >> 16) & 0x1FF);
320 digit->setTFine((word >> 8) & 0x0F);
321 auto flags = errorFlags;
323 unsigned short checkSum =
sumShorts(word);
327 digit->setIntegral(word & 0xFFFF);
341 digit->setSampleRise(word >> 24);
342 digit->setDeltaSamplePeak((word >> 20) & 0x0F);
343 digit->setDeltaSampleFall((word >> 16) & 0x0F);
347 digit->setErrorFlags(flags);
355 B2DEBUG(22,
"Checking whether buffer unpacks as InterimFEVer01, dataSize = " << bufferSize);
357 DataArray array(buffer, bufferSize, swapBytes);
362 unsigned header = array.
getWord();
363 if ((header & 0xFF) == 0xBE) {
367 if (header != 0xaaaa0104 and header != 0xaaaa0103 and header != 0xaaaa0100) {
375 if (header != 0xaaaa0104) {
391 unsigned magicWord = array.
getWord();
392 if (magicWord != 0x7473616c) {
396 if (header != 0xaaaa0103)
continue;
409 int numWords = 4 * 32;
414 for (
int i = 0; i < numWords; i++) {
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;
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;
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);
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);
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));
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) {
543 short samplePeak_p = word & 0xFFFF;
544 short valuePeak_p = (word >> 16) & 0xFFFF;
547 short sampleRise_p = word & 0xFFFF;
548 short valueRise0_p = (word >> 16) & 0xFFFF;
551 short valueRise1_p = word & 0xFFFF;
552 short sampleFall_p = (word >> 16) & 0xFFFF;
555 short valueFall0_p = word & 0xFFFF;
556 short valueFall1_p = (word >> 16) & 0xFFFF;
559 short integral_p = word & 0xFFFF;
567 short samplePeak_n = word & 0xFFFF;
568 short valuePeak_n = (word >> 16) & 0xFFFF;
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);
642 if (word != 0x7473616c) {
652 info->incrementFEHeadersCount();
653 if (digits.empty()) info->incrementEmptyFEHeadersCount();
655 if (header != 0xaaaa0103)
continue;
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));
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);
709 windows.push_back(word & 0x1FF);
712 windows.push_back(word & 0x1FF);
715 windows.push_back(word & 0x1FF);
717 int numWords = 4 * 32;
719 B2ERROR(
"TOPUnpacker: too few words for waveform data."
720 <<
LogVar(
"needed", numWords)
727 std::vector<short> adcData;
728 for (
int i = 0; i < numWords; i++) {
730 adcData.push_back(word & 0xFFFF);
731 adcData.push_back((word >> 16) & 0xFFFF);
740 moduleID = feemap->getModuleID();
741 boardstack = feemap->getBoardstackNumber();
743 B2ERROR(
"TOPUnpacker: no front-end map available."
744 <<
LogVar(
"SCROD ID", scrodID));
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) +
" occurence: " + 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);
830 bool pedestalSubtracted,
int expNo)
833 B2DEBUG(22,
"Unpacking Production firmware debug data format to TOPRawDigits "
834 "dataSize = " << bufferSize);
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;
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));
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);
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);
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;
933 && array.
getIndex() < evtNumWordsCore - 2) {
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) {
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
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) {
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
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));
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));
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);
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);
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
1076 B2WARNING(
"TOPUnpacker: hit checksum invalid.");
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) {
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);
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));
1161 B2DEBUG(22,
"the rest:");
1163 unsigned int numParsedWaveforms = 0;
1164 while (array.
peekWord() != 0x6c617374
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;
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));
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;
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));
1263 B2INFO(
"TOPUnpacker: Channels seen per event statistics:");
1264 B2INFO(
"TOPUnpacker: nChn\tcount");
1266 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
StoreObjPtr< TOPInjectionVeto > m_injectionVeto
injection veto flag
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.
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.
int unpackProdDebug(const int *buffer, int bufferSize, TOP::RawDataType dataFormat, bool pedestalSubtracted, int expNo)
Unpack raw data given in production debugging 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