CbmRoot
Loading...
Searching...
No Matches
bmon/ReadoutConfig.cxx
Go to the documentation of this file.
1/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Dominik Smith [committer] */
4
5#include "ReadoutConfig.h"
6
8#include "CbmTofAddress.h"
9#include "Exceptions.h"
10#include "gDpbMessv100.h"
11
12#include <bitset>
13#include <iomanip>
14
15#include <fmt/format.h>
16
17using namespace std;
18
20{
21 // --- Constructor ------------------------------------------------------------------
23 // ------------------------------------------------------------------------------------
24
25 // --- Destructor -----------------------------------------------------------------
27 // ------------------------------------------------------------------------------------
28
29 // --- Equipment IDs --------------------------------------------------------------
30 std::vector<uint16_t> ReadoutConfig::GetEquipmentIds()
31 {
32 std::vector<uint16_t> result;
33 for (auto& entry : fReadoutMap)
34 result.push_back(entry.first);
35 return result;
36 }
37 // ------------------------------------------------------------------------------------
38
39 // --- Number of elinks for a component / equipment -------------------------------
40 size_t ReadoutConfig::GetNumElinks(uint16_t equipmentId)
41 {
42 size_t result = 0;
43 auto it = fReadoutMap.find(equipmentId);
44 if (it != fReadoutMap.end()) result = fReadoutMap[equipmentId].size();
45 return result;
46 }
47 // ------------------------------------------------------------------------------------
48
49
50 // --- Mapping (equimentId, elink) -> address[channel] ------------------------------
51 std::vector<uint32_t> ReadoutConfig::Map(uint16_t equipmentId, uint16_t elinkId)
52 {
53 std::vector<uint32_t> result;
54 auto equipIter = fReadoutMap.find(equipmentId);
55 if (equipIter != fReadoutMap.end()) {
56 if (elinkId < equipIter->second.size()) {
57 result = equipIter->second.at(elinkId);
58 }
59 }
60 return result;
61 }
62 // ------------------------------------------------------------------------------------
63
64
65 // --- Mapping (equimentId, elink) -> time offset -------------------------------------
66 int32_t ReadoutConfig::GetElinkTimeOffset(uint16_t equipmentId, uint16_t elinkId)
67 {
68 int32_t result = 0;
69 auto equipIter = fTimeOffsetMap.find(equipmentId);
70 if (equipIter != fTimeOffsetMap.end()) {
71 if (elinkId < equipIter->second.size()) {
72 result = equipIter->second.at(elinkId);
73 }
74 }
75 return result;
76 }
77 // ------------------------------------------------------------------------------------
78
79
81 {
83
84 // Constructing the map (equipmentId, eLink, channel) -> (TOF address)
85 const uint32_t numChanPerComp = pars.NChansPerComponent();
86
87 // Constructs the fviRpcChUId array
89
90 for (uint16_t comp = 0; comp < pars.NComponents(); comp++) {
91
92 uint16_t equipment = pars.eqIds.at(comp);
93 fReadoutMap[equipment].resize(pars.NElinksPerComponent());
94 fTimeOffsetMap[equipment].resize(pars.NElinksPerComponent());
95
96 for (uint16_t elink = 0; elink < pars.NElinksPerComponent(); elink++) {
97 fReadoutMap[equipment][elink].resize(pars.nChannelsPerAsic);
98
99 const uint32_t crob = elink / pars.NElinksPerCrob() + comp * pars.NCrobsPerComponent();
100 fTimeOffsetMap[equipment][elink] = pars.crobs[crob].timeOffset;
101
102 for (uint16_t channel = 0; channel < pars.nChannelsPerAsic; channel++) {
103
104 const uint32_t chanInComp = elink * pars.nChannelsPerAsic + channel;
105 uint32_t chanInSys = comp * numChanPerComp + chanInComp;
106
107 { // hack? perhaps can be removed
108 const int numFullFlims = 8;
109 if (comp > numFullFlims) {
110 chanInSys -= (comp - numFullFlims) * numChanPerComp / 2;
111 }
112 }
113
114 const uint32_t chanUId = fviRpcChUId[chanInSys];
115 fReadoutMap[equipment][elink][channel] = chanUId;
116 } //# channel
117 } //# elink
118 } //# component
119 }
120
121 // -------------------------------------------------------------------------
123 {
124 const uint32_t numAsics = pars.NComponents() * pars.nFebsPerComponent * pars.nAsicsPerFeb;
125 const uint32_t numChan = numAsics * pars.nChannelsPerAsic;
126 fviRpcChUId.resize(numChan);
127
128 L_(debug) << "============================================================";
129 L_(debug) << "================== BMON Mapping ============================";
130
131 uint32_t uCh = 0;
132 for (uint32_t uGbtx = 0; uGbtx < pars.NCrobs(); ++uGbtx) {
133 const uint32_t uCh0 = uCh;
134 const auto& crob = pars.crobs.at(uGbtx);
135 switch (crob.rpcType) {
136 case 5: {
138 BuildChannelsUidMapBmon(uCh, uGbtx, pars);
139 break;
140 }
141 case 99: {
143 BuildChannelsUidMapBmon_2022(uCh, uGbtx, pars);
144 break;
145 }
146 case -1: {
147 L_(warning) << " Found unused GBTX link at uCh = " << uCh;
148 uCh += 160;
149 break;
150 }
151 default: {
152 L_(error) << "Invalid Bmon Type specifier for GBTx " << std::setw(2) << uGbtx << ": " << crob.rpcType;
153 }
154 } // switch (crob.rpcType)
155 if ((int32_t)(uCh - uCh0) != pars.nFebsPerComponent * pars.nAsicsPerFeb * pars.nChannelsPerAsic / 2) {
156 throw FatalError("Bmon mapping error for Gbtx {}, diff = {}, expected = {}", uGbtx, uCh - uCh0,
157 pars.nFebsPerComponent * pars.nAsicsPerFeb * pars.nChannelsPerAsic / 2);
158 }
159
160 L_(info) << " Map for CROB " << uGbtx;
161 std::vector<int32_t> vAddrBunch(8, -1);
162 for (uint32_t uChPrint = uCh0; uChPrint < uCh; ++uChPrint) {
163 vAddrBunch[uChPrint % 8] = fviRpcChUId[uChPrint];
164 if (7 == uChPrint % 8) {
165 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << " 0x" << std::setw(8)
166 << vAddrBunch[1] << " 0x" << std::setw(8) << vAddrBunch[2] << " 0x" << std::setw(8) << vAddrBunch[3]
167 << " 0x" << std::setw(8) << vAddrBunch[4] << " 0x" << std::setw(8) << vAddrBunch[5] << " 0x"
168 << std::setw(8) << vAddrBunch[6] << " 0x" << std::setw(8) << vAddrBunch[7] << std::dec;
169 }
170 }
171 switch (uCh % 8) {
172 case 0: {
173 break;
174 }
175 case 1: {
176 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << std::dec;
177 break;
178 }
179 case 2: {
180 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << " 0x" << std::setw(8)
181 << vAddrBunch[1] << std::dec;
182 break;
183 }
184 case 3: {
185 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << " 0x" << std::setw(8)
186 << vAddrBunch[1] << " 0x" << std::setw(8) << vAddrBunch[2] << std::dec;
187 break;
188 }
189 case 4: {
190 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << " 0x" << std::setw(8)
191 << vAddrBunch[1] << " 0x" << std::setw(8) << vAddrBunch[2] << " 0x" << std::setw(8) << vAddrBunch[3]
192 << std::dec;
193 break;
194 }
195 case 5: {
196 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << " 0x" << std::setw(8)
197 << vAddrBunch[1] << " 0x" << std::setw(8) << vAddrBunch[2] << " 0x" << std::setw(8) << vAddrBunch[3]
198 << " 0x" << std::setw(8) << vAddrBunch[4] << std::dec;
199 break;
200 }
201 case 6: {
202 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << " 0x" << std::setw(8)
203 << vAddrBunch[1] << " 0x" << std::setw(8) << vAddrBunch[2] << " 0x" << std::setw(8) << vAddrBunch[3]
204 << " 0x" << std::setw(8) << vAddrBunch[4] << " 0x" << std::setw(8) << vAddrBunch[5] << std::dec;
205 break;
206 }
207 case 7: {
208 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << " 0x" << std::setw(8)
209 << vAddrBunch[1] << " 0x" << std::setw(8) << vAddrBunch[2] << " 0x" << std::setw(8) << vAddrBunch[3]
210 << " 0x" << std::setw(8) << vAddrBunch[4] << " 0x" << std::setw(8) << vAddrBunch[5] << " 0x"
211 << std::setw(8) << vAddrBunch[6] << std::dec;
212 break;
213 }
214 }
215 } // for (UInt_t uGbtx = 0; uGbtx < numCrob; ++uGbtx)
216
217 L_(debug) << "============================================================";
218 }
219
220 // -------------------------------------------------------------------------
221 void ReadoutConfig::BuildChannelsUidMapBmon(uint32_t& uCh, uint32_t uGbtx, const ReadoutSetup& pars)
222 {
223 const auto& crob = pars.crobs.at(uGbtx);
224 L_(debug) << " Map diamond " << crob.moduleId << " at GBTX " << uGbtx << " - uCh = " << uCh;
225 for (uint32_t uGet4 = 0; uGet4 < pars.NElinksPerCrob(); ++uGet4) {
226 for (uint32_t uGet4Ch = 0; uGet4Ch < pars.nChannelsPerAsic; ++uGet4Ch) {
228 if (uGet4 < 32 && 0 == uGet4Ch && -1 < crob.moduleId) {
229 uint32_t uChannelBmon = uGet4 + 32 * crob.rpcSide;
230 uChannelBmon /= 8;
231 fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(crob.moduleId, 0, uChannelBmon, 0, crob.rpcType);
232 L_(debug) << " Bmon channel: " << uChannelBmon << " from GBTx " << uGbtx << " , indx " << uCh
233 << " address 0x" << std::hex << std::setfill('0') << std::setw(8) << fviRpcChUId[uCh] << std::dec;
234 } // Valid Bmon channel
235 else {
236 fviRpcChUId[uCh] = 0;
237 } // Invalid Bmon channel
238 uCh++;
239 }
240 }
241 }
242
243 // -------------------------------------------------------------------------
244 void ReadoutConfig::BuildChannelsUidMapBmon_2022(uint32_t& uCh, uint32_t uGbtx, const ReadoutSetup& pars)
245 {
246 const auto& crob = pars.crobs.at(uGbtx);
247 L_(debug) << " Map 2022 diamond " << crob.moduleId << " at GBTX " << uGbtx << " - uCh = " << uCh;
248 for (uint32_t uGet4 = 0; uGet4 < pars.NElinksPerCrob(); ++uGet4) {
249 for (uint32_t uGet4Ch = 0; uGet4Ch < pars.nChannelsPerAsic; ++uGet4Ch) {
251 if (-1 < crob.moduleId && uGet4 < 32 && 0 == uGet4 % 4 && 0 == uGet4Ch) {
254 uint32_t uChannelBmon = (uGet4 / 8 + 4 * (uGbtx / 2)) % 16;
256 fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(crob.moduleId, 0, uChannelBmon, crob.rpcSide, 5);
257 L_(debug) << " Bmon channel: " << uChannelBmon << " side " << crob.rpcSide << " from GBTx " << uGbtx
258 << " , indx " << uCh << " address 0x" << std::hex << std::setfill('0') << std::setw(8)
259 << fviRpcChUId[uCh] << std::dec;
260 } // Valid Bmon channel
261 else {
262 fviRpcChUId[uCh] = 0;
263 } // Invalid Bmon channel
264 uCh++;
265 }
266 }
267 }
268} // namespace cbm::algo::bmon
#define L_(level)
static uint32_t GetUniqueAddress(uint32_t Sm, uint32_t Rpc, uint32_t Channel, uint32_t Side=0, uint32_t SmType=0, uint32_t RpcType=0)
std::map< uint16_t, std::vector< std::vector< uint32_t > > > fReadoutMap
void Init(const ReadoutSetup &pars)
Initialisation of readout map.
ReadoutConfig(const ReadoutSetup &pars)
Constructor.
int32_t GetElinkTimeOffset(uint16_t equipId, uint16_t elink)
API: Mapping from component and elink to time offset.
std::vector< uint16_t > GetEquipmentIds()
Equipment in the configuration.
std::vector< uint32_t > Map(uint16_t equipId, uint16_t elink)
API: Mapping from component and elink to addresses per channel.
std::map< uint16_t, std::vector< int32_t > > fTimeOffsetMap
void BuildChannelsUidMap(const ReadoutSetup &pars)
size_t GetNumElinks(uint16_t equipmentId)
Number of elinks of a component.
void BuildChannelsUidMapBmon(uint32_t &uCh, uint32_t uGbtx, const ReadoutSetup &pars)
std::vector< int32_t > fviRpcChUId
UID/address for each channel, build from type, side and module.
void BuildChannelsUidMapBmon_2022(uint32_t &uCh, uint32_t uGbtx, const ReadoutSetup &pars)
Hash for CbmL1LinkKey.
Indicates an unrecoverable error. Should tear down the process.
Definition Exceptions.h:34
Readout setup / Hardware cabling for BMon Used to create the hardware mapping for the BMon unpacker.