CbmRoot
Loading...
Searching...
No Matches
tof/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
15using namespace std;
16
18
19namespace cbm::algo::tof
20{
21
22 // --- Constructor ------------------------------------------------------------------
24 // ------------------------------------------------------------------------------------
25
26 // --- Destructor -----------------------------------------------------------------
28 // ------------------------------------------------------------------------------------
29
30 // --- Equipment IDs --------------------------------------------------------------
31 std::vector<uint16_t> ReadoutConfig::GetEquipmentIds()
32 {
33 std::vector<uint16_t> result;
34 for (auto& entry : fReadoutMap)
35 result.push_back(entry.first);
36 return result;
37 }
38 // ------------------------------------------------------------------------------------
39
40 // --- Number of elinks for a component / equipment -------------------------------
41 size_t ReadoutConfig::GetNumElinks(uint16_t equipmentId)
42 {
43 size_t result = 0;
44 auto it = fReadoutMap.find(equipmentId);
45 if (it != fReadoutMap.end()) result = fReadoutMap[equipmentId].size();
46 return result;
47 }
48 // ------------------------------------------------------------------------------------
49
50
51 // --- Mapping (equimentId, elink) -> address[channel] ------------------------------
52 std::vector<uint32_t> ReadoutConfig::Map(uint16_t equipmentId, uint16_t elinkId)
53 {
54 std::vector<uint32_t> result;
55 auto equipIter = fReadoutMap.find(equipmentId);
56 if (equipIter != fReadoutMap.end()) {
57 if (elinkId < equipIter->second.size()) {
58 result = equipIter->second.at(elinkId);
59 }
60 }
61 return result;
62 }
63 // ------------------------------------------------------------------------------------
64
65
66 // --- Mapping (equimentId, elink) -> time offset -------------------------------------
67 int32_t ReadoutConfig::GetElinkTimeOffset(uint16_t equipmentId, uint16_t elinkId)
68 {
69 int32_t result = 0;
70 auto equipIter = fTimeOffsetMap.find(equipmentId);
71 if (equipIter != fTimeOffsetMap.end()) {
72 if (elinkId < equipIter->second.size()) {
73 result = equipIter->second.at(elinkId);
74 }
75 }
76 return result;
77 }
78 // ------------------------------------------------------------------------------------
79
80
82 {
84
85 // Constructing the map (equipmentId, eLink, channel) -> (TOF address)
86 const uint32_t numChanPerComp = pars.NChansPerComponent();
87
88 // Constructs the fviRpcChUId array
90
91 for (uint16_t comp = 0; comp < pars.NComponents(); comp++) {
92
93 uint16_t equipment = pars.eqIds.at(comp);
94 fReadoutMap[equipment].resize(pars.NElinksPerComponent());
95 fTimeOffsetMap[equipment].resize(pars.NElinksPerComponent());
96
97 for (uint16_t elink = 0; elink < pars.NElinksPerComponent(); elink++) {
98 fReadoutMap[equipment][elink].resize(pars.nChannelsPerAsic);
99
100 const uint32_t crob = elink / pars.NElinksPerCrob() + comp * pars.NCrobsPerComponent();
101 fTimeOffsetMap[equipment][elink] = pars.crobs[crob].timeOffset;
102
103 const uint32_t asicId =
104 pars.CheckInnerComp(equipment) ? ElinkIdxToGet4IdxInner(elink, pars) : ElinkIdxToGet4Idx(elink, pars);
105
106 for (uint16_t channel = 0; channel < pars.nChannelsPerAsic; channel++) {
107 const uint32_t febId = (asicId / pars.nAsicsPerFeb);
108 const uint32_t chanInFeb = (asicId % pars.nAsicsPerFeb) * pars.nChannelsPerAsic + channel;
109 const uint32_t remappedChan =
110 comp * numChanPerComp + febId * pars.NChansPerFeb() + Get4ChanToPadiChan(chanInFeb, pars);
111 const uint32_t chanUId = fviRpcChUId[remappedChan];
112 fReadoutMap[equipment][elink][channel] = chanUId;
113 } //# channel
114 } //# elink
115 } //# component
116 }
117
118 int32_t ReadoutConfig::ElinkIdxToGet4Idx(uint32_t elink, const ReadoutSetup& pars)
119 {
120 if (gdpbv100::kuChipIdMergedEpoch == elink) {
121 return elink;
122 }
123 else if (elink < pars.NElinksPerComponent()) {
124 return pars.elink2Asic[elink % pars.NElinksPerCrob()] + pars.NElinksPerCrob() * (elink / pars.NElinksPerCrob());
125 }
126 else {
127 throw FatalError("tof::ReadoutConfig::ElinkIdxToGet4Idx => Index out of bound, {} vs {}, stop there!", elink,
128 static_cast<uint32_t>(pars.NElinksPerComponent()));
129 }
130 }
131
132 int32_t ReadoutConfig::ElinkIdxToGet4IdxInner(uint32_t elink, const ReadoutSetup& pars)
133 {
134 if (0 == pars.elink2AsicInner.size()) {
135 throw FatalError("tof::ReadoutConfig::ElinkIdxToGet4IdxInner => map is empty, stop there, check your Config!");
136 }
137 else if (gdpbv100::kuChipIdMergedEpoch == elink) {
138 return elink;
139 }
140 else if (elink < pars.NElinksPerComponent()) {
141 return pars.elink2AsicInner[elink % pars.NElinksPerCrob()]
142 + pars.NElinksPerCrob() * (elink / pars.NElinksPerCrob());
143 }
144 else {
145 throw FatalError("tof::ReadoutConfig::ElinkIdxToGet4IdxInner => Index out of bound, {} vs {}, stop there!", elink,
146 static_cast<uint32_t>(pars.NElinksPerComponent()));
147 }
148 }
149 // -------------------------------------------------------------------------
150
151
152 // -------------------------------------------------------------------------
153 int32_t ReadoutConfig::Get4ChanToPadiChan(uint32_t channelInFee, const ReadoutSetup& pars)
154 {
155 if (channelInFee < pars.NChansPerFeb()) {
156 return pars.asic2PadI[channelInFee];
157 }
158 else {
159 throw FatalError("CbmMcbm2018TofPar::Get4ChanToPadiChan => Index out of bound, {} vs {}, returning crazy value!",
160 channelInFee, static_cast<uint32_t>(pars.NChansPerFeb()));
161 }
162 }
163 // -------------------------------------------------------------------------
164
165 // -------------------------------------------------------------------------
167 {
168 uint32_t uNrOfGet4 = pars.NComponents() * pars.nFebsPerComponent * pars.nAsicsPerFeb;
169 uint32_t uNrOfChannels = uNrOfGet4 * pars.nChannelsPerAsic;
170 fviRpcChUId.resize(uNrOfChannels);
171
172 // D.Smith 03.06.2024: TO DO. Clarify
173 uint32_t nbRobPerComp = 2; // number of Gbtx per Gdpb (flim) for the final channel count check
174 if (pars.elink2AsicInner.size() > 0) {
175 nbRobPerComp = 1; // Hack for 2024 TOF mapping
176 }
177
178 L_(debug) << "============================================================";
179 L_(debug) << "================== TOF Mapping =============================";
180
181 uint32_t uCh = 0;
182 for (uint32_t uGbtx = 0; uGbtx < pars.NCrobs(); ++uGbtx) {
183 uint32_t uCh0 = uCh;
184 uint32_t uGdpb = uCh0 / (pars.nFebsPerComponent * pars.nAsicsPerFeb * pars.nChannelsPerAsic);
185 const auto& crob = pars.crobs.at(uGbtx);
186 switch (crob.rpcType) {
187 case 2: // intended fall-through
188 case 0: {
189 // CBM modules
190 BuildChannelsUidMapCbm(uCh, crob);
191 break;
192 }
193 case 1: {
194 // STAR eTOF modules
195 BuildChannelsUidMapStar(uCh, crob);
196 break;
197 }
198 case 78: {
199 // cern-20-gap + ceramic module
200 BuildChannelsUidMapCern(uCh, crob);
201 }
202 [[fallthrough]]; // fall through is intended
203 case 8: // ceramics
204 {
205 BuildChannelsUidMapCera(uCh, crob);
206 break;
207 }
208 case 4: // intended fallthrough
209 [[fallthrough]];
210 case 7: [[fallthrough]];
211 case 9: // Star2 boxes
212 {
213 if ((pars.eqIds[uGdpb] & 0xF000) == 0xB000) {
215 }
216 else {
217 BuildChannelsUidMapStar2(uCh, crob);
218 }
219 break;
220 }
221 case 6: // Buc box
222 {
223 if ((pars.eqIds[uGdpb] & 0xF000) == 0xB000) {
225 }
226 else {
227 BuildChannelsUidMapBuc(uCh, crob);
228 }
229 break;
230 }
231 case 66: // Buc box 2024
232 {
233 BuildChannelsUidMapBuc(uCh, crob);
234 break;
235 }
236 case 69: {
238 BuildChannelsUidMapBuc(uCh, crob);
240 uCh -= 80; // PAL, 2022/03/17: ?!?
241 BuildChannelsUidMapStar2(uCh, crob);
242 uCh -= 80; // PAL, 2022/03/17: ?!?
243 break;
244 }
245 case -1: {
246 L_(warning) << " Found unused GBTX link at uCh = " << uCh;
247 uCh += 160;
248 break;
249 }
250 default: {
251 L_(error) << "Invalid Tof Type specifier for GBTx " << std::setw(2) << uGbtx << ": " << crob.rpcType;
252 }
253 } // switch (crob.rpcType)
254
255 if (uCh - uCh0 != pars.nFebsPerComponent * pars.nAsicsPerFeb * pars.nChannelsPerAsic / nbRobPerComp) {
256 throw FatalError("Tof mapping error for Gbtx {}, diff = {}, type {}", uGbtx, uCh - uCh0, crob.rpcType);
257 }
258
259 L_(debug) << " Map for CROB " << uGbtx;
260 std::vector<int32_t> vAddrBunch(8, -1);
261 for (uint32_t uChPrint = uCh0; uChPrint < uCh; ++uChPrint) {
262 vAddrBunch[uChPrint % 8] = fviRpcChUId[uChPrint];
263 if (7 == uChPrint % 8) {
264 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << " 0x" << std::setw(8)
265 << vAddrBunch[1] << " 0x" << std::setw(8) << vAddrBunch[2] << " 0x" << std::setw(8) << vAddrBunch[3]
266 << " 0x" << std::setw(8) << vAddrBunch[4] << " 0x" << std::setw(8) << vAddrBunch[5] << " 0x"
267 << std::setw(8) << vAddrBunch[6] << " 0x" << std::setw(8) << vAddrBunch[7] << std::dec;
268 }
269 }
270 switch (uCh % 8) {
271 case 0: {
272 break;
273 }
274 case 1: {
275 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << std::dec;
276 break;
277 }
278 case 2: {
279 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << " 0x" << std::setw(8)
280 << vAddrBunch[1] << std::dec;
281 break;
282 }
283 case 3: {
284 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << " 0x" << std::setw(8)
285 << vAddrBunch[1] << " 0x" << std::setw(8) << vAddrBunch[2] << std::dec;
286 break;
287 }
288 case 4: {
289 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << " 0x" << std::setw(8)
290 << vAddrBunch[1] << " 0x" << std::setw(8) << vAddrBunch[2] << " 0x" << std::setw(8) << vAddrBunch[3]
291 << std::dec;
292 break;
293 }
294 case 5: {
295 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << " 0x" << std::setw(8)
296 << vAddrBunch[1] << " 0x" << std::setw(8) << vAddrBunch[2] << " 0x" << std::setw(8) << vAddrBunch[3]
297 << " 0x" << std::setw(8) << vAddrBunch[4] << std::dec;
298 break;
299 }
300 case 6: {
301 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << " 0x" << std::setw(8)
302 << vAddrBunch[1] << " 0x" << std::setw(8) << vAddrBunch[2] << " 0x" << std::setw(8) << vAddrBunch[3]
303 << " 0x" << std::setw(8) << vAddrBunch[4] << " 0x" << std::setw(8) << vAddrBunch[5] << std::dec;
304 break;
305 }
306 case 7: {
307 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << " 0x" << std::setw(8)
308 << vAddrBunch[1] << " 0x" << std::setw(8) << vAddrBunch[2] << " 0x" << std::setw(8) << vAddrBunch[3]
309 << " 0x" << std::setw(8) << vAddrBunch[4] << " 0x" << std::setw(8) << vAddrBunch[5] << " 0x"
310 << std::setw(8) << vAddrBunch[6] << std::dec;
311 break;
312 }
313 }
314 } // for (UInt_t uGbtx = 0; uGbtx < numCrob; ++uGbtx)
315
316 L_(debug) << "============================================================";
317 }
318 // -------------------------------------------------------------------------
319
320
321 // -------------------------------------------------------------------------
322 void ReadoutConfig::BuildChannelsUidMapCbm(uint32_t& uCh, const CROB& crob)
323 {
324 if (crob.rpcSide < 4) { // mTof modules
325 const int32_t RpcMap[5] = {4, 2, 0, 3, 1};
326 const int32_t RpcMapInv[5] = {0, 2, 4, 1, 3};
327 for (int32_t iRpc = 0; iRpc < crob.nRPC; iRpc++) {
328 int32_t iStrMax = 32;
329 uint32_t uChNext = 1;
330 int32_t iRpcMap = -1;
331 if (crob.rpcSide < 2) {
332 iRpcMap = RpcMap[iRpc];
333 }
334 else {
335 iRpcMap = RpcMapInv[iRpc];
336 }
337
338 for (int32_t iStr = 0; iStr < iStrMax; iStr++) {
339 int32_t iStrMap = iStr;
340
341 if (crob.rpcSide % 2 == 0) {
342 iStrMap = 31 - iStr;
343 }
344 if (crob.moduleId > -1)
345 fviRpcChUId.at(uCh) =
346 CbmTofAddress::GetUniqueAddress(crob.moduleId, iRpcMap, iStrMap, crob.rpcSide % 2, crob.rpcType);
347 else
348 fviRpcChUId.at(uCh) = 0;
349 uCh += uChNext;
350 } // for (int32_t iStr = 0; iStr < iStrMax; iStr++)
351 } // for (int32_t iRpc = 0; iRpc < crob.nRPC; iRpc++)
352 } // if (crob.rpcSide < 2)
353 }
354
355
356 // -------------------------------------------------------------------------
357 void ReadoutConfig::BuildChannelsUidMapStar(uint32_t& uCh, const CROB& crob)
358 {
359 if (crob.rpcSide < 2) {
360 // mTof modules
361 L_(debug) << "Start eTOF module side " << crob.rpcSide << " at " << uCh;
362 const int32_t RpcMap[3] = {0, 1, 2};
363 for (int32_t iRpc = 0; iRpc < crob.nRPC; iRpc++) {
364 int32_t iStrMax = 32;
365 int32_t uChNext = 1;
366
367 for (int32_t iStr = 0; iStr < iStrMax; iStr++) {
368 int32_t iStrMap = iStr;
369 int32_t iRpcMap = RpcMap[iRpc];
370
371 if (crob.rpcSide == 0) iStrMap = 31 - iStr;
372 if (crob.moduleId > -1)
373 fviRpcChUId[uCh] =
374 CbmTofAddress::GetUniqueAddress(crob.moduleId, iRpcMap, iStrMap, crob.rpcSide, crob.rpcType);
375 else
376 fviRpcChUId[uCh] = 0;
377 uCh += uChNext;
378 }
379 }
380 }
381 uCh += 64;
382 }
383
384 // -------------------------------------------------------------------------
386 {
387 L_(debug) << " Map CERN 20 gap at GBTX - uCh = " << uCh;
388 // clang-format off
389 const int32_t StrMap[32] = {0, 1, 2, 3, 4, 31, 5, 6, 7, 30, 8,
390 9, 10, 29, 11, 12, 13, 14, 28, 15, 16, 17,
391 18, 27, 26, 25, 24, 23, 22, 21, 20, 19};
392 // clang-format on
393 int32_t iModuleId = 0;
394 int32_t iModuleType = 7;
395 int32_t iRpcMap = 0;
396 for (int32_t iFeet = 0; iFeet < 2; iFeet++) {
397 for (int32_t iStr = 0; iStr < 32; iStr++) {
398 int32_t iStrMap = 31 - 12 - StrMap[iStr];
399 int32_t iSideMap = iFeet;
400 if (iStrMap < 20)
401 fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(iModuleId, iRpcMap, iStrMap, iSideMap, iModuleType);
402 else
403 fviRpcChUId[uCh] = 0;
404 uCh++;
405 }
406 }
407 L_(debug) << " Map end CERN 20 gap at GBTX - uCh = " << uCh;
408 }
409
410 // -------------------------------------------------------------------------
412 {
413 int32_t iModuleId = 0;
414 int32_t iModuleType = 8;
415 for (int32_t iRpc = 0; iRpc < 8; iRpc++) {
416 fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(iModuleId, 7 - iRpc, 0, 0, iModuleType);
417 uCh++;
418 }
419 uCh += (24 + 2 * 32);
420 L_(debug) << " Map end ceramics box at GBTX - uCh = " << uCh;
421 }
422
423
424 // -------------------------------------------------------------------------
425 void ReadoutConfig::BuildChannelsUidMapStar2(uint32_t& uCh, const CROB& crob)
426 {
427 const int32_t iRpc[5] = {1, -1, 1, 0, 0};
428 const int32_t iSide[5] = {1, -1, 0, 1, 0};
429 for (int32_t iFeet = 0; iFeet < 5; iFeet++) {
430 for (int32_t iStr = 0; iStr < 32; iStr++) {
431 int32_t iStrMap = iStr;
432 int32_t iRpcMap = iRpc[iFeet];
433 int32_t iSideMap = iSide[iFeet];
434 if (iSideMap == 0) iStrMap = 31 - iStr;
435 switch (crob.rpcSide) {
436 case 0:; break;
437 case 1:;
438 iRpcMap = 1 - iRpcMap; // swap counters
439 break;
440 case 2:
441 switch (iFeet) {
442 case 1:
443 iRpcMap = iRpc[4];
444 iSideMap = iSide[4];
445 iStrMap = 31 - iStrMap;
446 break;
447 case 4:
448 iRpcMap = iRpc[1];
449 iSideMap = iSide[1];
450 break;
451 default:;
452 }
453 break;
454 case 3: // direct beam 20210524
455 switch (iFeet) {
456 case 0:
457 iRpcMap = 0;
458 iSideMap = 0;
459 iStrMap = iStr;
460 break;
461 case 1:
462 iRpcMap = 0;
463 iSideMap = 1;
464 iStrMap = 31 - iStr;
465 break;
466 default: iSideMap = -1;
467 }
468 break;
469 }
470 if (iSideMap > -1)
471 fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(crob.moduleId, iRpcMap, iStrMap, iSideMap, crob.rpcType);
472 else
473 fviRpcChUId[uCh] = 0;
474 uCh++;
475 }
476 }
477 }
478
479 // -------------------------------------------------------------------------
480 void ReadoutConfig::BuildChannelsUidMapStar2Inner(uint32_t& uCh, const CROB& crob)
481 {
482 if (crob.rpcSide < 3) {
483 int32_t NrFeet = 2;
484 if (crob.rpcSide < 2) NrFeet = 1;
485 int32_t iFeet = 0;
486 for (; iFeet < NrFeet; iFeet++) {
487 for (int32_t iStr = 0; iStr < 32; iStr++) {
488 int32_t iStrMap = iStr;
489 int32_t iRpcMap = crob.nRPC;
490 int32_t iSideMap = crob.rpcSide;
491 if (crob.rpcSide == 2) {
492 if (iFeet == 0)
493 iSideMap = 0;
494 else
495 iSideMap = 1;
496 }
497 if (crob.rpcType != 6)
498 if (iSideMap == 0) iStrMap = 31 - iStr;
499
500 if (iSideMap > -1)
501 fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(crob.moduleId, iRpcMap, iStrMap, iSideMap, crob.rpcType);
502 else
503 fviRpcChUId[uCh] = 0;
504
505 uCh++;
506 }
507 }
508 while (iFeet < 2) {
509 for (int32_t iStr = 0; iStr < 32; iStr++) {
510 fviRpcChUId[uCh] = 0;
511 uCh++;
512 }
513 iFeet++;
514 }
515 }
516 else {
517 if (crob.rpcSide == 3) {
518 int iSideMap = -1;
519 int iStrMap = -1;
520 int iRpcMap = -1;
521 for (int32_t iFeet = 0; iFeet < 5; iFeet++) {
522 for (int32_t iStr = 0; iStr < 32; iStr++) {
523 switch (iFeet) {
524 case 0: iSideMap = -1; break;
525 case 1:
526 iRpcMap = 0;
527 iStrMap = iStr;
528 iSideMap = 0;
529 break;
530 case 2:
531 iRpcMap = 0;
532 iStrMap = iStr;
533 iSideMap = 1;
534 break;
535 case 3:
536 iRpcMap = 1;
537 iStrMap = iStr;
538 iSideMap = 0;
539 break;
540 case 4:
541 iRpcMap = 1;
542 iStrMap = iStr;
543 iSideMap = 1;
544 break;
545 }
546 if (iSideMap > -1)
547 fviRpcChUId[uCh] =
548 CbmTofAddress::GetUniqueAddress(crob.moduleId, iRpcMap, iStrMap, iSideMap, crob.rpcType);
549 else
550 fviRpcChUId[uCh] = 0;
551 uCh++;
552 }
553 }
554 }
555 else if (crob.rpcSide == 4) {
556 int iSideMap = -1;
557 int iStrMap = -1;
558 int iRpcMap = -1;
559 const int ConOff[8] = {0, 2, 4, 6, 7, 1, 3, 5}; // Get4 after Gbtx
560 for (int32_t iFeet = 0; iFeet < 5; iFeet++) {
561 for (int32_t iStr = 0; iStr < 32; iStr++) {
562 switch (iFeet) {
563 case 0: iSideMap = -1; break;
564 case 1:
565 iRpcMap = 0;
566 iStrMap = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
567 iSideMap = 0;
568 break;
569 case 2:
570 iRpcMap = 0;
571 iStrMap = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
572 iSideMap = 1;
573 break;
574 case 3:
575 iRpcMap = 1;
576 iStrMap = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
577 iSideMap = 1;
578 break;
579 case 4:
580 iRpcMap = 1;
581 iStrMap = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
582 iSideMap = 0;
583 break;
584 }
585 if (iSideMap > -1)
586 fviRpcChUId[uCh] =
587 CbmTofAddress::GetUniqueAddress(crob.moduleId, iRpcMap, iStrMap, iSideMap, crob.rpcType);
588 else
589 fviRpcChUId[uCh] = 0;
590 uCh++;
591 }
592 }
593 }
594 }
595 }
596
597 // -------------------------------------------------------------------------
598 void ReadoutConfig::BuildChannelsUidMapBuc(uint32_t& uCh, const CROB& crob)
599 {
600 int32_t iModuleIdMap = crob.moduleId;
601 const int32_t iRpc[5] = {0, -1, 0, 1, 1};
602 const int32_t iSide[5] = {1, -1, 0, 1, 0};
603 for (int32_t iFeet = 0; iFeet < 5; iFeet++) {
604 for (int32_t iStr = 0; iStr < 32; iStr++) {
605 int32_t iStrMap = iStr;
606 int32_t iRpcMap = iRpc[iFeet];
607 int32_t iSideMap = iSide[iFeet];
608 switch (crob.rpcSide) {
609 case 0:; break;
610 case 1: // HD cosmic 2019, Buc2018, v18n
611 iStrMap = 31 - iStr;
612 iRpcMap = 1 - iRpcMap;
613 break;
614 case 2: // v18m_cosmicHD
615 // iStrMap=31-iStr;
616 iSideMap = 1 - iSideMap;
617 break;
618 case 3: {
619 const int ConOff[8] = {0, 2, 4, 6, 7, 1, 3, 5}; // Get4 after Gbtx
620 switch (iFeet) {
621 case 0: iSideMap = -1; break;
622 case 1:
623 iRpcMap = 0;
624 iStrMap = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
625 iSideMap = 0;
626 break;
627 case 2:
628 iRpcMap = 0;
629 iStrMap = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
630 iSideMap = 1;
631 break;
632 case 3:
633 iRpcMap = 1;
634 iStrMap = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
635 iSideMap = 1;
636 break;
637 case 4:
638 iRpcMap = 1;
639 iStrMap = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
640 iSideMap = 0;
641 break;
642 }
643 } break;
644 case 4: // HD cosmic 2019, Buc2018, v18o
645 iRpcMap = 1 - iRpcMap;
646 break;
647 case 5: // HD cosmic 2020, Buc2018, v20a
648 iStrMap = 31 - iStr;
649 break;
650 case 6: //BUC special
651 {
652 switch (crob.moduleId) {
653 case 0: iRpcMap = 0; break;
654 case 1: iRpcMap = 1; break;
655 }
656 if (iFeet % 2 == 1)
657 iModuleIdMap = 1;
658 else
659 iModuleIdMap = 0;
660
661 switch (iFeet) {
662 case 0:
663 case 3: iSideMap = 0; break;
664 case 1:
665 case 2: iSideMap = 1; break;
666 }
667 } break;
668 case 8: {
669 // Special case for two channels in 2022
670 // Fallthrough to 7 for all other channels
671 if (2 == iFeet) {
672 if (7 == iStr) {
674 fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(0, 0, 0, 0, 8);
675 uCh++;
676 continue;
677 }
678 else if (23 == iStr) {
680 fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(1, 0, 0, 0, 8);
681 uCh++;
682 continue;
683 }
684 }
685 }
686 [[fallthrough]]; // fall through is intended
687 case 7: {
688 // clang-format off
689 const int32_t iChMap[160]={
690 124, 125, 126, 127, 12, 13, 14, 15, 4, 5, 6, 7, 28, 29, 30, 31, 120, 121, 122, 123, 8, 9, 10, 11, 104, 105, 106, 107, 108, 109, 110, 111,
691 36, 37, 38, 39, 52, 53, 54, 55, 60, 61, 62, 63, 128, 129, 130, 131, 40, 41, 42, 43, 148, 149, 150, 151, 56, 57, 58, 59, 132, 133, 134, 135,
692 136, 137, 138, 139, 140, 141, 142, 143, 96, 97, 98, 99, 64, 65, 66, 67, 100, 101, 102, 103, 84, 85, 86, 87, 152, 153, 154, 155, 68, 69, 70, 71,
693 156, 157, 158, 159, 144, 145, 146, 147, 44, 45, 46, 47, 76, 77, 78, 79, 48, 49, 50, 51, 20, 21, 22, 23, 32, 33, 34, 35, 116, 117, 118, 119,
694 75, 74, 73, 72, 92, 93, 94, 95, 16, 17, 18, 19, 80, 81, 82, 83, 115, 114, 113, 112, 24, 25, 26, 27, 88, 89, 90, 91, 0, 1, 2, 3
695 };
696 // clang-format on
697 int32_t iInd = iFeet * 32 + iStr;
698 int32_t i = 0;
699 for (; i < 160; i++)
700 if (iInd == iChMap[i]) break;
701 iStrMap = i % 32;
702 int32_t iFeetInd = (i - iStrMap) / 32;
703 switch (iFeetInd) {
704 case 0:
705 iRpcMap = 0;
706 iSideMap = 1;
707 break;
708 case 1:
709 iRpcMap = 1;
710 iSideMap = 1;
711 break;
712 case 2:
713 iRpcMap = 1;
714 iSideMap = 0;
715 break;
716 case 3:
717 iRpcMap = 0;
718 iSideMap = 0;
719 break;
720 case 4: iSideMap = -1; break;
721 }
722 iModuleIdMap = crob.moduleId;
723 } break;
724 default:;
725 } // switch (crob.rpcSide)
726 if (iSideMap > -1)
727 fviRpcChUId[uCh] =
728 CbmTofAddress::GetUniqueAddress(iModuleIdMap, iRpcMap, iStrMap, iSideMap, crob.rpcType % 10);
729 else
730 fviRpcChUId[uCh] = 0;
731
732 uCh++;
733 } // for (int32_t iStr = 0; iStr < 32; iStr++)
734 } // for (int32_t iFeet = 0; iFeet < 5; iFeet++)
735 }
736 // -------------------------------------------------------------------------
737
738} // namespace cbm::algo::tof
#define L_(level)
#define CBM_YAML_INSTANTIATE(type)
Explicitly instantiate the Read and Dump functions for a type.
Definition Yaml.h:305
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)
void BuildChannelsUidMapStar(uint32_t &uCh, const CROB &crob)
void BuildChannelsUidMapCern(uint32_t &uCh, const CROB &crob)
void BuildChannelsUidMapStar2Inner(uint32_t &uCh, const CROB &crob)
int32_t ElinkIdxToGet4Idx(uint32_t elink, const ReadoutSetup &pars)
Mapping to eLink to ASIC number within DPB. Mapping is the same for each DPB.
std::map< uint16_t, std::vector< std::vector< uint32_t > > > fReadoutMap
void BuildChannelsUidMapStar2(uint32_t &uCh, const CROB &crob)
void BuildChannelsUidMapCera(uint32_t &uCh, const CROB &crob)
std::vector< int32_t > fviRpcChUId
int32_t GetElinkTimeOffset(uint16_t equipId, uint16_t elink)
API: Mapping from component and elink to time offset.
void BuildChannelsUidMapCbm(uint32_t &uCh, const CROB &crob)
std::map< uint16_t, std::vector< uint64_t > > fTimeOffsetMap
void BuildChannelsUidMap(const ReadoutSetup &pars)
void Init(const ReadoutSetup &pars)
Initialisation of readout map.
std::vector< uint32_t > Map(uint16_t equipId, uint16_t elink)
API: Mapping from component and elink to addresses per channel.
int32_t ElinkIdxToGet4IdxInner(uint32_t elink, const ReadoutSetup &pars)
Mapping to eLink to ASIC number within DPB for 2024 inner TOF FEBs. Mapping is the same for each DPB.
ReadoutConfig(const ReadoutSetup &pars)
Constructor.
std::vector< uint16_t > GetEquipmentIds()
Equipment in the configuration.
void BuildChannelsUidMapBuc(uint32_t &uCh, const CROB &crob)
int32_t Get4ChanToPadiChan(uint32_t channelInFee, const ReadoutSetup &pars)
size_t GetNumElinks(uint16_t equipmentId)
Number of elinks of a component.
const uint32_t kuChipIdMergedEpoch
Hash for CbmL1LinkKey.
Indicates an unrecoverable error. Should tear down the process.
Definition Exceptions.h:34
Readout setup / Hardware cabling for TOF Used to create the hardware mapping for the TOF unpacker.
std::vector< i32 > elink2AsicInner
bool CheckInnerComp(uint32_t uCompId) const