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 1: // intended fall-through
189 case 0: {
190 // CBM modules
191 BuildChannelsUidMapCbm(uCh, crob);
192 break;
193 }
194 case 11: {
195 // STAR eTOF modules
196 BuildChannelsUidMapStar(uCh, crob);
197 break;
198 }
199 case 78: {
200 // cern-20-gap + ceramic module
201 BuildChannelsUidMapCern(uCh, crob);
202 }
203 [[fallthrough]]; // fall through is intended
204 case 8: // ceramics
205 {
206 BuildChannelsUidMapCera(uCh, crob);
207 break;
208 }
209 case 4: // intended fallthrough
210 [[fallthrough]];
211 case 7: [[fallthrough]];
212 case 9: // Star2 boxes
213 {
214 if ((pars.eqIds[uGdpb] & 0xF000) == 0xB000) {
216 }
217 else {
218 BuildChannelsUidMapStar2(uCh, crob);
219 }
220 break;
221 }
222 case 6: // Buc box
223 {
224 if ((pars.eqIds[uGdpb] & 0xF000) == 0xB000) {
226 }
227 else {
228 BuildChannelsUidMapBuc(uCh, crob);
229 }
230 break;
231 }
232 case 66: // Buc box 2024
233 {
234 BuildChannelsUidMapBuc(uCh, crob);
235 break;
236 }
237 case 69: {
239 BuildChannelsUidMapBuc(uCh, crob);
241 uCh -= 80; // PAL, 2022/03/17: ?!?
242 BuildChannelsUidMapStar2(uCh, crob);
243 uCh -= 80; // PAL, 2022/03/17: ?!?
244 break;
245 }
246 case -1: {
247 L_(warning) << " Found unused GBTX link at uCh = " << uCh;
248 uCh += 160;
249 break;
250 }
251 default: {
252 L_(error) << "Invalid Tof Type specifier for GBTx " << std::setw(2) << uGbtx << ": " << crob.rpcType;
253 }
254 } // switch (crob.rpcType)
255
256 if (uCh - uCh0 != pars.nFebsPerComponent * pars.nAsicsPerFeb * pars.nChannelsPerAsic / nbRobPerComp) {
257 throw FatalError("Tof mapping error for Gbtx {}, diff = {}, type {}", uGbtx, uCh - uCh0, crob.rpcType);
258 }
259
260 L_(debug) << " Map for CROB " << uGbtx;
261 std::vector<int32_t> vAddrBunch(8, -1);
262 for (uint32_t uChPrint = uCh0; uChPrint < uCh; ++uChPrint) {
263 vAddrBunch[uChPrint % 8] = fviRpcChUId[uChPrint];
264 if (7 == uChPrint % 8) {
265 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << " 0x" << std::setw(8)
266 << vAddrBunch[1] << " 0x" << std::setw(8) << vAddrBunch[2] << " 0x" << std::setw(8) << vAddrBunch[3]
267 << " 0x" << std::setw(8) << vAddrBunch[4] << " 0x" << std::setw(8) << vAddrBunch[5] << " 0x"
268 << std::setw(8) << vAddrBunch[6] << " 0x" << std::setw(8) << vAddrBunch[7] << std::dec;
269 }
270 }
271 switch (uCh % 8) {
272 case 0: {
273 break;
274 }
275 case 1: {
276 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << std::dec;
277 break;
278 }
279 case 2: {
280 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << " 0x" << std::setw(8)
281 << vAddrBunch[1] << std::dec;
282 break;
283 }
284 case 3: {
285 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << " 0x" << std::setw(8)
286 << vAddrBunch[1] << " 0x" << std::setw(8) << vAddrBunch[2] << std::dec;
287 break;
288 }
289 case 4: {
290 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << " 0x" << std::setw(8)
291 << vAddrBunch[1] << " 0x" << std::setw(8) << vAddrBunch[2] << " 0x" << std::setw(8) << vAddrBunch[3]
292 << std::dec;
293 break;
294 }
295 case 5: {
296 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << " 0x" << std::setw(8)
297 << vAddrBunch[1] << " 0x" << std::setw(8) << vAddrBunch[2] << " 0x" << std::setw(8) << vAddrBunch[3]
298 << " 0x" << std::setw(8) << vAddrBunch[4] << std::dec;
299 break;
300 }
301 case 6: {
302 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << " 0x" << std::setw(8)
303 << vAddrBunch[1] << " 0x" << std::setw(8) << vAddrBunch[2] << " 0x" << std::setw(8) << vAddrBunch[3]
304 << " 0x" << std::setw(8) << vAddrBunch[4] << " 0x" << std::setw(8) << vAddrBunch[5] << std::dec;
305 break;
306 }
307 case 7: {
308 L_(debug) << std::hex << std::setfill('0') << "0x" << std::setw(8) << vAddrBunch[0] << " 0x" << std::setw(8)
309 << vAddrBunch[1] << " 0x" << std::setw(8) << vAddrBunch[2] << " 0x" << std::setw(8) << vAddrBunch[3]
310 << " 0x" << std::setw(8) << vAddrBunch[4] << " 0x" << std::setw(8) << vAddrBunch[5] << " 0x"
311 << std::setw(8) << vAddrBunch[6] << std::dec;
312 break;
313 }
314 }
315 } // for (UInt_t uGbtx = 0; uGbtx < numCrob; ++uGbtx)
316
317 L_(debug) << "============================================================";
318 }
319 // -------------------------------------------------------------------------
320
321
322 // -------------------------------------------------------------------------
323 void ReadoutConfig::BuildChannelsUidMapCbm(uint32_t& uCh, const CROB& crob)
324 {
325 if (crob.rpcSide < 4) { // mTof modules
326 const int32_t RpcMap[5] = {4, 2, 0, 3, 1};
327 const int32_t RpcMapInv[5] = {0, 2, 4, 1, 3};
328 for (int32_t iRpc = 0; iRpc < crob.nRPC; iRpc++) {
329 int32_t iStrMax = 32;
330 uint32_t uChNext = 1;
331 int32_t iRpcMap = -1;
332 if (crob.rpcSide < 2) {
333 iRpcMap = RpcMap[iRpc];
334 }
335 else {
336 iRpcMap = RpcMapInv[iRpc];
337 }
338
339 for (int32_t iStr = 0; iStr < iStrMax; iStr++) {
340 int32_t iStrMap = iStr;
341
342 if (crob.rpcSide % 2 == 0) {
343 iStrMap = 31 - iStr;
344 }
345 if (crob.moduleId > -1)
346 fviRpcChUId.at(uCh) =
347 CbmTofAddress::GetUniqueAddress(crob.moduleId, iRpcMap, iStrMap, crob.rpcSide % 2, crob.rpcType);
348 else
349 fviRpcChUId.at(uCh) = 0;
350 uCh += uChNext;
351 } // for (int32_t iStr = 0; iStr < iStrMax; iStr++)
352 } // for (int32_t iRpc = 0; iRpc < crob.nRPC; iRpc++)
353 } // if (crob.rpcSide < 2)
354 }
355
356
357 // -------------------------------------------------------------------------
358 void ReadoutConfig::BuildChannelsUidMapStar(uint32_t& uCh, const CROB& crob)
359 {
360 if (crob.rpcSide < 2) {
361 // mTof modules
362 L_(debug) << "Start eTOF module side " << crob.rpcSide << " at " << uCh;
363 const int32_t RpcMap[3] = {0, 1, 2};
364 for (int32_t iRpc = 0; iRpc < crob.nRPC; iRpc++) {
365 int32_t iStrMax = 32;
366 int32_t uChNext = 1;
367
368 for (int32_t iStr = 0; iStr < iStrMax; iStr++) {
369 int32_t iStrMap = iStr;
370 int32_t iRpcMap = RpcMap[iRpc];
371
372 if (crob.rpcSide == 0) iStrMap = 31 - iStr;
373 if (crob.moduleId > -1)
374 fviRpcChUId[uCh] =
375 CbmTofAddress::GetUniqueAddress(crob.moduleId, iRpcMap, iStrMap, crob.rpcSide, crob.rpcType);
376 else
377 fviRpcChUId[uCh] = 0;
378 uCh += uChNext;
379 }
380 }
381 }
382 uCh += 64;
383 }
384
385 // -------------------------------------------------------------------------
387 {
388 L_(debug) << " Map CERN 20 gap at GBTX - uCh = " << uCh;
389 // clang-format off
390 const int32_t StrMap[32] = {0, 1, 2, 3, 4, 31, 5, 6, 7, 30, 8,
391 9, 10, 29, 11, 12, 13, 14, 28, 15, 16, 17,
392 18, 27, 26, 25, 24, 23, 22, 21, 20, 19};
393 // clang-format on
394 int32_t iModuleId = 0;
395 int32_t iModuleType = 7;
396 int32_t iRpcMap = 0;
397 for (int32_t iFeet = 0; iFeet < 2; iFeet++) {
398 for (int32_t iStr = 0; iStr < 32; iStr++) {
399 int32_t iStrMap = 31 - 12 - StrMap[iStr];
400 int32_t iSideMap = iFeet;
401 if (iStrMap < 20)
402 fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(iModuleId, iRpcMap, iStrMap, iSideMap, iModuleType);
403 else
404 fviRpcChUId[uCh] = 0;
405 uCh++;
406 }
407 }
408 L_(debug) << " Map end CERN 20 gap at GBTX - uCh = " << uCh;
409 }
410
411 // -------------------------------------------------------------------------
413 {
414 int32_t iModuleId = 0;
415 int32_t iModuleType = 8;
416 for (int32_t iRpc = 0; iRpc < 8; iRpc++) {
417 fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(iModuleId, 7 - iRpc, 0, 0, iModuleType);
418 uCh++;
419 }
420 uCh += (24 + 4 * 32);
421 L_(debug) << " Map end ceramics box at GBTX - uCh = " << uCh;
422 }
423
424
425 // -------------------------------------------------------------------------
426 void ReadoutConfig::BuildChannelsUidMapStar2(uint32_t& uCh, const CROB& crob)
427 {
428 const int32_t iRpc[5] = {1, -1, 1, 0, 0};
429 const int32_t iSide[5] = {1, -1, 0, 1, 0};
430 for (int32_t iFeet = 0; iFeet < 5; iFeet++) {
431 for (int32_t iStr = 0; iStr < 32; iStr++) {
432 int32_t iStrMap = iStr;
433 int32_t iRpcMap = iRpc[iFeet];
434 int32_t iSideMap = iSide[iFeet];
435 if (iSideMap == 0) iStrMap = 31 - iStr;
436 switch (crob.rpcSide) {
437 case 0:; break;
438 case 1:;
439 iRpcMap = 1 - iRpcMap; // swap counters
440 break;
441 case 2:
442 switch (iFeet) {
443 case 1:
444 iRpcMap = iRpc[4];
445 iSideMap = iSide[4];
446 iStrMap = 31 - iStrMap;
447 break;
448 case 4:
449 iRpcMap = iRpc[1];
450 iSideMap = iSide[1];
451 break;
452 default:;
453 }
454 break;
455 case 3: // direct beam 20210524
456 switch (iFeet) {
457 case 0:
458 iRpcMap = 0;
459 iSideMap = 0;
460 iStrMap = iStr;
461 break;
462 case 1:
463 iRpcMap = 0;
464 iSideMap = 1;
465 iStrMap = 31 - iStr;
466 break;
467 default: iSideMap = -1;
468 }
469 break;
470 }
471 if (iSideMap > -1)
472 fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(crob.moduleId, iRpcMap, iStrMap, iSideMap, crob.rpcType);
473 else
474 fviRpcChUId[uCh] = 0;
475 uCh++;
476 }
477 }
478 }
479
480 // -------------------------------------------------------------------------
481 void ReadoutConfig::BuildChannelsUidMapStar2Inner(uint32_t& uCh, const CROB& crob)
482 {
483 if (crob.rpcSide < 3) {
484 int32_t NrFeet = 2;
485 if (crob.rpcSide < 2) NrFeet = 1;
486 int32_t iFeet = 0;
487 for (; iFeet < NrFeet; iFeet++) {
488 for (int32_t iStr = 0; iStr < 32; iStr++) {
489 int32_t iStrMap = iStr;
490 int32_t iRpcMap = crob.nRPC;
491 int32_t iSideMap = crob.rpcSide;
492 if (crob.rpcSide == 2) {
493 if (iFeet == 0)
494 iSideMap = 0;
495 else
496 iSideMap = 1;
497 }
498 if (crob.rpcType != 6)
499 if (iSideMap == 0) iStrMap = 31 - iStr;
500
501 if (iSideMap > -1)
502 fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(crob.moduleId, iRpcMap, iStrMap, iSideMap, crob.rpcType);
503 else
504 fviRpcChUId[uCh] = 0;
505
506 uCh++;
507 }
508 }
509 while (iFeet < 2) {
510 for (int32_t iStr = 0; iStr < 32; iStr++) {
511 fviRpcChUId[uCh] = 0;
512 uCh++;
513 }
514 iFeet++;
515 }
516 }
517 else {
518 if (crob.rpcSide == 3) {
519 int iSideMap = -1;
520 int iStrMap = -1;
521 int iRpcMap = -1;
522 for (int32_t iFeet = 0; iFeet < 5; iFeet++) {
523 for (int32_t iStr = 0; iStr < 32; iStr++) {
524 switch (iFeet) {
525 case 0: iSideMap = -1; break;
526 case 1:
527 iRpcMap = 0;
528 iStrMap = iStr;
529 iSideMap = 0;
530 break;
531 case 2:
532 iRpcMap = 0;
533 iStrMap = iStr;
534 iSideMap = 1;
535 break;
536 case 3:
537 iRpcMap = 1;
538 iStrMap = iStr;
539 iSideMap = 0;
540 break;
541 case 4:
542 iRpcMap = 1;
543 iStrMap = iStr;
544 iSideMap = 1;
545 break;
546 }
547 if (iSideMap > -1)
548 fviRpcChUId[uCh] =
549 CbmTofAddress::GetUniqueAddress(crob.moduleId, iRpcMap, iStrMap, iSideMap, crob.rpcType);
550 else
551 fviRpcChUId[uCh] = 0;
552 uCh++;
553 }
554 }
555 }
556 else if (crob.rpcSide == 4) {
557 int iSideMap = -1;
558 int iStrMap = -1;
559 int iRpcMap = -1;
560 const int ConOff[8] = {0, 2, 4, 6, 7, 1, 3, 5}; //Get4 after Gbtx
561 for (int32_t iFeet = 0; iFeet < 5; iFeet++) {
562 for (int32_t iStr = 0; iStr < 32; iStr++) {
563 switch (iFeet) {
564 case 0: iSideMap = -1; break;
565 case 1:
566 iRpcMap = 0;
567 iStrMap = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
568 iSideMap = 0;
569 break;
570 case 2:
571 iRpcMap = 0;
572 iStrMap = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
573 iSideMap = 1;
574 break;
575 case 3:
576 iRpcMap = 1;
577 iStrMap = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
578 iSideMap = 1;
579 break;
580 case 4:
581 iRpcMap = 1;
582 iStrMap = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
583 iSideMap = 0;
584 break;
585 }
586 if (iSideMap > -1)
587 fviRpcChUId[uCh] =
588 CbmTofAddress::GetUniqueAddress(crob.moduleId, iRpcMap, iStrMap, iSideMap, crob.rpcType);
589 else
590 fviRpcChUId[uCh] = 0;
591 uCh++;
592 }
593 }
594 }
595 else if (crob.rpcSide == 5) {
596 int iSideMap = -1;
597 int iStrMap = -1;
598 int iRpcMap = -1;
599 const int ConOff[8] = {0, 2, 4, 6, 7, 1, 3, 5}; // Get4 after Gbtx
600 for (int32_t iFeet = 0; iFeet < 5; iFeet++) {
601 for (int32_t iStr = 0; iStr < 32; iStr++) {
602 switch (iFeet) {
603 case 0: iSideMap = -1; break;
604 case 1:
605 iRpcMap = 0;
606 iStrMap = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
607 iStrMap = 31 - iStrMap;
608 iSideMap = 1;
609 break;
610 case 2:
611 iRpcMap = 0;
612 iStrMap = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
613 iStrMap = 31 - iStrMap;
614 iSideMap = 0;
615 break;
616 case 3:
617 iRpcMap = 1;
618 iStrMap = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
619 iStrMap = 31 - iStrMap;
620 iSideMap = 0;
621 break;
622 case 4:
623 iRpcMap = 1;
624 iStrMap = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
625 iStrMap = 31 - iStrMap;
626 iSideMap = 1;
627 break;
628 }
629 if (iSideMap > -1)
630 fviRpcChUId[uCh] =
631 CbmTofAddress::GetUniqueAddress(crob.moduleId, iRpcMap, iStrMap, iSideMap, crob.rpcType);
632 else
633 fviRpcChUId[uCh] = 0;
634 uCh++;
635 }
636 }
637 }
638 }
639 }
640
641 // -------------------------------------------------------------------------
642 void ReadoutConfig::BuildChannelsUidMapBuc(uint32_t& uCh, const CROB& crob)
643 {
644 int32_t iModuleIdMap = crob.moduleId;
645 const int32_t iRpc[5] = {0, -1, 0, 1, 1};
646 const int32_t iSide[5] = {1, -1, 0, 1, 0};
647 for (int32_t iFeet = 0; iFeet < 5; iFeet++) {
648 for (int32_t iStr = 0; iStr < 32; iStr++) {
649 int32_t iStrMap = iStr;
650 int32_t iRpcMap = iRpc[iFeet];
651 int32_t iSideMap = iSide[iFeet];
652 switch (crob.rpcSide) {
653 case 0:; break;
654 case 1: // HD cosmic 2019, Buc2018, v18n
655 iStrMap = 31 - iStr;
656 iRpcMap = 1 - iRpcMap;
657 break;
658 case 2: // v18m_cosmicHD
659 // iStrMap=31-iStr;
660 iSideMap = 1 - iSideMap;
661 break;
662 case 3: {
663 const int ConOff[8] = {0, 2, 4, 6, 7, 1, 3, 5}; // Get4 after Gbtx
664 switch (iFeet) {
665 case 0: iSideMap = -1; break;
666 case 1:
667 iRpcMap = 0;
668 iStrMap = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
669 iSideMap = 0;
670 break;
671 case 2:
672 iRpcMap = 0;
673 iStrMap = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
674 iSideMap = 1;
675 break;
676 case 3:
677 iRpcMap = 1;
678 iStrMap = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
679 iSideMap = 1;
680 break;
681 case 4:
682 iRpcMap = 1;
683 iStrMap = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
684 iSideMap = 0;
685 break;
686 }
687 } break;
688 case 4: // HD cosmic 2019, Buc2018, v18o
689 iRpcMap = 1 - iRpcMap;
690 break;
691 case 5: // Buc2025, mCBM
692 iRpcMap = 1 - iRpcMap;
693 iSideMap = 1 - iSideMap;
694 break;
695 case 55: // HD cosmic 2020, Buc2018, v20a
696 iStrMap = 31 - iStr;
697 break;
698 case 6: //BUC special
699 {
700 switch (crob.moduleId) {
701 case 0: iRpcMap = 0; break;
702 case 1: iRpcMap = 1; break;
703 }
704 if (iFeet % 2 == 1)
705 iModuleIdMap = 1;
706 else
707 iModuleIdMap = 0;
708
709 switch (iFeet) {
710 case 0:
711 case 3: iSideMap = 0; break;
712 case 1:
713 case 2: iSideMap = 1; break;
714 }
715 } break;
716 case 8: {
717 // Special case for two channels in 2022
718 // Fallthrough to 7 for all other channels
719 if (2 == iFeet) {
720 if (7 == iStr) {
722 fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(0, 0, 0, 0, 8);
723 uCh++;
724 continue;
725 }
726 else if (23 == iStr) {
728 fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(1, 0, 0, 0, 8);
729 uCh++;
730 continue;
731 }
732 }
733 }
734 [[fallthrough]]; // fall through is intended
735 case 7: {
736 // clang-format off
737 const int32_t iChMap[160]={
738 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,
739 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,
740 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,
741 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,
742 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
743 };
744 // clang-format on
745 int32_t iInd = iFeet * 32 + iStr;
746 int32_t i = 0;
747 for (; i < 160; i++)
748 if (iInd == iChMap[i]) break;
749 iStrMap = i % 32;
750 int32_t iFeetInd = (i - iStrMap) / 32;
751 switch (iFeetInd) {
752 case 0:
753 iRpcMap = 0;
754 iSideMap = 1;
755 break;
756 case 1:
757 iRpcMap = 1;
758 iSideMap = 1;
759 break;
760 case 2:
761 iRpcMap = 1;
762 iSideMap = 0;
763 break;
764 case 3:
765 iRpcMap = 0;
766 iSideMap = 0;
767 break;
768 case 4: iSideMap = -1; break;
769 }
770 iModuleIdMap = crob.moduleId;
771 } break;
772 default:;
773 } // switch (crob.rpcSide)
774 if (iSideMap > -1)
775 fviRpcChUId[uCh] =
776 CbmTofAddress::GetUniqueAddress(iModuleIdMap, iRpcMap, iStrMap, iSideMap, crob.rpcType % 10);
777 else
778 fviRpcChUId[uCh] = 0;
779
780 uCh++;
781 } // for (int32_t iStr = 0; iStr < 32; iStr++)
782 } // for (int32_t iFeet = 0; iFeet < 5; iFeet++)
783 }
784 // -------------------------------------------------------------------------
785
786} // 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)
int32_t GetElinkTimeOffset(uint16_t equipId, uint16_t elink)
API: Mapping from component and elink to time offset.
int32_t ElinkIdxToGet4Idx(uint32_t elink, const ReadoutSetup &pars)
Mapping to eLink to ASIC number within DPB. Mapping is the same for each DPB.
ReadoutConfig(const ReadoutSetup &pars)
Constructor.
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.
std::map< uint16_t, std::vector< std::vector< uint32_t > > > fReadoutMap
int32_t Get4ChanToPadiChan(uint32_t channelInFee, const ReadoutSetup &pars)
std::vector< int32_t > fviRpcChUId
std::vector< uint16_t > GetEquipmentIds()
Equipment in the configuration.
void BuildChannelsUidMapCbm(uint32_t &uCh, const CROB &crob)
std::map< uint16_t, std::vector< uint64_t > > fTimeOffsetMap
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.
void BuildChannelsUidMapCera(uint32_t &uCh, const CROB &crob)
size_t GetNumElinks(uint16_t equipmentId)
Number of elinks of a component.
void BuildChannelsUidMapStar2(uint32_t &uCh, const CROB &crob)
void BuildChannelsUidMapStar(uint32_t &uCh, const CROB &crob)
void BuildChannelsUidMapStar2Inner(uint32_t &uCh, const CROB &crob)
void BuildChannelsUidMap(const ReadoutSetup &pars)
void BuildChannelsUidMapCern(uint32_t &uCh, const CROB &crob)
void BuildChannelsUidMapBuc(uint32_t &uCh, const CROB &crob)
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