11 #include <trg/cdc/modules/unpacker/CDCTriggerUnpackerModule.h>
12 #include <framework/core/ModuleParam.templateDetails.h>
13 #include <trg/cdc/dbobjects/CDCTriggerNeuroConfig.h>
22 using namespace CDCTriggerUnpacker;
35 using dataWord = std::bitset<wordWidth>;
59 unsigned inEventWidth,
unsigned inOffset,
60 int inHeaderSize, std::vector<int> inNodeID,
61 unsigned inNInnerMergers,
int& inDelay,
65 inHeaderSize, inNodeID, inDelay, inCnttrg, inDebugLevel),
67 nInnerMergers(inNInnerMergers) {};
74 void reserve(
int subDetectorId, std::array<int, nFinesse> nWords)
override
76 if (subDetectorId != iNode) {
79 if (nWords[iFinesse] < headerSize) {
82 size_t nClocks = (nWords[iFinesse] - headerSize) / eventWidth;
85 for (
unsigned i = 0; i < nClocks; ++i) {
88 B2DEBUG(20, name <<
": " << nClocks <<
" clocks");
89 }
else if (entries != nClocks) {
90 B2DEBUG(20,
"Number of clocks in " << name <<
" conflicts with others!");
96 std::array<int*, 4> data32tab,
97 std::array<int, 4> nWords)
99 if (subDetectorId != iNode) {
102 if (nWords[iFinesse] < headerSize) {
103 B2DEBUG(20,
"The module " << name <<
" does not have enough data (" <<
104 nWords[iFinesse] <<
"). Nothing will be unpacked.");
110 for (
int i = headerSize; i < nWords[iFinesse]; i += eventWidth) {
111 int iclock = (i - headerSize) / eventWidth;
112 auto mergerClock = (*arrayPtr)[iclock];
113 B2DEBUG(100,
"clock " << iclock);
115 for (
unsigned j = offset; j < eventWidth; ++j) {
116 int iMerger = (eventWidth - j - 1) / 8 + nInnerMergers;
117 int pos = (eventWidth - j - 1) % 8;
118 dataWord word(data32tab[iFinesse][i + j]);
120 mergerClock->m_signal[iMerger].set(pos *
wordWidth + k, word[k]);
124 if (debugLevel >= 300) {
125 printBuffer(data32tab[iFinesse] + headerSize, eventWidth);
127 printBuffer(data32tab[iFinesse] + headerSize + eventWidth, eventWidth);
129 for (
int i = 0; i < std::accumulate(nMergers.begin(), nMergers.end(), 0); ++i) {
130 B2DEBUG(99, (*arrayPtr)[0]->m_signal[i].to_string());
140 std::string inName,
unsigned inEventWidth,
unsigned inOffset,
141 unsigned inHeaderSize, std::vector<int> inNodeID,
142 unsigned inNumTS,
int& inDelay,
146 inDelay, inCnttrg, inDebugLevel),
147 inputArrayPtr(inArrayPtr), outputArrayPtr(outArrayPtr),
148 iTracker(std::stoul(inName.substr(inName.length() - 1))),
149 numTS(inNumTS), offsetBitWidth(inOffset) {};
170 void reserve(
int subDetectorId, std::array<int, nFinesse> nWords)
override
172 size_t nClocks = (nWords[iFinesse] - headerSize) / eventWidth;
174 if (subDetectorId == iNode) {
176 for (
unsigned i = 0; i < nClocks; ++i) {
180 for (
unsigned j = 0; j < nTrackers; ++j) {
181 for (
unsigned iAxialTSF = 0; iAxialTSF < nAxialTSF; ++iAxialTSF) {
182 inputClock->
m_signal[iAxialTSF][j].fill(zero_val);
184 outputClock->
m_signal[j].fill(zero_val);
187 B2DEBUG(20, name <<
": " << nClocks <<
" clocks");
188 }
else if (entries != nClocks) {
189 B2DEBUG(20,
"Number of clocks in " << name <<
" conflicts with others!");
204 std::array<int*, 4> data32tab,
205 std::array<int, 4> nWords)
207 if (subDetectorId != iNode) {
214 using halfDataWord = std::bitset<16>;
215 std::vector<halfDataWord> counters;
216 counters.reserve(inputArrayPtr->
getEntries());
217 for (
int iclock = 0; iclock < inputArrayPtr->
getEntries(); ++iclock) {
218 counters.emplace_back(data32tab[iFinesse]
219 [headerSize + eventWidth * iclock] & 0xffff);
220 B2DEBUG(100,
"iclock " << iclock <<
" --> " << counters.at(iclock).to_ulong() <<
" : " << std::hex << counters.at(iclock));
222 bool counter_correct_error =
false;
223 while (counters.at(1).to_ulong() - counters.at(0).to_ulong() != 4) {
224 std::rotate(counters.begin(), counters.begin() + 1, counters.end());
233 B2DEBUG(90,
"PHYSJG: clock counter rotation over one cycle: " << ccShift);
234 for (
const auto& c : counters) {
235 B2DEBUG(90,
"" << c.to_ulong() <<
" : " << std::hex << c);
237 counter_correct_error =
true;
241 if (counter_correct_error) {
242 B2DEBUG(20,
"PHYSJG: " << name <<
" too many clock counter rotation corrections: " << ccShift <<
" data object skipped.");
246 if (! std::is_sorted(counters.begin(), counters.end(),
247 [](halfDataWord i, halfDataWord j) {
248 return (j.to_ulong() - i.to_ulong() == 4);
250 B2DEBUG(20,
"clock counters are still out of order");
251 for (
const auto& c : counters) {
252 B2DEBUG(90,
"" << c.to_ulong());
257 B2DEBUG(15,
"shifting the first " << ccShift <<
258 " clock(s) to the end for " << name);
264 for (
int i = headerSize; i < nWords[iFinesse]; i += eventWidth) {
265 int iclock = (i - headerSize) / eventWidth - ccShift;
269 auto inputClock = (*inputArrayPtr)[iclock];
270 auto outputClock = (*outputArrayPtr)[iclock];
272 outputClock->m_signal[iTracker].fill(zero_val);
273 B2DEBUG(90,
"unpacker clock " << iclock);
274 if (debugLevel >= 300) {
275 printBuffer(data32tab[iFinesse] + headerSize + eventWidth * iclock,
279 std::array<dataWord, 2> ccword({
280 data32tab[iFinesse][i + 2], data32tab[iFinesse][i + 3]
284 for (
unsigned iTSF = 0; iTSF < nAxialTSF; ++iTSF) {
286 inputClock->m_signal[nAxialTSF - 1 - iTSF][iTracker].fill(zero_val);
288 if (firmwareVersion <
"18012600") {
302 for (
unsigned pos = 0; pos < clockCounterWidth; ++pos) {
303 const int j = (pos + iTSF * clockCounterWidth) /
wordWidth;
304 const int k = (pos + iTSF * clockCounterWidth) %
wordWidth;
321 inputClock->m_signal[nAxialTSF - 1 - iTSF][iTracker][pos] =
326 for (
unsigned pos = 0; pos < numTS * lenTS; ++pos) {
327 const int j = (offsetBitWidth + pos + iTSF * numTS * lenTS) /
wordWidth;
328 const int k = (offsetBitWidth + pos + iTSF * numTS * lenTS) %
wordWidth;
329 dataWord word(data32tab[iFinesse][i + j]);
333 inputClock->m_signal[nAxialTSF - 1 - iTSF][iTracker]
334 [clockCounterWidth + pos] = std_logic(word[
wordWidth - 1 - k]);
350 unsigned TSFWidth = clockCounterWidth + numTS * lenTS;
351 for (
unsigned pos = 0; pos < TSFWidth; ++pos) {
352 const int j = (offsetBitWidth + pos + iTSF * TSFWidth) /
wordWidth;
353 const int k = (offsetBitWidth + pos + iTSF * TSFWidth) %
wordWidth;
354 dataWord word(data32tab[iFinesse][i + j]);
355 inputClock->m_signal[nAxialTSF - 1 - iTSF][iTracker][pos] =
359 if (debugLevel >= 100) {
360 display_hex(inputClock->m_signal[nAxialTSF - 1 - iTSF][iTracker]);
364 if (firmwareVersion <
"18012600") {
369 const int outputOffset = nAxialTSF * numTS * lenTS;
370 const int oldtrackWidth = 6;
371 for (
unsigned pos = 0; pos < 732; ++pos) {
372 const int j = (offsetBitWidth + pos + outputOffset) /
wordWidth;
373 const int k = (offsetBitWidth + pos + outputOffset) %
wordWidth;
374 dataWord word(data32tab[iFinesse][i + j]);
375 outputClock->m_signal[iTracker][clockCounterWidth + oldtrackWidth + pos]
385 const int outputOffset = offsetBitWidth + nAxialTSF * numTS * lenTS + 45;
386 for (
unsigned pos = 0; pos < T2DOutputWidth; ++pos) {
387 const int j = (pos + outputOffset) /
wordWidth;
388 const int k = (pos + outputOffset) %
wordWidth;
389 dataWord word(data32tab[iFinesse][i + j]);
390 outputClock->m_signal[iTracker][clockCounterWidth + pos]
394 if (debugLevel >= 100) {
395 display_hex(outputClock->m_signal[iTracker]);
405 std::string inName,
unsigned inEventWidth,
unsigned inOffset,
406 unsigned inHeaderSize, std::vector<int> inNodeID,
int& inDelay,
410 inDelay, inCnttrg, inDebugLevel),
412 iTracker(std::stoul(inName.substr(inName.length() - 1))),
413 offsetBitWidth(inOffset) {};
422 void reserve(
int subDetectorId, std::array<int, nFinesse> nWords)
override
424 size_t nClocks = (nWords[iFinesse] - headerSize) / eventWidth;
426 if (subDetectorId == iNode) {
428 for (
unsigned i = 0; i < nClocks; ++i) {
431 for (
unsigned j = 0; j < nTrackers; ++j) {
432 nnclock->
m_signal[j].fill(zero_val);
435 B2DEBUG(20, name <<
": " << nClocks <<
" clocks");
436 }
else if (entries != nClocks) {
437 B2DEBUG(20,
"Number of clocks in " << name <<
" conflicts with others!");
443 std::array<int*, nFinesse> data32tab,
444 std::array<int, nFinesse> nWords)
override
446 if (subDetectorId != iNode) {
451 for (
int i = headerSize; i < nWords[iFinesse]; i += eventWidth) {
452 int iclock = (i - headerSize) / eventWidth;
453 auto nnclock = (*ArrayPtr)[iclock];
454 B2DEBUG(20,
"clock " << iclock);
455 if (debugLevel >= 300) {
456 printBuffer(data32tab[iFinesse] + headerSize + eventWidth * iclock,
460 for (
unsigned pos = 0; pos < NN_WIDTH; ++pos) {
461 const int j = (offsetBitWidth + pos) /
wordWidth;
462 const int k = (offsetBitWidth + pos) %
wordWidth;
463 std::bitset<wordWidth> word(data32tab[iFinesse][i + j]);
464 nnclock->m_signal[iTracker][pos] = std_logic(word[
wordWidth - 1 - k]);
466 if (debugLevel >= 100) {
467 display_hex(nnclock->m_signal[iTracker]);
483 "whether to unpack merger data (recorded by Merger Reader / TSF)",
false);
485 "whether to unpack 2D tracker data",
false);
487 "whether to unpacker neurotrigger data",
false);
489 "flag to decode 2D finder track",
false);
491 "flag to decode input TS to 2D",
false);
493 "flag to decode neurotrigger data",
false);
503 "list of COPPER and HSLB ID of Merger reader (TSF)", defaultMergerNodeID);
511 "list of COPPER and HSLB ID of 2D tracker", defaultTracker2DNodeID);
519 "list of COPPER and HSLB ID of neurotrigger", defaultNeuroNodeID);
521 "number of words (number of bits / 32) of the B2L header", 3);
523 "Whether to align out-of-sync Belle2Link data between different sub-modules",
true);
525 "Use values stored in the payload of the ConditionsDB."
526 "This affects the output scaling of the Neurotrigger as well as the"
527 "bit configuration of its unpacker. If false, an old unpacker version with fixed scalings and old bit adresses is used.",
530 "Simulate 13 bit drift time by using 2d clock counter value.",
540 m_mergerBits.registerInDataStore(
"CDCTriggerMergerBits");
543 m_bitsTo2D.registerInDataStore(
"CDCTriggerTSFTo2DBits");
544 m_bits2DTo3D.registerInDataStore(
"CDCTrigger2DTo3DBits");
547 m_bitsNN.registerInDataStore(
"CDCTriggerNNBits");
551 m_TSHits.registerInDataStore(
"CDCTriggerSegmentHits");
564 m_NeuroInputs.registerInDataStore(
"CDCTriggerNeuroTracksInput");
572 for (
int iSL = 0; iSL < 9; iSL += 2) {
574 const int nInnerMergers = std::accumulate(
nMergers.begin(),
576 B2DEBUG(20,
"in: " << nInnerMergers);
593 int datasize_2D = 64;
600 for (
int iTracker = 0; iTracker < 4; ++iTracker) {
604 "Tracker2D" + std::to_string(iTracker), datasize_2D, 82,
m_headerSize,
613 "Neuro" + std::to_string(iTracker), 64, 0,
m_headerSize,
631 m_exp = bevt->getExperiment();
632 m_run = bevt->getRun();
635 B2FATAL(
"CDCTriggerNeuroConfig is not valid.");
637 B2DEBUG(2,
"Load Neurotrigger configuration for network " <<
m_cdctriggerneuroconfig->getNNName() <<
" from database ");
638 B2DEBUG(10, padright(
"Name", 50) << padright(
"start", 10) << padright(
"end", 10) << padright(
"offset", 10));
640 B2DEBUG(10, padright(x.name, 48) <<
": " << padright(std::to_string(x.start), 10) << padright(std::to_string(x.end),
641 10) << padright(std::to_string(x.offset), 10));
650 B2DEBUG(10, padright(
" ", 100));
651 B2DEBUG(10,
"----------------------------------------------------------------------------------------------------");
652 B2DEBUG(10, padright(
" ", 100));
654 std::string experimentstring =
"Experiment " + std::to_string(eventMetaData->getExperiment()) +
" Run " +
655 std::to_string(eventMetaData->getRun()) +
" Event " + std::to_string(eventMetaData->getEvent());
656 B2DEBUG(10, padright(experimentstring, 100));
661 B2DEBUG(20,
"exp<7: skip cdctrg unpacker for DQM");
666 B2DEBUG(99,
m_rawTriggers.getEntries() <<
" COPPERs in RawTRGs");
670 const int subDetectorId = rawTRG.GetNodeID(0);
673 const int nEntriesRawTRG = rawTRG.GetNumEntries();
676 B2DEBUG(99,
"nEntries of rawTRG: " << nEntriesRawTRG);
677 for (
int j = 0; j < nEntriesRawTRG; ++j) {
681 std::array<int, nFinesse> nWords;
682 std::array<int*, nFinesse> data32tab;
685 for (
int iFinesse = 0; iFinesse <
nFinesse; ++iFinesse) {
686 nWords[iFinesse] = rawTRG.GetDetectorNwords(j, iFinesse);
687 if (nWords[iFinesse] == 0) {
690 data32tab[iFinesse] = (
int*)rawTRG.GetDetectorBuffer(j, iFinesse);
695 if (trg->getHeaders(subDetectorId, data32tab, nWords)) {
696 trg->reserve(subDetectorId, nWords);
697 B2DEBUG(99,
"starting to unpack a subTrigger, subDetectorId" << std::hex << subDetectorId);
698 trg->unpack(subDetectorId, data32tab, nWords);
703 B2DEBUG(99,
"looped over entries and filled words " << nEntriesRawTRG);
705 B2DEBUG(99,
"looped over rawTriggers, unpacking 2D ");
709 for (
short iclock = 0; iclock <
m_bits2DTo3D.getEntries(); ++iclock) {
717 B2DEBUG(99,
"unpack 2D Input TS ");
719 std::array<int, 4> clockCounter2D = {0, 0, 0, 0};
720 std::array<int, 4> timeOffset2D = {0, 0, 0, 0};
722 for (
int iTracker = 0; iTracker < nTrackers; ++iTracker) {
727 std::string strInput = slv_to_bin_string(trackerData);
728 clockCounter2D[iTracker] = std::stoi(strInput.substr(0, clockCounterWidth), 0, 2);
729 int clockCounterDiff = clockCounter2D[iTracker] - clockCounter2D[0];
739 if (clockCounterDiff > 1250) {
740 clockCounterDiff -= 1280;
741 }
else if (clockCounterDiff < -1250) {
742 clockCounterDiff += 1280;
744 timeOffset2D[iTracker] = clockCounterDiff;
745 if (clockCounterDiff != 0) {
746 B2DEBUG(100,
"Adding " << clockCounterDiff <<
" clock(s) to 2D" << iTracker <<
" found time");
748 if (std::abs(clockCounterDiff) > 2) {
749 B2DEBUG(20,
"Clock counters between 2D [0," << iTracker <<
"] differ by " << clockCounterDiff <<
" clocks! (" \
750 << clockCounter2D[0] <<
", " << clockCounter2D[iTracker] <<
")");
753 for (
short iclock = 0; iclock <
m_bitsTo2D.getEntries(); ++iclock) {
754 B2DEBUG(30,
"clock " << iclock);
758 B2DEBUG(99,
"now unpack neuro ");
767 B2DEBUG(99,
" all is unpacked ##### ");