10 #include <trg/cdc/dataobjects/Bitstream.h>
11 #include <trg/cdc/dataobjects/CDCTriggerTrack.h>
12 #include <trg/cdc/dataobjects/CDCTriggerSegmentHit.h>
13 #include <trg/cdc/dataobjects/CDCTriggerFinderClone.h>
14 #include <trg/cdc/dataobjects/CDCTriggerMLPInput.h>
15 #include <framework/gearbox/Const.h>
16 #include <trg/cdc/dbobjects/CDCTriggerNeuroConfig.h>
24 namespace CDCTriggerUnpacker {
26 constexpr
double pi() {
return std::atan(1) * 4; }
29 static constexpr std::array<int, 9> nMergers = {10, 10, 12, 14, 16, 18, 20, 22, 24};
34 static constexpr
int TSFOutputWidth = TSF_TO_2D_WIDTH;
35 static constexpr
int nTrackers = NUM_2D;
36 static constexpr
int nAxialTSF = NUM_TSF;
37 static constexpr
int nStereoTSF = 4;
38 static constexpr
int T2DOutputWidth = T2D_TO_3D_WIDTH;
39 static constexpr
unsigned lenTS = 21;
41 static constexpr
int nMax2DTracksPerClock = 4;
44 static constexpr
int clockCounterWidth = 9;
47 static constexpr std::array<int, nAxialTSF> nAxialMergers = {10, 12, 16, 20, 24};
49 static constexpr std::array<int, 9> nWiresInSuperLayer = {
50 160, 160, 192, 224, 256, 288, 320, 352, 384
53 static constexpr
int nCellsInLayer = 16;
56 using TSFOutputVector = std::array<char, TSFOutputWidth>;
57 using TSFOutputArray = std::array<TSFOutputVector, nTrackers>;
58 using TSFOutputBus = std::array<TSFOutputArray, nAxialTSF>;
59 using TSFOutputBitStream = Bitstream<TSFOutputBus>;
61 using T2DOutputVector = std::array<char, T2DOutputWidth>;
62 using T2DOutputBus = std::array<T2DOutputVector, nTrackers>;
63 using T2DOutputBitStream = Bitstream<T2DOutputBus>;
65 using NNVector = std::array<char, NN_WIDTH>;
66 using NNBus = std::array<NNVector, nTrackers>;
67 using NNBitStream = Bitstream<NNBus>;
77 std::string padto(std::string s,
unsigned l)
80 s.insert(s.begin(), l - s.size(),
' ');
84 std::string padright(std::string s,
unsigned l)
87 s.insert(s.end(), l - s.size(),
' ');
92 void printBuffer(
int* buf,
int nwords)
94 for (
int j = 0; j < nwords; ++j) {
95 printf(
" %.8x", buf[j]);
96 if ((j + 1) % 8 == 0) {
104 std::string rawIntToAscii(
int buf)
106 std::ostringstream firmwareTypeStream;
107 firmwareTypeStream << std::hex << buf;
108 std::string firmwareTypeHex(firmwareTypeStream.str());
109 std::string firmwareType(4,
'0');
110 for (
int i = 0; i < 4; i++) {
111 std::istringstream firmwareTypeIStream(firmwareTypeHex.substr(i * 2, 2));
113 firmwareTypeIStream >> std::hex >> character;
114 firmwareType[i] = character;
119 std::string rawIntToString(
int buf)
121 std::ostringstream firmwareVersionStream;
122 firmwareVersionStream << std::hex << buf;
123 return firmwareVersionStream.str();
149 char std_logic(
bool inBit)
161 for (
int i = 0; i < size; i++) {
162 if (count[i] >= 0 && count[i] < 9) {
165 B2DEBUG(20,
"invalid signal detected: " <<
static_cast<int>(count[i]));
175 int ini = padding ? 4 - signal.size() % 4 : 0;
176 std::string res(ini,
'0');
177 for (
auto const& bit : signal) {
178 if (bit >= 0 && bit < 9) {
181 B2DEBUG(20,
"invalid signal detected: " <<
static_cast<int>(bit));
189 void display_hex(
const std::array<char, N>& signal)
191 std::ios oldState(
nullptr);
192 oldState.copyfmt(std::cout);
193 if (std::any_of(signal.begin(), signal.end(), [](
char i)
194 {return i != zero_val && i != one_val;})) {
195 B2DEBUG(20,
"Some bit in the signal vector is neither 0 nor 1. \n" <<
196 "Displaying binary values instead.");
200 std::cout << std::setfill(
'0');
201 for (
unsigned i = 0; i < signal.size(); i += 4) {
202 std::bitset<4> set(binString.substr(i, 4));
203 std::cout << std::setw(1) << std::hex << set.to_ulong();
207 std::cout.copyfmt(oldState);
217 template<
size_t nbits,
size_t min,
size_t max>
218 std::bitset < max - min + 1 >
subset(std::bitset<nbits> set)
220 const size_t outWidth = max - min + 1;
221 std::string str = set.to_string();
222 return std::bitset<outWidth>(str.substr(nbits - max - 1, outWidth));
233 unsigned short globalSegmentID(
unsigned short localID,
unsigned short iSL)
235 auto itr = nWiresInSuperLayer.begin();
236 unsigned short globalID = std::accumulate(itr, itr + iSL, 0);
241 using tsOut = std::array<unsigned, 4>;
268 std::array<tsOut, 9>
ts;
277 if ((b2line.
offset + foundtime >= 0) &&
278 (b2line.
offset + foundtime <= bitsNN->getEntries())) {
282 if (slv_to_bin_string(bitsn->
signal()[iTracker]).size() >= (NN_WIDTH - b2line.
start)) {
283 data = slv_to_bin_string(bitsn->
signal()[iTracker]).substr(NN_WIDTH - 1 - b2line.
end, b2line.
end - b2line.
start + 1);
299 std::vector<bool> decodedriftthreshold(std::string p_driftthreshold)
301 std::vector<bool> res;
302 for (
unsigned i = 0; i < p_driftthreshold.size(); ++i) {
303 if (p_driftthreshold.substr(i, 1) ==
"1") {
305 }
else if (p_driftthreshold.substr(i, 1) ==
"0") {
306 res.push_back(
false);
308 B2WARNING(
"Invalid input in NNBitstream appending 'false'!");
309 res.push_back(
false);
314 std::vector<bool> decodefoundoldtrack(std::string p_foundoldtrack)
316 std::vector<bool> res;
317 for (
unsigned i = 0; i < p_foundoldtrack.size(); ++i) {
318 if (p_foundoldtrack.substr(i, 1) ==
"1") {
320 }
else if (p_foundoldtrack.substr(i, 1) ==
"0") {
321 res.push_back(
false);
323 B2WARNING(
"Invalid input in NNBitstream appending 'false'!");
324 res.push_back(
false);
329 bool decodevalstereobit(std::string p_valstereobit)
332 if (p_valstereobit ==
"1") {
334 }
else if (p_valstereobit ==
"0") {
337 B2WARNING(
"Invalid input in NNBitstream appending 'false'!");
353 unsigned TSIDInSL(
unsigned tsIDInTracker,
unsigned iSL,
unsigned iTracker)
355 const unsigned nCellsInSL = nMergers[iSL] * nCellsInLayer;
357 unsigned iTS = tsIDInTracker + nCellsInSL * iTracker / nTrackers;
359 if (iTS >= nCellsInSL) {
374 int mlp_bin_to_signed_int(std::string signal)
376 constexpr
unsigned len = 13;
377 std::bitset<len> signal_bit(signal);
378 const unsigned shift = 16 - len;
381 int signal_out = (int16_t (signal_bit.to_ulong() << shift)) >> shift;
392 tsOut decodeTSHit(std::string tsIn)
394 constexpr
unsigned lenID = 8;
395 constexpr
unsigned lenPriorityTime = 9;
396 constexpr
unsigned lenLR = 2;
397 constexpr
unsigned lenPriorityPosition = 2;
398 constexpr std::array<unsigned, 4> tsLens = {
399 lenID, lenPriorityTime, lenLR, lenPriorityPosition
401 std::array<unsigned, 5> tsPos = { 0 };
402 std::partial_sum(tsLens.begin(), tsLens.end(), tsPos.begin() + 1);
404 tsOutput[0] = std::bitset<tsLens[0]>(tsIn.substr(tsPos[0], tsLens[0])).to_ulong();
405 tsOutput[1] = std::bitset<tsLens[1]>(tsIn.substr(tsPos[1], tsLens[1])).to_ulong();
406 tsOutput[2] = std::bitset<tsLens[2]>(tsIn.substr(tsPos[2], tsLens[2])).to_ulong();
407 tsOutput[3] = std::bitset<tsLens[3]>(tsIn.substr(tsPos[3], tsLens[3])).to_ulong();
410 tsOut decodeTSHit_sim(std::string tsIn, std::string twodcc)
412 constexpr
unsigned lenID = 8;
413 constexpr
unsigned lenPriorityTime = 9;
414 constexpr
unsigned lenLR = 2;
415 constexpr
unsigned lenPriorityPosition = 2;
416 constexpr std::array<unsigned, 4> tsLens = {
417 lenID, lenPriorityTime, lenLR, lenPriorityPosition
419 std::string C = tsIn.substr(lenID + 5, 4);
420 std::string B = tsIn.substr(lenID, 5);
421 std::string Bp = twodcc.substr(4, 5);
422 std::string Ap = twodcc.substr(0, 4);
425 if (std::stoul(B, 0, 2) <= std::stoul(Bp, 0, 2)) {
428 B2DEBUG(14,
"2DCC overflow detected!");
429 pts = std::bitset<4>(std::stoul(Ap, 0, 2) - 1).to_string() + B + C;
431 pt = std::stoul(pts, 0, 2);
432 std::array<unsigned, 5> tsPos = { 0 };
433 std::partial_sum(tsLens.begin(), tsLens.end(), tsPos.begin() + 1);
435 tsOutput[0] = std::bitset<tsLens[0]>(tsIn.substr(tsPos[0], tsLens[0])).to_ulong();
437 tsOutput[2] = std::bitset<tsLens[2]>(tsIn.substr(tsPos[2], tsLens[2])).to_ulong();
438 tsOutput[3] = std::bitset<tsLens[3]>(tsIn.substr(tsPos[3], tsLens[3])).to_ulong();
441 tsOut decodeTSHit_ext(std::string tsIn, std::string expt)
443 constexpr
unsigned lenID = 8;
444 constexpr
unsigned lenPriorityTime = 9;
445 constexpr
unsigned lenLR = 2;
446 constexpr
unsigned lenPriorityPosition = 2;
447 constexpr std::array<unsigned, 4> tsLens = {
448 lenID, lenPriorityTime, lenLR, lenPriorityPosition
450 unsigned pt = std::stoul(expt, 0, 2);
451 std::array<unsigned, 5> tsPos = { 0 };
452 std::partial_sum(tsLens.begin(), tsLens.end(), tsPos.begin() + 1);
454 tsOutput[0] = std::bitset<tsLens[0]>(tsIn.substr(tsPos[0], tsLens[0])).to_ulong();
456 tsOutput[2] = std::bitset<tsLens[2]>(tsIn.substr(tsPos[2], tsLens[2])).to_ulong();
457 tsOutput[3] = std::bitset<tsLens[3]>(tsIn.substr(tsPos[3], tsLens[3])).to_ulong();
470 TRG2DFinderTrack decode2DTrack(std::string p_charge,
483 unsigned shift = 16 - p_omega.size();
484 TRG2DFinderTrack trackout;
485 int omega = std::stoi(p_omega, 0, 2);
488 int omegafirm = (int16_t (omega << shift)) >> shift;
491 const double BField = 1.5e-4;
499 int phi = std::stoi(p_phi, 0, 2);
501 double globalPhi0 = pi() / 4 + pi() / 2 / 80 * (phi + 1) + pi() / 2 * iTracker;
504 trackout.ts[0] = (sim13dt) ? decodeTSHit_sim(p_ts0, p_2dcc) : decodeTSHit(p_ts0);
505 trackout.ts[1] = (sim13dt) ? decodeTSHit_sim(p_ts2, p_2dcc) : decodeTSHit(p_ts2);
506 trackout.ts[2] = (sim13dt) ? decodeTSHit_sim(p_ts4, p_2dcc) : decodeTSHit(p_ts4);
507 trackout.ts[3] = (sim13dt) ? decodeTSHit_sim(p_ts6, p_2dcc) : decodeTSHit(p_ts6);
508 trackout.ts[4] = (sim13dt) ? decodeTSHit_sim(p_ts8, p_2dcc) : decodeTSHit(p_ts8);
510 if (globalPhi0 > pi() * 2) {
511 globalPhi0 -= pi() * 2;
513 trackout.phi0 = globalPhi0;
514 B2DEBUG(20,
"Unpacking 2DTrack in Tracker: " << iTracker);
515 B2DEBUG(20,
" Omega: " << std::to_string(omega) <<
", Omegafirm: " << std::to_string(omegafirm) <<
", converted to: " <<
516 std::to_string(trackout.omega));
517 B2DEBUG(20,
" Phi: " << std::to_string(phi) <<
", converted to: " << std::to_string(trackout.phi0));
521 TRG2DFinderTrack decode2DTrack(std::string trackIn,
unsigned iTracker)
523 constexpr
unsigned lenCharge = 2;
524 constexpr
unsigned lenOmega = 7;
525 constexpr
unsigned lenPhi0 = 7;
526 constexpr std::array<unsigned, 3> trackLens = {lenCharge, lenOmega, lenPhi0};
527 std::array<unsigned, 4> trackPos{ 0 };
528 std::partial_sum(trackLens.begin(), trackLens.end(), trackPos.begin() + 1);
529 const unsigned shift = 16 - lenOmega;
530 TRG2DFinderTrack trackOut;
531 std::bitset<trackLens[1]> omega(trackIn.substr(trackPos[1], trackLens[1]));
534 int omegaFirm = (int16_t (omega.to_ulong() << shift)) >> shift;
536 const double BField = 1.5e-4;
541 int phi0 = std::bitset<trackLens[2]>(trackIn.substr(trackPos[2], trackLens[2])).to_ulong();
542 trackOut.phi0 = pi() / 4 + pi() / 2 / 80 * (phi0 + 1);
543 for (
unsigned i = 0; i < 5; ++i) {
544 trackOut.ts[i] = decodeTSHit(trackIn.substr(trackPos.back() + i * lenTS, lenTS));
548 double globalPhi0 = trackOut.phi0 + pi() / 2 * iTracker;
549 if (globalPhi0 > pi() * 2) {
550 globalPhi0 -= pi() * 2;
552 trackOut.phi0 = globalPhi0;
564 TRGNeuroTrack decodeNNTrack(std::string p_mlpout_z,
565 std::string p_mlpout_theta,
566 std::string p_tsfsel,
567 std::string p_mlpin_alpha,
568 std::string p_mlpin_drifttime,
569 std::string p_mlpin_id,
570 std::string p_netsel,
571 const DBObjPtr<CDCTriggerNeuroConfig> neurodb,
574 B2LDataField p_extendedpts)
577 float scale_z = 1. / (1 << (p_mlpout_z.size() - 1));
578 float scale_theta = 1. / (1 << (p_mlpout_theta.size() - 1));
579 float scale_alpha = 1. / (1 << (p_mlpin_alpha.size() - 1) / 9);
580 float scale_drifttime = 1. / (1 << (p_mlpin_drifttime.size() - 1) / 9);
581 float scale_id = 1. / (1 << (p_mlpin_id.size() - 1) / 9);
582 TRGNeuroTrack foundTrack;
583 int theta_raw = mlp_bin_to_signed_int(p_mlpout_theta);
584 int z_raw = mlp_bin_to_signed_int(p_mlpout_z);
585 std::vector<float> unscaledT = neurodb->getMLPs()[0].unscaleTarget({(z_raw * scale_z), (theta_raw * scale_theta)});
586 foundTrack.z = unscaledT[0];
587 foundTrack.theta = unscaledT[1];
588 foundTrack.sector = std::stoi(p_netsel, 0, 2);
589 for (
unsigned iSL = 0; iSL < 9; ++iSL) {
590 foundTrack.inputAlpha[iSL] =
591 mlp_bin_to_signed_int(p_mlpin_alpha.substr((8 - iSL) * p_mlpin_alpha.size() / 9, p_mlpin_alpha.size() / 9)) * scale_alpha;
592 foundTrack.inputT[iSL] =
593 mlp_bin_to_signed_int(p_mlpin_drifttime.substr((8 - iSL) * p_mlpin_drifttime.size() / 9,
594 p_mlpin_drifttime.size() / 9)) * scale_drifttime;
595 foundTrack.inputID[iSL] =
596 mlp_bin_to_signed_int(p_mlpin_id.substr((8 - iSL) * p_mlpin_drifttime.size() / 9, p_mlpin_drifttime.size() / 9)) * scale_id;
598 foundTrack.ts[iSL] = decodeTSHit_sim(p_tsfsel.substr((8 - iSL) * lenTS, lenTS), p_2dcc);
600 if (p_extendedpts.name !=
"None") {
601 foundTrack.ts[iSL] = decodeTSHit_ext(p_tsfsel.substr((8 - iSL) * lenTS, lenTS), p_extendedpts.data.substr((8 - iSL) * 13, 13));
603 foundTrack.ts[iSL] = decodeTSHit(p_tsfsel.substr((8 - iSL) * lenTS, lenTS));
609 TRGNeuroTrack decodeNNTrack_old(std::string trackIn, std::string selectIn)
611 constexpr
unsigned lenMLP = 13;
612 float scale = 1. / (1 << (lenMLP - 1));
613 TRGNeuroTrack foundTrack;
614 int theta_raw = mlp_bin_to_signed_int(trackIn.substr(1, lenMLP));
615 foundTrack.theta = theta_raw * scale * M_PI_2 + M_PI_2;
616 int z_raw = mlp_bin_to_signed_int(trackIn.substr(lenMLP + 1, lenMLP));
617 foundTrack.z = z_raw * scale * 50.;
618 foundTrack.sector = std::bitset<3>(trackIn.substr(2 * lenMLP + 1, 3)).to_ulong();
619 for (
unsigned iSL = 0; iSL < 9; ++iSL) {
620 foundTrack.inputAlpha[iSL] =
621 mlp_bin_to_signed_int(selectIn.substr((2 + (8 - iSL)) * lenMLP + 4, lenMLP)) * scale;
622 foundTrack.inputT[iSL] =
623 mlp_bin_to_signed_int(selectIn.substr((11 + (8 - iSL)) * lenMLP + 4, lenMLP)) * scale;
624 foundTrack.inputID[iSL] =
625 mlp_bin_to_signed_int(selectIn.substr((20 + (8 - iSL)) * lenMLP + 4, lenMLP)) * scale;
627 decodeTSHit(selectIn.substr(29 * lenMLP + 4 + (8 - iSL) * lenTS, lenTS));
636 CDCTriggerSegmentHit* addTSHit(
tsOut ts,
unsigned iSL,
unsigned iTracker,
637 StoreArray<CDCTriggerSegmentHit>* tsHits,
640 unsigned iTS = TSIDInSL(ts[0], iSL, iTracker);
642 CDCTriggerSegmentHit* hit =
nullptr;
656 hit = tsHits->appendNew(iSL, iTS, ts[3], ts[2], ts[1], 0, foundTime, iTracker);
657 B2DEBUG(15,
"make hit at SL " << iSL <<
" ID " << iTS <<
" clock " << foundTime <<
" iTracker " << iTracker);
676 void decode2DOutput(
short foundTime,
677 T2DOutputBitStream* bits,
678 StoreArray<CDCTriggerTrack>* storeTracks,
679 StoreArray<CDCTriggerFinderClone>* storeClones,
680 StoreArray<CDCTriggerSegmentHit>* tsHits)
682 const unsigned lenTrack = 121;
683 const unsigned oldTrackWidth = 6;
684 const unsigned foundWidth = 6;
685 std::array<int, 4> posTrack;
686 for (
unsigned i = 0; i < posTrack.size(); ++i) {
687 posTrack[i] = oldTrackWidth + foundWidth + lenTrack * i;
689 for (
unsigned iTracker = 0; iTracker < nTrackers; ++iTracker) {
690 const auto slv = bits->signal()[iTracker];
692 substr(clockCounterWidth, T2DOutputWidth - clockCounterWidth);
693 for (
unsigned i = 0; i < nMax2DTracksPerClock; ++i) {
695 if (slv[clockCounterWidth + oldTrackWidth + i] == one_val) {
696 TRG2DFinderTrack trk = decode2DTrack(strOutput.substr(posTrack[i], lenTrack), iTracker);
697 B2DEBUG(15,
"2DOut phi0:" << trk.phi0 <<
", omega:" << trk.omega
698 <<
", at clock " << foundTime <<
", tracker " << iTracker);
699 CDCTriggerTrack* track =
700 storeTracks->appendNew(trk.phi0, trk.omega, 0., foundTime, iTracker);
701 CDCTriggerFinderClone* clone =
702 storeClones->appendNew(slv[clockCounterWidth + i] == one_val, iTracker);
703 clone->addRelationTo(track);
710 for (
unsigned iAx = 0; iAx < nAxialTSF; ++iAx) {
711 const auto& ts = trk.ts[iAx];
713 unsigned iTS = TSIDInSL(ts[0], 2 * iAx, iTracker);
714 CDCTriggerSegmentHit* hit =
715 tsHits->appendNew(2 * iAx,
726 2000 + iTracker * 100 + foundTime,
728 track->addRelationTo(hit);
748 void decode2DInput(
short foundTime,
749 std::array<int, 4> timeOffset,
750 TSFOutputBitStream* bits,
751 StoreArray<CDCTriggerSegmentHit>* tsHits)
754 for (
unsigned iAx = 0; iAx < nAxialTSF; ++iAx) {
755 for (
unsigned iTracker = 0; iTracker < nTrackers; ++iTracker) {
756 const auto& tracker = bits->signal()[iAx][iTracker];
758 bool noMoreHit =
false;
759 for (
unsigned pos = clockCounterWidth; pos < TSFOutputWidth; pos += lenTS) {
760 std::string tsHitStr = strInput.substr(pos, lenTS);
761 B2DEBUG(50, tsHitStr);
762 tsOut ts = decodeTSHit(tsHitStr);
767 }
else if (noMoreHit) {
768 B2DEBUG(20,
"Discontinuous TS hit detected!");
770 unsigned iTS = TSIDInSL(ts[0], 2 * iAx, iTracker);
772 CDCTriggerSegmentHit hit(2 * iAx,
778 foundTime + timeOffset[iTracker],
791 if (std::none_of(tsHits->begin(), tsHits->end(),
792 [hit](CDCTriggerSegmentHit storeHit) {
793 return (storeHit.getSegmentID() == hit.getSegmentID() &&
794 storeHit.foundTime() == hit.foundTime());
796 B2DEBUG(40,
"found TS hit ID " << hit.getSegmentID() <<
797 ", SL" << 2 * iAx <<
", local ID " << iTS <<
799 tsHits->appendNew(hit);
801 B2DEBUG(45,
"skipping redundant hit ID " << hit.getSegmentID() <<
" in 2D" << iTracker);
824 CDCTriggerTrack* decodeNNInput(
short iclock,
827 StoreArray<CDCTriggerTrack>* store2DTracks,
828 StoreArray<CDCTriggerSegmentHit>* tsHits)
830 CDCTriggerTrack* track2D =
nullptr;
831 constexpr
unsigned lenTrack = 135;
833 const auto slvIn = bitsIn->signal()[iTracker];
835 strIn = strIn.substr(NN_WIDTH - 570 - 496, 982);
837 for (
unsigned iSt = 0; iSt < nStereoTSF; ++iSt) {
838 for (
unsigned iHit = 0; iHit < 10; ++iHit) {
840 unsigned pos = ((nStereoTSF - iSt - 1) * 10 + iHit) * lenTS;
841 tsOut ts = decodeTSHit(strIn.substr(pos, lenTS));
843 addTSHit(ts, iSt * 2 + 1, iTracker, tsHits, iclock);
847 std::string strTrack = strIn.substr(nStereoTSF * 10 * lenTS, lenTrack);
848 if (!std::all_of(strTrack.begin(), strTrack.end(), [](
char i) {return i ==
'0';})) {
849 std::string infobits = strTrack.substr(5 * lenTS + 14, 16);
850 strTrack =
"00" + strTrack.substr(5 * lenTS, 14) + strTrack.substr(0,
852 TRG2DFinderTrack trk2D = decode2DTrack(strTrack, iTracker);
853 B2DEBUG(15,
"NNIn phi0:" << trk2D.phi0 <<
", omega:" << trk2D.omega
854 <<
", at clock " << iclock <<
", tracker " << iTracker);
855 B2DEBUG(300,
"Content of new infobits: " << infobits);
856 std::vector<bool> foundoldtrack;
857 std::vector<bool> driftthreshold;
860 for (i = 0; i < 6; i++) {
861 if (infobits.substr(i, 1) ==
"1") {
862 foundoldtrack.push_back(
true);
863 }
else if (infobits.substr(i, 1) ==
"0") {
864 foundoldtrack.push_back(
false);
866 B2WARNING(
"Invalid input in NNBitstream appending 'false'!");
867 foundoldtrack.push_back(
false);
871 if (infobits.substr(i, 1) ==
"1") {
873 }
else if (infobits.substr(i, 1) ==
"0") {
874 valstereobit =
false;
876 B2WARNING(
"Invalid input in NNBitstream appending 'false'!");
877 valstereobit =
false;
879 for (i = 7; i < 16; i++) {
880 if (infobits.substr(i, 1) ==
"1") {
881 driftthreshold.push_back(
true);
882 }
else if (infobits.substr(i, 1) ==
"0") {
883 driftthreshold.push_back(
false);
885 B2WARNING(
"Invalid input in NNBitstream appending 'false'!");
886 driftthreshold.push_back(
false);
889 B2DEBUG(15,
"bits for foundoldtrack: " << foundoldtrack[0]
894 << foundoldtrack[5]);
895 B2DEBUG(15,
"bits for driftthreshold: " << driftthreshold[0]
903 << driftthreshold[8]);
904 B2DEBUG(15,
"bits for valstereobit: " << valstereobit);
915 B2DEBUG(15,
"make new 2D track with phi " << trk2D.phi0 <<
" omega " << trk2D.omega <<
" clock " << iclock);
916 track2D = store2DTracks->appendNew(trk2D.phi0, trk2D.omega, 0., foundoldtrack, driftthreshold, valstereobit, iclock, iTracker);
918 for (
unsigned iAx = 0; iAx < nAxialTSF; ++iAx) {
919 const auto& ts = trk2D.ts[iAx];
921 CDCTriggerSegmentHit* hit =
922 addTSHit(ts, 2 * iAx, iTracker, tsHits, iclock);
923 track2D->addRelationTo(hit);
951 void decodeNNOutput_old(
short foundTime,
953 NNBitStream* bitsOut,
954 NNBitStream* bitsSelectTS,
955 StoreArray<CDCTriggerTrack>* storeNNTracks,
956 StoreArray<CDCTriggerSegmentHit>* tsHits,
957 StoreArray<CDCTriggerMLPInput>* storeNNInputs,
958 CDCTriggerTrack* track2D)
960 const auto slvOut = bitsOut->signal()[iTracker];
962 strTrack = strTrack.substr(496, 570);
963 const auto slvSelect = bitsSelectTS->signal()[iTracker];
965 strSelect = strSelect.substr(496, 570);
966 TRGNeuroTrack trkNN = decodeNNTrack_old(strTrack, strSelect);
967 B2DEBUG(15,
"make new NN track with , z:" << trkNN.z <<
", theta:" << trkNN.theta <<
968 ", sector:" << trkNN.sector <<
", clock " << foundTime);
972 phi0 = track2D->getPhi0();
973 omega = track2D->getOmega();
975 std::vector<bool> tsvector(9,
false);
976 for (
unsigned iSL = 0; iSL < 9; ++iSL) {
977 if (trkNN.ts[iSL][3] > 0) {
978 tsvector[iSL] =
true;
981 CDCTriggerTrack* trackNN = storeNNTracks->appendNew(phi0, omega, 0.,
982 trkNN.z, cos(trkNN.theta) / sin(trkNN.theta), 0., track2D->getFoundOldTrack(), track2D->getDriftThreshold(),
983 track2D->getValidStereoBit(), trkNN.sector, tsvector, foundTime, iTracker);
984 std::vector<float> inputVector(27, 0.);
985 for (
unsigned iSL = 0; iSL < 9; ++iSL) {
986 inputVector[3 * iSL] = trkNN.inputID[iSL];
987 inputVector[3 * iSL + 1] = trkNN.inputT[iSL];
988 inputVector[3 * iSL + 2] = trkNN.inputAlpha[iSL];
990 CDCTriggerMLPInput* storeInput =
991 storeNNInputs->appendNew(inputVector, trkNN.sector);
992 trackNN->addRelationTo(storeInput);
994 track2D->addRelationTo(trackNN);
997 for (
unsigned iSL = 0; iSL < 9; ++iSL) {
998 if (trkNN.ts[iSL][3] > 0) {
999 CDCTriggerSegmentHit* hit = addTSHit(trkNN.ts[iSL] , iSL, iTracker, tsHits, foundTime);
1000 trackNN->addRelationTo(hit);
1023 StoreArray<CDCTriggerUnpacker::NNBitStream>* bitsNN,
1024 StoreArray<CDCTriggerTrack>* store2DTracks,
1025 StoreArray<CDCTriggerTrack>* storeNNTracks,
1026 StoreArray<CDCTriggerSegmentHit>* tsHits,
1027 StoreArray<CDCTriggerSegmentHit>* tsHitsAll,
1028 StoreArray<CDCTriggerMLPInput>* storeNNInputs,
1029 const DBObjPtr<CDCTriggerNeuroConfig> neurodb,
1032 for (
unsigned iTracker = 0; iTracker < nTrackers; ++iTracker) {
1033 B2DEBUG(21,
"----------------------------------------------------------------------------------------------------");
1034 B2DEBUG(21, padright(
" Unpacking Tracker: " + std::to_string(iTracker), 100));
1037 for (
short iclock = 0; iclock < bitsNN->getEntries(); ++iclock) {
1039 B2LDataField p_nnenable(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"NNEnable"));
1040 if (p_nnenable.name ==
"None") {
1041 B2DEBUG(5,
"Neurotrigger: NNENable position unknown, skipping ... ");
1043 }
else if (p_nnenable.data ==
"1") {
1044 B2DEBUG(10, padright(
"Tracker: " + std::to_string(iTracker) +
", Clock: " + std::to_string(iclock) +
" : NNEnable set!", 100));
1046 B2DEBUG(21, padright(
" UnpackerClock: " + std::to_string(iclock), 100));
1050 CDCTriggerNeuroConfig::B2FormatLine nnall;
1054 nnall.name =
"nnall";
1055 B2LDataField p_nnall(bitsNN, iclock, iTracker, nnall);
1056 B2DEBUG(22, padright(
" all bits: ", 100));
1057 B2DEBUG(22, padright(
" " + p_nnall.data, 100));
1059 B2LDataField p_driftthreshold(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"DriftThreshold"));
1060 if ((p_driftthreshold.name !=
"None") && (p_driftthreshold.data.size() == 0)) {
1061 B2DEBUG(10,
"Could not load Datafield: " << p_driftthreshold.name <<
" from bitstream. Maybe offset was out of bounds? clock: " <<
1066 B2LDataField p_valstereobit(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"ValStereoBit"));
1067 if ((p_valstereobit.name !=
"None") && (p_valstereobit.data.size() == 0)) {
1068 B2DEBUG(10,
"Could not load Datafield: " << p_valstereobit.name <<
" from bitstream. Maybe offset was out of bounds? clock: " <<
1073 B2LDataField p_foundoldtrack(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"FoundOldTrack"));
1074 if ((p_foundoldtrack.name !=
"None") && (p_foundoldtrack.data.size() == 0)) {
1075 B2DEBUG(10,
"Could not load Datafield: " << p_foundoldtrack.name <<
" from bitstream. Maybe offset was out of bounds? clock: " <<
1080 B2LDataField p_phi(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"Phi"));
1081 if ((p_phi.name !=
"None") && (p_phi.data.size() == 0)) {
1082 B2DEBUG(10,
"Could not load Datafield: " << p_phi.name <<
" from bitstream. Maybe offset was out of bounds? clock: " << iclock);
1086 B2LDataField p_omega(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"Omega"));
1087 if ((p_omega.name !=
"None") && (p_omega.data.size() == 0)) {
1088 B2DEBUG(10,
"Could not load Datafield: " << p_omega.name <<
" from bitstream. Maybe offset was out of bounds? clock: " << iclock);
1092 B2LDataField p_ts8(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"TS8"));
1093 if ((p_ts8.name !=
"None") && (p_ts8.data.size() == 0)) {
1094 B2DEBUG(10,
"Could not load Datafield: " << p_ts8.name <<
" from bitstream. Maybe offset was out of bounds? clock: " << iclock);
1098 B2LDataField p_ts6(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"TS6"));
1099 if ((p_ts6.name !=
"None") && (p_ts6.data.size() == 0)) {
1100 B2DEBUG(10,
"Could not load Datafield: " << p_ts6.name <<
" from bitstream. Maybe offset was out of bounds? clock: " << iclock);
1104 B2LDataField p_ts4(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"TS4"));
1105 if ((p_ts4.name !=
"None") && (p_ts4.data.size() == 0)) {
1106 B2DEBUG(10,
"Could not load Datafield: " << p_ts4.name <<
" from bitstream. Maybe offset was out of bounds? clock: " << iclock);
1110 B2LDataField p_ts2(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"TS2"));
1111 if ((p_ts2.name !=
"None") && (p_ts2.data.size() == 0)) {
1112 B2DEBUG(10,
"Could not load Datafield: " << p_ts2.name <<
" from bitstream. Maybe offset was out of bounds? clock: " << iclock);
1116 B2LDataField p_ts0(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"TS0"));
1117 if ((p_ts0.name !=
"None") && (p_ts0.data.size() == 0)) {
1118 B2DEBUG(10,
"Could not load Datafield: " << p_ts0.name <<
" from bitstream. Maybe offset was out of bounds? clock: " << iclock);
1122 B2LDataField p_tsf1(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"TSF1"));
1123 if ((p_tsf1.name !=
"None") && (p_tsf1.data.size() == 0)) {
1124 B2DEBUG(10,
"Could not load Datafield: " << p_tsf1.name <<
" from bitstream. Maybe offset was out of bounds? clock: " << iclock);
1128 B2LDataField p_tsf3(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"TSF3"));
1129 if ((p_tsf3.name !=
"None") && (p_tsf3.data.size() == 0)) {
1130 B2DEBUG(10,
"Could not load Datafield: " << p_tsf3.name <<
" from bitstream. Maybe offset was out of bounds? clock: " << iclock);
1134 B2LDataField p_tsf5(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"TSF5"));
1135 if ((p_tsf5.name !=
"None") && (p_tsf5.data.size() == 0)) {
1136 B2DEBUG(10,
"Could not load Datafield: " << p_tsf5.name <<
" from bitstream. Maybe offset was out of bounds? clock: " << iclock);
1140 B2LDataField p_tsf7(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"TSF7"));
1141 if ((p_tsf7.name !=
"None") && (p_tsf7.data.size() == 0)) {
1142 B2DEBUG(10,
"Could not load Datafield: " << p_tsf7.name <<
" from bitstream. Maybe offset was out of bounds? clock: " << iclock);
1146 B2LDataField p_tsfsel(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"TSFsel"));
1147 if ((p_tsfsel.name !=
"None") && (p_tsfsel.data.size() == 0)) {
1148 B2DEBUG(10,
"Could not load Datafield: " << p_tsfsel.name <<
" from bitstream. Maybe offset was out of bounds? clock: " << iclock);
1152 B2LDataField p_mlpin_alpha(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"MLPIn_alpha"));
1153 if ((p_mlpin_alpha.name !=
"None") && (p_mlpin_alpha.data.size() == 0)) {
1154 B2DEBUG(10,
"Could not load Datafield: " << p_mlpin_alpha.name <<
" from bitstream. Maybe offset was out of bounds? clock: " <<
1159 B2LDataField p_mlpin_drifttime(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"MLPIn_driftt"));
1160 if ((p_mlpin_drifttime.name !=
"None") && (p_mlpin_drifttime.data.size() == 0)) {
1161 B2DEBUG(10,
"Could not load Datafield: " << p_mlpin_drifttime.name <<
" from bitstream. Maybe offset was out of bounds? clock: " <<
1166 B2LDataField p_mlpin_id(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"MLPIn_id"));
1167 if ((p_mlpin_id.name !=
"None") && (p_mlpin_id.data.size() == 0)) {
1168 B2DEBUG(10,
"Could not load Datafield: " << p_mlpin_id.name <<
" from bitstream. Maybe offset was out of bounds? clock: " <<
1173 B2LDataField p_netsel(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"Netsel"));
1174 if ((p_netsel.name !=
"None") && (p_netsel.data.size() == 0)) {
1175 B2DEBUG(10,
"Could not load Datafield: " << p_netsel.name <<
" from bitstream. Maybe offset was out of bounds? clock: " << iclock);
1179 B2LDataField p_mlpout_z(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"MLPOut_z"));
1180 if ((p_mlpout_z.name !=
"None") && (p_mlpout_z.data.size() == 0)) {
1181 B2DEBUG(10,
"Could not load Datafield: " << p_mlpout_z.name <<
" from bitstream. Maybe offset was out of bounds? clock: " <<
1186 B2LDataField p_mlpout_theta(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"MLPOut_theta"));
1187 if ((p_mlpout_theta.name !=
"None") && (p_mlpout_theta.data.size() == 0)) {
1188 B2DEBUG(10,
"Could not load Datafield: " << p_mlpout_theta.name <<
" from bitstream. Maybe offset was out of bounds? clock: " <<
1193 B2LDataField p_2dcc(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"2dcc"));
1194 if ((p_2dcc.name !=
"None") && (p_2dcc.data.size() == 0)) {
1195 B2DEBUG(10,
"Could not load Datafield: " << p_2dcc.name <<
" from bitstream. Maybe offset was out of bounds? clock: " << iclock);
1199 B2LDataField p_extendedpts(bitsNN, iclock, iTracker, neurodb->getB2FormatLine(
"extendedPriorityTimes"));
1200 if ((p_extendedpts.name !=
"None") && (p_extendedpts.data.size() == 0)) {
1201 B2DEBUG(10,
"Could not load Datafield: " << p_extendedpts.name <<
" from bitstream. Maybe offset was out of bounds? clock: " <<
1207 CDCTriggerTrack* track2D =
nullptr;
1211 B2DEBUG(21, padright(
" Stereos: ", 100));
1212 for (
auto stereolayer : {p_tsf1, p_tsf3, p_tsf5, p_tsf7}) {
1213 if (stereolayer.name ==
"None") {
1214 B2ERROR(
"Error in CDCTriggerNeuroConfig Payload, position of stereo tsf could not be found!");
1217 std::string tsstr =
" | ";
1218 for (
unsigned iHit = 0; iHit < 10; ++iHit) {
1219 tsOut ts = (sim13dt) ? decodeTSHit_sim(stereolayer.data.substr(iHit * lenTS, lenTS),
1220 p_2dcc.data) : decodeTSHit(stereolayer.data.substr(iHit * lenTS, lenTS));
1222 unsigned iTS = TSIDInSL(ts[0], sln * 2 + 1, iTracker);
1223 tsstr += std::to_string(iTS) +
", " + std::to_string(ts[1]) +
", " + std::to_string(ts[2]) +
", " + std::to_string(ts[3]) +
" | ";
1224 addTSHit(ts, sln * 2 + 1, iTracker, tsHitsAll, iclock);
1227 B2DEBUG(21, padright(
" SL" + std::to_string(sln * 2 + 1) + tsstr, 100));
1231 B2DEBUG(21, padright(
" 2DCC: " + std::to_string(std::stoi(p_2dcc.data, 0, 2)) +
", (" + p_2dcc.data +
")", 100));
1232 if (p_nnenable.data ==
"1") {
1233 std::vector<bool> foundoldtrack{
false};
1234 std::vector<bool> driftthreshold{
false};
1236 if (p_foundoldtrack.name !=
"None") {
1237 foundoldtrack = decodefoundoldtrack(p_foundoldtrack.data);
1239 if (p_driftthreshold.name !=
"None") {
1240 driftthreshold = decodedriftthreshold(p_driftthreshold.data);
1242 if (p_valstereobit.name !=
"None") {
1243 valstereobit = decodevalstereobit(p_valstereobit.data);
1246 if (std::all_of(p_phi.data.begin(), p_phi.data.end(), [](
char i) {return i == 0;})) {
1247 B2ERROR(
"Empty Phi Value found for 2DTrack, should not happen!");
1250 TRG2DFinderTrack trk2D = decode2DTrack(
1262 track2D = store2DTracks->appendNew(trk2D.phi0, trk2D.omega, 0., foundoldtrack, driftthreshold, valstereobit, iclock, iTracker);
1263 B2DEBUG(12, padright(
" 2DTrack: (phi=" + std::to_string(trk2D.phi0) +
", omega=" + std::to_string(
1264 trk2D.omega) +
", update=" + std::to_string(foundoldtrack[1]) +
")", 100));
1268 for (
unsigned iAx = 0; iAx < nAxialTSF; ++iAx) {
1269 const auto& ts = trk2D.ts[iAx];
1271 CDCTriggerSegmentHit* hit =
1272 addTSHit(ts, 2 * iAx, iTracker, tsHitsAll, iclock);
1273 unsigned iTS = TSIDInSL(ts[0], iAx * 2, iTracker);
1274 tsstr +=
"(SL" + std::to_string(iAx * 2) +
", " + std::to_string(iTS) +
", " + std::to_string(ts[1]) +
", " + std::to_string(
1275 ts[2]) +
", " + std::to_string(ts[3]) +
"),";
1276 track2D->addRelationTo(hit);
1279 B2DEBUG(16, padright(
" 2DTrack TS: " + tsstr, 100));
1283 TRGNeuroTrack trkNN;
1284 trkNN = decodeNNTrack(p_mlpout_z.data,
1285 p_mlpout_theta.data,
1288 p_mlpin_drifttime.data,
1297 B2DEBUG(11, padright(
" NNTrack: (z=" + std::to_string(trkNN.z) +
", theta=" + std::to_string(trkNN.theta) +
")", 100));
1299 double phi0 = track2D->getPhi0();
1300 double omega = track2D->getOmega();
1302 std::vector<bool> tsvector(9,
false);
1304 for (
unsigned iSL = 0; iSL < 9; ++iSL) {
1305 if (trkNN.ts[iSL][3] > 0) {
1306 tsvector[iSL] =
true;
1307 unsigned iTS = TSIDInSL(trkNN.ts[iSL][0], iSL, iTracker);
1308 tsstr +=
"(SL" + std::to_string(iSL) +
", " + std::to_string(iTS) +
", " + std::to_string(trkNN.ts[iSL][1]) +
", " + std::to_string(
1309 trkNN.ts[iSL][2]) +
", " + std::to_string(trkNN.ts[iSL][3]) +
"),\n";
1313 tsstr +=
"( - ),\n";
1316 B2DEBUG(15, padright(
" NNTrack TS: " + tsstr, 100));
1318 CDCTriggerTrack* trackNN = storeNNTracks->appendNew(phi0, omega, 0.,
1319 trkNN.z, cos(trkNN.theta) / sin(trkNN.theta), 0., track2D->getFoundOldTrack(), track2D->getDriftThreshold(),
1320 track2D->getValidStereoBit(), trkNN.sector, tsvector, iclock, iTracker);
1321 std::vector<float> inputVector(27, 0.);
1322 for (
unsigned iSL = 0; iSL < 9; ++iSL) {
1323 inputVector[3 * iSL] = trkNN.inputID[iSL];
1324 inputVector[3 * iSL + 1] = trkNN.inputT[iSL];
1325 inputVector[3 * iSL + 2] = trkNN.inputAlpha[iSL];
1327 CDCTriggerMLPInput* storeInput =
1328 storeNNInputs->appendNew(inputVector, trkNN.sector);
1329 trackNN->addRelationTo(storeInput);
1330 track2D->addRelationTo(trackNN);
1332 for (
unsigned iSL = 0; iSL < 9; ++iSL) {
1333 if (trkNN.ts[iSL][3] > 0) {
1334 CDCTriggerSegmentHit* hit =
nullptr;
1362 hit = addTSHit(trkNN.ts[iSL] , iSL, iTracker, tsHits, iclock);
1366 trackNN->addRelationTo(hit);
1368 track2D->addRelationTo(hit);
1392 void decodeNNIO_old(
1393 StoreArray<CDCTriggerUnpacker::NNBitStream>* bitsNN,
1394 StoreArray<CDCTriggerTrack>* store2DTracks,
1395 StoreArray<CDCTriggerTrack>* storeNNTracks,
1396 StoreArray<CDCTriggerSegmentHit>* tsHits,
1397 StoreArray<CDCTriggerMLPInput>* storeNNInputs)
1399 for (
short iclock = 0; iclock < bitsNN->getEntries(); ++iclock) {
1400 NNBitStream* bitsIn = (*bitsNN)[iclock];
1401 NNBitStream* bitsOutEnable = (*bitsNN)[iclock];
1402 for (
unsigned iTracker = 0; iTracker < nTrackers; ++iTracker) {
1403 const auto slvOutEnable = bitsOutEnable->signal()[iTracker];
1404 const auto slvIn = bitsIn->signal()[iTracker];
1407 if (stringOutEnable.c_str()[0] ==
'1') {
1408 CDCTriggerTrack* nntrack2D = decodeNNInput(iclock, iTracker, bitsIn, store2DTracks, tsHits);
1410 int foundTime = iclock;
1411 if (foundTime < bitsNN->getEntries()) {
1412 NNBitStream* bitsOut = (*bitsNN)[foundTime];
1413 NNBitStream* bitsSelectTS = (*bitsNN)[iclock];
1414 decodeNNOutput_old(iclock, iTracker, bitsOut, bitsSelectTS,
1415 storeNNTracks, tsHits, storeNNInputs,