CbmRoot
Loading...
Searching...
No Matches
mvd/UnpackMS.cxx
Go to the documentation of this file.
1/* Copyright (C) 2025 IKF Frankfurt University, Frankfurt am Main
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Ajit Kumar [committer], Bartosz Sobol, Benedikt Gutsche */
4
6
8
9#include <cassert>
10#include <cmath>
11#include <iostream>
12#include <limits>
13#include <utility>
14#include <vector>
15
16using std::unique_ptr;
17using std::vector;
18
19
20namespace cbm::algo::mvd
21{
22 uint32_t frame_nbr_l = 0;
23 uint32_t frame_nbr_m = 0;
24 int frLen = 0;
25
26 UnpackMS::UnpackMS(const UnpackPar& pars, const uint64_t& frameLengthNs)
27 : fParams(pars)
28 , fFrameLengthNs(frameLengthNs)
29 {
30 }
31
32 UnpackMS::~UnpackMS() = default;
33
34
35 // ---- Algorithm execution ---------------------------------------------
36 UnpackMS::Result_t UnpackMS::operator()(const uint8_t* msContent, const fles::MicrosliceDescriptor& msDescr,
37 const uint64_t tTimeslice) const
38 {
39
40 // --- Output data
41 Result_t result = {};
42
43 // printMsContent(msContent, msDescr.size);
44
45 auto msSize = msDescr.size / 4; // Size in 32 bit blocks;
46 const uint32_t* pInBuff = reinterpret_cast<const uint32_t*>(msContent);
47
48 auto eq_idx = msDescr.eq_id; // equipment id
49
50 const uint32_t len = msSize;
51 const uint32_t* arr = pInBuff;
52 unsigned int n = 0;
53 uint32_t data;
54
55 for (; n < len; n++) {
56 data = arr[n];
57 if (data == 0xFCAAFCAA) continue;
58 ProcessData(data, tTimeslice, std::get<0>(result), std::get<1>(result), std::get<2>(result), eq_idx);
59 }
60
61 return result;
62 }
63
64 // ----- Process hit message --------------------------------------------
65 void UnpackMS::ProcessData(const uint32_t& data, const uint64_t& time, std::vector<CbmMvdRawDigi>& digiVec,
66 UnpackMonitorData& /*monitor*/, UnpackAuxData& /*aux*/, uint16_t& eq_idx) const
67 {
68 uint32_t column = std::numeric_limits<uint32_t>::max();
69 uint32_t row = std::numeric_limits<uint32_t>::max();
70
71 if ((data & 0xFF000000) == 0xFE000000) {
72 headersnow++;
73
74 if (headersnow == 1) {
75 frame_nbr_l = data & 0xFF;
76 frame_nbr_l += (data & 0xFF0000) >> 8;
77 }
78 else if (headersnow == 2) {
79 frame_nbr_l += (data & 0xFF) << 16;
80 frame_nbr_l += (data & 0xFF0000) << 8;
81 }
82 else if (headersnow == 3) {
83 frame_nbr_m = data & 0xFF;
84 frame_nbr_m += (data & 0xFF0000) >> 8;
85 }
86 else if (headersnow == 4) {
87 frame_nbr_m += (data & 0xFF) << 16;
88 frame_nbr_m += (data & 0xFF0000) << 8;
89 uint64_t tmp_l = static_cast<uint64_t>(frame_nbr_l);
90 uint64_t tmp_m = static_cast<uint64_t>(frame_nbr_m);
91 frameTime = (tmp_m << 32) + tmp_l;
92 frLen = 0;
93 }
94 }
95
96 //End of frame - process frame results and error flags
97 else if ((data & 0xFF00) == 0xFF00) {
98 headersnow = 0;
99
100 // if(frLen > 0) digiVec.emplace_back(eq_idx, 0, 0, frLen, 0.1, 0.1, frameTime-time, 0, frameTime);
101 }
102
103 else {
104 headersnow = 0;
105
106 //New region starts - save region number
107 if ((data & 0xFF00) == 0xFD00) {
108 int tmp = data & 0xFF;
109 if (tmp > 63) return;
110 region = tmp;
111 }
112 else {
113
114 frLen++;
115
116 dcd_pxl(region, data & 0xFFFF, column, row);
117 int code = data & 0b111;
118
119 if (code & 0b1) {
120 int codeTmp = 1;
121 dcd_pxl(region, ((data & 0xFFFF) + (codeTmp << 6)), column, row);
122 }
123
124 if (code & 0b10) {
125 int codeTmp = 2;
126 dcd_pxl(region, ((data & 0xFFFF) + (codeTmp << 6)), column, row);
127 }
128
129 if (code & 0b100) {
130 int codeTmp = 3;
131 dcd_pxl(region, ((data & 0xFFFF) + (codeTmp << 6)), column, row);
132 }
133 }
134
135 //Second Hit data - decode pixel address and save
136 if ((data & 0xFF000000) != 0xFC000000) {
137
138 dcd_pxl(region, data >> 16, column, row);
139 int code = (data >> 16) & 0b111;
140
141 if (code & 0b1) {
142 int codeTmp = 1;
143 dcd_pxl(region, ((data >> 16) + (codeTmp << 6)), column, row);
144 }
145
146 if (code & 0b10) {
147 int codeTmp = 2;
148 dcd_pxl(region, ((data >> 16) + (codeTmp << 6)), column, row);
149 }
150
151 if (code & 0b100) {
152 int codeTmp = 3;
153 dcd_pxl(region, ((data >> 16) + (codeTmp << 6)), column, row);
154 }
155 }
156 }
157 if (std::numeric_limits<uint32_t>::max() == row && std::numeric_limits<uint32_t>::max() == column) return;
158
159 if (eq_idx == 0) column = 1023 - column; // both sensor is facing each other for mcbm
160
161 // --- Create MVD address
162 uint32_t address = CbmMvdAddress::GetAddress(eq_idx, 0, 0, 0, 0, 0, row, column);
163 // --- Create output digi
164 // => FIXME: for support of mCBM 2025, compute frame-number from frameTime and enforce frame-number reset on each TS
165 // => FIXME: unprotected conversion from 64b time in TS to 32b CbmMvdRawDigi time, safe for all TS sizes < ~4.294s
166 uint64_t timeInTs = frameTime - time;
167 digiVec.emplace_back(address, timeInTs, timeInTs / fFrameLengthNs, frameTime);
168 }
169
170 void UnpackMS::dcd_pxl(const uint16_t& regionIn, const uint16_t& word, uint32_t& column, uint32_t& row) const
171 {
172 unsigned pixelcode = (word >> 6) & 0x3ff;
173 unsigned side = 0, topdown = 0;
174 if ((pixelcode & 3) == 0x1 || (pixelcode & 3) == 0x2) side = 1;
175 if ((pixelcode & 3) == 0x3 || (pixelcode & 3) == 0x2) topdown = 1;
176 row = (pixelcode >> 2) * 2 + topdown;
177 column = (((word >> 3) & 0x7) + regionIn * 8) * 2 + side;
178 }
179
180
181 // --------------------------------------------------------------------------
182 void UnpackMS::printMsContent(const uint8_t* msContent, size_t size) const
183 {
184 for (size_t i = 0; i < size; ++i) {
185 std::cout << std::hex << static_cast<int>(msContent[i]) << " ";
186 }
187 std::cout << std::dec << std::endl; // Reset formatting
188 }
189} // namespace cbm::algo::mvd
static constexpr size_t size()
Definition KfSimdPseudo.h:2
static uint32_t GetAddress(int32_t station=0, int32_t sideUD=0, int32_t sideLR=0, int32_t sideTB=0, int32_t ladder=0, int32_t sensor=0, int32_t sensorY=0, int32_t sensorX=0)
std::tuple< std::vector< Digi_t >, Monitor_t, Aux_t > Result_t
uint64_t fFrameLengthNs
Frame length in ns, default value from mCBM 2025.
UnpackPar fParams
Parameter container.
void ProcessData(const uint32_t &data, const uint64_t &time, std::vector< CbmMvdRawDigi > &digiVec, UnpackMonitorData &monitor, UnpackAuxData &aux, uint16_t &eq_idx) const
Process a hit message.
void dcd_pxl(const uint16_t &regionIn, const uint16_t &word, uint32_t &column, uint32_t &row) const
~UnpackMS() override
Destructor.
UnpackMS(const UnpackPar &pars, const uint64_t &frameLengthNs)
Construct with parameters.
Result_t operator()(const uint8_t *msContent, const fles::MicrosliceDescriptor &msDescr, const uint64_t tTimeslice) const override
Algorithm execution.
void printMsContent(const uint8_t *msContent, size_t size) const
uint32_t frame_nbr_m
uint32_t frame_nbr_l
Parameters required for the MVD unpacking (specific to one component)