CbmRoot
Loading...
Searching...
No Matches
CbmStsUnpackAlgo.cxx
Go to the documentation of this file.
1/* Copyright (C) 2021 Goethe-University, Frankfurt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Pierre-Alain Loizeau, Pascal Raisig [committer], Dominik Smith */
4
5#include "CbmStsUnpackAlgo.h"
6
7#include "CbmStsDigi.h"
8
9#include <FairParGenericSet.h>
10#include <FairTask.h>
11#include <Logger.h>
12
13#include <Rtypes.h>
14#include <RtypesCore.h>
15
16#include <cstdint>
17#include <iomanip>
18
20
22
23// ---- getAsicIndex ----
24uint32_t CbmStsUnpackAlgo::getAsicIndex(uint32_t dpbidx, uint32_t crobidx, uint16_t elinkidx)
25{
26
27 uint32_t asicidx = 0;
28 const int32_t uFebIdx = fElinkIdxToFebIdxVec.at(elinkidx);
29 const uint32_t febtype = fviFebType[dpbidx][crobidx][uFebIdx];
30 // Feb type a
31 if (febtype == 0) asicidx = fElinkIdxToAsicIdxVec.at(elinkidx).first;
32 // Feb type b
33 if (febtype == 1) asicidx = fElinkIdxToAsicIdxVec.at(elinkidx).second;
34 // else would be inactive feb, this was not handled in the previous implementation, this I expect it should not happen
35
36 const uint32_t uAsicIdx = (dpbidx * fNrCrobPerDpb + crobidx) * fNrAsicsPerCrob + asicidx;
37 return uAsicIdx;
38}
39
40// ---- getFullTimeStamp ----
41uint64_t CbmStsUnpackAlgo::getFullTimeStamp(const uint16_t usRawTs)
42{
43 // Use TS w/o overlap bits as they will anyway come from the TS_MSB
44 const uint64_t ulTime =
45 usRawTs + fulTsMsbIndexInTs[fuCurrDpbIdx] * static_cast<uint64_t>(stsxyter::kuHitNbTsBinsBinning);
46 /*
47 + static_cast<uint64_t>(stsxyter::kuHitNbTsBinsBinning) * static_cast<uint64_t>(fvulCurrentTsMsb[fuCurrDpbIdx])
48 + static_cast<uint64_t>(stsxyter::kulTsCycleNbBinsBinning)
49 * static_cast<uint64_t>(fvuCurrentTsMsbCycle[fuCurrDpbIdx]);
50*/
51 return ulTime;
52}
53
54// ---- init
56{
57 if (!fbUseFwBinning) {
58 LOG(warning) << "Chosen STS unpacker always uses firmware binning (``false'' setting is ignored).";
59 }
60 return kTRUE;
61}
62
63// ---- initDpbIdIndexMap ----
65{
66 fDpbIdIndexMap.clear();
67 for (uint32_t uDpb = 0; uDpb < parset->GetNrOfDpbs(); ++uDpb) {
68 fDpbIdIndexMap[parset->GetDpbId(uDpb)] = uDpb;
69 LOG(debug) << "Eq. ID for DPB #" << std::setw(2) << uDpb << " = 0x" << std::setw(4) << std::hex
70 << parset->GetDpbId(uDpb) << std::dec << " => " << fDpbIdIndexMap[parset->GetDpbId(uDpb)];
71 }
72}
73
74// ---- initParSet(FairParGenericSet* parset) ----
75Bool_t CbmStsUnpackAlgo::initParSet(FairParGenericSet* parset)
76{
77 LOG(info) << fName << "::initParSet - for container " << parset->ClassName();
78 if (parset->IsA() == CbmMcbm2018StsPar::Class()) return initParSet(static_cast<CbmMcbm2018StsPar*>(parset));
79
80 // If we do not know the derived ParSet class we return false
81 LOG(error)
82 << fName << "::initParSet - for container " << parset->ClassName()
83 << " failed, since CbmStsUnpackAlgo::initParSet() does not know the derived ParSet and what to do with it!";
84 return kFALSE;
85}
86
87// ---- initParSet(CbmMcbm2018StsPar* parset) ----
89{
90 LOG(debug) << fName << "::initParSetAsic - ";
91
92 //Type of each module: 0 for connectors on the right, 1 for connectors on the left
93 std::vector<int32_t> viModuleType;
94
95 // STS address for the first strip of each module
96 std::vector<int32_t> viModAddress;
97
98 // Idx of the STS module for each FEB, [ NbDpb ][ NbCrobPerDpb ][ NbFebsPerCrob ], -1 if inactive
99 std::vector<std::vector<std::vector<int32_t>>> viFebModuleIdx;
100
101 // Array to hold the active flag for all CROBs, [ NbDpb ][ NbCrobPerDpb ]
102 std::vector<std::vector<bool>> vbCrobActiveFlag;
103
104 //STS module side for each FEB, [ NbDpb ][ NbCrobPerDpb ][ NbFebsPerCrob ], 0 = P, 1 = N, -1 if inactive
105 std::vector<std::vector<std::vector<int32_t>>> viFebModuleSide;
106
107 // Total number of STS modules in the setup
108 const uint32_t uNbModules = parset->GetNbOfModules();
109 LOG(debug) << "Nr. of STS Modules: " << uNbModules;
110
111 // Total number of STS DPBs in system
112 const uint32_t uNbOfDpbs = parset->GetNrOfDpbs();
113 LOG(debug) << "Nr. of STS DPBs: " << uNbOfDpbs;
114
115 // Get Nr of Febs
116 fuNbFebs = parset->GetNrOfFebs();
117 LOG(debug) << "Nr. of FEBs: " << fuNbFebs;
118
119 // Get Nr of eLinks per CROB
121
122 // Get Nr of ASICs per CROB
124
125 // Get Nr of CROBs per DPB
127
128 // Get Number of ASICs per FEB
130
131 // Get Number of Channels per Asic
133
134 // Get Number of Channels per FEB
135 fNrChsPerFeb = parset->GetNbChanPerFeb();
136
137 // Get Number of FEBs per CROB
139
140 for (size_t ielink = 0; ielink < fNrElinksPerCrob; ++ielink) {
141 fElinkIdxToFebIdxVec.emplace_back(parset->ElinkIdxToFebIdx(ielink));
142 fElinkIdxToAsicIdxVec.emplace_back(
143 std::make_pair(parset->ElinkIdxToAsicIdxFebA(ielink), parset->ElinkIdxToAsicIdxFebB(ielink)));
144 }
145
146 // Get Nr of Asics
147 const uint32_t uNbStsXyters = parset->GetNrOfAsics();
148 LOG(debug) << "Nr. of StsXyter ASICs: " << uNbStsXyters;
149
150 //Initialize temporary "per Feb" fields
151 initTempVectors(parset, &viModuleType, &viModAddress, &viFebModuleIdx, &vbCrobActiveFlag, &viFebModuleSide);
152
153 // Initialize ADC cuts for FEBs
155 for (auto cut : fdAdcCut_perFeb) {
156 fvbFebAdcCut[cut.first] = cut.second;
157 }
158
159 // Read dpb index map from parameter container
160 initDpbIdIndexMap(parset);
161
162 if (fvdTimeOffsetNsAsics.size() < uNbStsXyters) {
163 fvdTimeOffsetNsAsics.resize(uNbStsXyters, 0.0);
164 }
165
166 //Initialize class-wide "per Feb" fields
167 fviFebType.resize(uNbOfDpbs);
168
169 for (uint32_t uDpb = 0; uDpb < uNbOfDpbs; ++uDpb) {
170 fviFebType[uDpb].resize(fNrCrobPerDpb);
171 for (uint32_t uCrobIdx = 0; uCrobIdx < fNrCrobPerDpb; ++uCrobIdx) {
172 fviFebType[uDpb][uCrobIdx].resize(parset->GetNbFebsPerCrob(), -1);
173 for (uint32_t uFebIdx = 0; uFebIdx < parset->GetNbFebsPerCrob(); ++uFebIdx) {
174 fvbFebPulser.push_back(parset->IsFebPulser(uDpb, uCrobIdx, uFebIdx));
175 fvdFebAdcGain.push_back(parset->GetFebAdcGain(uDpb, uCrobIdx, uFebIdx));
176 fvdFebAdcOffs.push_back(parset->GetFebAdcOffset(uDpb, uCrobIdx, uFebIdx));
177
178 if (0 <= viFebModuleIdx[uDpb][uCrobIdx][uFebIdx]
179 && static_cast<uint32_t>(viFebModuleIdx[uDpb][uCrobIdx][uFebIdx]) < uNbModules
180 && 0 <= viFebModuleSide[uDpb][uCrobIdx][uFebIdx] && viFebModuleSide[uDpb][uCrobIdx][uFebIdx] < 2) {
181 switch (viModuleType[viFebModuleIdx[uDpb][uCrobIdx][uFebIdx]]) {
182 case 0: // FEB-8-1 with ZIF connector on the right
183 {
184 // P side (0) has type A (0)
185 // N side (1) has type B (1)
186 fviFebType[uDpb][uCrobIdx][uFebIdx] = viFebModuleSide[uDpb][uCrobIdx][uFebIdx];
187
194 fviFebAddress.push_back(viModAddress[viFebModuleIdx[uDpb][uCrobIdx][uFebIdx]]);
195 // + (viFebModuleSide[uDpb][uCrobIdx][uFebIdx] << 25));
196 fviFebSide.push_back(viFebModuleSide[uDpb][uCrobIdx][uFebIdx]);
197 break;
198 } // case 0: // FEB-8-1 with ZIF connector on the right
199 case 1: // FEB-8-1 with ZIF connector on the left
200 {
201 // P side (0) has type B (1)
202 // N side (1) has type A (0)
203 fviFebType[uDpb][uCrobIdx][uFebIdx] = !(viFebModuleSide[uDpb][uCrobIdx][uFebIdx]);
204
211 fviFebAddress.push_back(viModAddress[viFebModuleIdx[uDpb][uCrobIdx][uFebIdx]]);
212 // + ((!viFebModuleSide[uDpb][uCrobIdx][uFebIdx]) << 25));
213 fviFebSide.push_back(viFebModuleSide[uDpb][uCrobIdx][uFebIdx]);
214 break;
215 } // case 1: // FEB-8-1 with ZIF connector on the left
216 default:
217 LOG(fatal) << Form("Bad module type for DPB #%02u CROB #%u FEB %02u: %d", uDpb, uCrobIdx, uFebIdx,
218 viModuleType[viFebModuleIdx[uDpb][uCrobIdx][uFebIdx]]);
219 break;
220 }
221 } // FEB active and module index OK
222 else if (-1 == viFebModuleIdx[uDpb][uCrobIdx][uFebIdx] || -1 == viFebModuleSide[uDpb][uCrobIdx][uFebIdx]) {
223 fviFebAddress.push_back(0);
224 fviFebSide.push_back(-1);
225 } // Module index or type is set to inactive
226 else {
227 LOG(fatal) << Form("Bad module Index and/or Side for DPB #%02u CROB "
228 "#%u FEB %02u: %d %d",
229 uDpb, uCrobIdx, uFebIdx, viFebModuleIdx[uDpb][uCrobIdx][uFebIdx],
230 viFebModuleSide[uDpb][uCrobIdx][uFebIdx]);
231 } // Bad module index or type for this FEB
232 }
233 }
234 }
235
236 printActiveCrobs(parset, vbCrobActiveFlag);
237 printAddressMaps(parset, viFebModuleIdx, viFebModuleSide);
238
239 LOG(debug) << "Unpacking data in bin sorter FW mode";
240 initInternalStatus(parset);
241
242 if (fMonitor) fMonitor->Init(parset);
243
244 return kTRUE;
245}
246
247// ---- initTempVectors ----
248void CbmStsUnpackAlgo::initTempVectors(CbmMcbm2018StsPar* parset, std::vector<int32_t>* viModuleType,
249 std::vector<int32_t>* viModAddress,
250 std::vector<std::vector<std::vector<int32_t>>>* viFebModuleIdx,
251 std::vector<std::vector<bool>>* vbCrobActiveFlag,
252 std::vector<std::vector<std::vector<int32_t>>>* viFebModuleSide)
253{
254 const uint32_t uNbModules = parset->GetNbOfModules();
255 const uint32_t uNbOfDpbs = parset->GetNrOfDpbs();
256
257 viModuleType->resize(uNbModules);
258 viModAddress->resize(uNbModules);
259 for (uint32_t uModIdx = 0; uModIdx < uNbModules; ++uModIdx) {
260 (*viModuleType)[uModIdx] = parset->GetModuleType(uModIdx);
261 (*viModAddress)[uModIdx] = parset->GetModuleAddress(uModIdx);
262 LOG(debug) << "Module #" << std::setw(2) << uModIdx << " Type " << std::setw(4) << (*viModuleType)[uModIdx]
263 << " Address 0x" << std::setw(8) << std::hex << (*viModAddress)[uModIdx] << std::dec;
264 }
265 vbCrobActiveFlag->resize(uNbOfDpbs);
266 viFebModuleIdx->resize(uNbOfDpbs);
267 viFebModuleSide->resize(uNbOfDpbs);
268
269 for (uint32_t uDpb = 0; uDpb < uNbOfDpbs; ++uDpb) {
270 (*vbCrobActiveFlag)[uDpb].resize(fNrCrobPerDpb);
271 (*viFebModuleIdx)[uDpb].resize(fNrCrobPerDpb);
272 (*viFebModuleSide)[uDpb].resize(fNrCrobPerDpb);
273 for (uint32_t uCrobIdx = 0; uCrobIdx < fNrCrobPerDpb; ++uCrobIdx) {
274 (*vbCrobActiveFlag)[uDpb][uCrobIdx] = parset->IsCrobActive(uDpb, uCrobIdx);
275 (*viFebModuleIdx)[uDpb][uCrobIdx].resize(parset->GetNbFebsPerCrob());
276 (*viFebModuleSide)[uDpb][uCrobIdx].resize(parset->GetNbFebsPerCrob());
277 for (uint32_t uFebIdx = 0; uFebIdx < parset->GetNbFebsPerCrob(); ++uFebIdx) {
278 (*viFebModuleIdx)[uDpb][uCrobIdx][uFebIdx] = parset->GetFebModuleIdx(uDpb, uCrobIdx, uFebIdx);
279 (*viFebModuleSide)[uDpb][uCrobIdx][uFebIdx] = parset->GetFebModuleSide(uDpb, uCrobIdx, uFebIdx);
280 }
281 }
282 }
283}
284
285// ---- initInternalStatus ----
287{
288 const uint32_t uNbOfDpbs = parset->GetNrOfDpbs();
289 const uint32_t uNbStsXyters = parset->GetNrOfAsics();
290
291 fvulCurrentTsMsb.resize(uNbOfDpbs);
292 fvuCurrentTsMsbCycle.resize(uNbOfDpbs);
293 fulTsMsbIndexInTs.resize(uNbOfDpbs);
294 for (uint32_t uDpb = 0; uDpb < uNbOfDpbs; ++uDpb) {
295 fvulCurrentTsMsb[uDpb] = 0;
296 fvuCurrentTsMsbCycle[uDpb] = 0;
297 fulTsMsbIndexInTs[uDpb] = 0;
298 }
299
300 fvvusLastTsChan.resize(uNbStsXyters);
301 fvvusLastAdcChan.resize(uNbStsXyters);
302 fvvulLastTsMsbChan.resize(uNbStsXyters);
303 for (uint32_t uAsicIdx = 0; uAsicIdx < uNbStsXyters; ++uAsicIdx) {
304 fvvusLastTsChan[uAsicIdx].resize(fNrChsPerAsic, 0);
305 fvvusLastAdcChan[uAsicIdx].resize(fNrChsPerAsic, 0);
306 fvvulLastTsMsbChan[uAsicIdx].resize(fNrChsPerAsic, 0);
307 }
308}
309
310// ---- loopMsMessages ----
311void CbmStsUnpackAlgo::loopMsMessages(const uint8_t* msContent, const uint32_t uSize, const size_t uMsIdx)
312{
313 // If not integer number of message in input buffer, print warning/error
314 if (0 != (uSize % sizeof(stsxyter::Message))) {
315 LOG(error) << "The input microslice buffer does NOT "
316 << "contain only complete sDPB messages!";
317 }
318 // Compute the number of complete messages in the input microslice buffer
319 const uint32_t uNbMessages = (uSize - (uSize % sizeof(stsxyter::Message))) / sizeof(stsxyter::Message);
320
321 // Prepare variables for the loop on contents
322 const stsxyter::Message* pMess = reinterpret_cast<const stsxyter::Message*>(msContent);
323
324 for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx++) {
326 const stsxyter::MessType typeMess = pMess[uIdx].GetMessType();
327
328 LOG(debug2) << " Msg Idx " << std::setw(6) << uIdx << " Type " << stsxyter::Message::PrintMessType(typeMess);
329
330 if (fMonitor)
331 if (fMonitor->GetDebugMode()) {
332 fMonitor->ProcessDebugInfo(pMess[uIdx], fuCurrDpbIdx);
333 }
334 switch (typeMess) {
336 processHitInfo(pMess[uIdx]);
337 break;
338 }
340 processTsMsbInfo(pMess[uIdx], uIdx, uMsIdx);
341 break;
342 }
344 processEpochInfo(pMess[uIdx]);
345 if (0 < uIdx) {
346 LOG(warning) << "CbmStsUnpackAlgo::loopMsMessages => "
347 << "EPOCH message at unexpected position in MS: message " << uIdx << " VS message 0 expected!";
348 }
349 break;
350 }
352 processStatusInfo(pMess[uIdx], uIdx);
353 break;
354 }
356 break;
357 }
359 processErrorInfo(pMess[uIdx]);
360 break;
361 }
363 break;
364 }
365 default: {
366 LOG(fatal) << "CbmStsUnpackAlgo::loopMsMessages => "
367 << "Unknown message type, should never happen, stopping "
368 "here! Type found was: "
369 << static_cast<int>(typeMess);
370 }
371 }
372 }
373}
374
375// ---- MaskNoisyChannel ----
376void CbmStsUnpackAlgo::MaskNoisyChannel(const uint32_t uFeb, const uint32_t uChan, const bool bMasked)
377{
378 if (false == fbUseChannelMask) {
379 fbUseChannelMask = true;
381 for (uint32_t uFebIdx = 0; uFebIdx < fuNbFebs; ++uFebIdx) {
382 fvvbMaskedChannels[uFebIdx].resize(fNrChsPerFeb, false);
383 }
384 }
385 if (uFeb < fuNbFebs && uChan < fNrChsPerFeb)
386 fvvbMaskedChannels[uFeb][uChan] = bMasked;
387 else
388 LOG(fatal) << "CbmStsUnpackAlgo::MaskNoisyChannel => Invalid FEB "
389 "and/or CHAN index:"
390 << Form(" %u vs %u and %u vs %u", uFeb, fuNbFebs, uChan, fNrChsPerFeb);
391}
392
393
394// ---- printActiveCrobs ----
396 const std::vector<std::vector<bool>>& vbCrobActiveFlag)
397{
398 for (uint32_t uDpb = 0; uDpb < parset->GetNrOfDpbs(); ++uDpb) {
399 TString sPrintoutLine = Form("DPB #%02u CROB Active ?: ", uDpb);
400 for (uint32_t uCrobIdx = 0; uCrobIdx < fNrCrobPerDpb; ++uCrobIdx) {
401 sPrintoutLine += Form("%1u", (vbCrobActiveFlag[uDpb][uCrobIdx] == true));
402 }
403 LOG(debug) << sPrintoutLine;
404 }
405}
406
407// ---- printAddressMaps ----
409 const std::vector<std::vector<std::vector<int32_t>>>& viFebModuleIdx,
410 const std::vector<std::vector<std::vector<int32_t>>>& viFebModuleSide)
411{
412 uint32_t uGlobalFebIdx = 0;
413 for (uint32_t uDpb = 0; uDpb < parset->GetNrOfDpbs(); ++uDpb) {
414 for (uint32_t uCrobIdx = 0; uCrobIdx < fNrCrobPerDpb; ++uCrobIdx) {
415 LOG(debug) << Form("DPB #%02u CROB #%u: ", uDpb, uCrobIdx);
416 for (uint32_t uFebIdx = 0; uFebIdx < parset->GetNbFebsPerCrob(); ++uFebIdx) {
417 if (0 <= viFebModuleIdx[uDpb][uCrobIdx][uFebIdx])
418 LOG(debug) << Form(" FEB #%02u (%02u): Mod. Idx = %03d Side %c (%2d) Type %c "
419 "(%2d) (Addr. 0x%08x) ADC gain %4.0f e- ADC Offs %5.0f e-",
420 uFebIdx, uGlobalFebIdx, viFebModuleIdx[uDpb][uCrobIdx][uFebIdx],
421 1 == viFebModuleSide[uDpb][uCrobIdx][uFebIdx] ? 'N' : 'P',
422 viFebModuleSide[uDpb][uCrobIdx][uFebIdx],
423 1 == fviFebType[uDpb][uCrobIdx][uFebIdx] ? 'B' : 'A', fviFebType[uDpb][uCrobIdx][uFebIdx],
424 fviFebAddress[uGlobalFebIdx], fvdFebAdcGain[uGlobalFebIdx], fvdFebAdcOffs[uGlobalFebIdx]);
425 else
426 LOG(debug) << Form("Disabled FEB #%02u (%02u): Mod. Idx = %03d Side %c (%2d) Type %c "
427 "(%2d) (Addr. 0x%08x) ADC gain %4.0f e- ADC Offs %5.0f e-",
428 uFebIdx, uGlobalFebIdx, viFebModuleIdx[uDpb][uCrobIdx][uFebIdx],
429 1 == viFebModuleSide[uDpb][uCrobIdx][uFebIdx] ? 'N' : 'P',
430 viFebModuleSide[uDpb][uCrobIdx][uFebIdx],
431 1 == fviFebType[uDpb][uCrobIdx][uFebIdx] ? 'B' : 'A', fviFebType[uDpb][uCrobIdx][uFebIdx],
432 fviFebAddress[uGlobalFebIdx], fvdFebAdcGain[uGlobalFebIdx], fvdFebAdcOffs[uGlobalFebIdx]);
433 uGlobalFebIdx++;
434 }
435 }
436 }
437}
438
439// -------------------------------------------------------------------------
441{
442 if (mess.IsMsErrorFlagOn()) {
443 // I do pass here the Ts start time instead of the ms time, since, we removed the ms time as member for the time being
444 if (fMonitor) {
445 fMonitor->FillMsErrorsEvo(fMsStartTime, mess.GetMsErrorType());
446 }
447 if (fOptOutBVec)
448 fOptOutBVec->emplace_back(
450 }
451}
452
453// ---- processHitInfo ----
455{
456 const uint16_t usElinkIdx = mess.GetLinkIndexHitBinning();
457 const uint32_t uCrobIdx = usElinkIdx / fNrElinksPerCrob;
458 int32_t uFebIdx = fElinkIdxToFebIdxVec.at(usElinkIdx);
459 if (-1 == uFebIdx) {
460 LOG(warning) << "CbmStsUnpackAlgo::processHitInfo => "
461 << "Wrong elink Idx! Elink raw " << Form("%d remap %d", usElinkIdx, uFebIdx);
462 return;
463 }
464 //uFebIdx += ( fuCurrDpbIdx * fNrCrobPerDpb + ____CrobIndexCalculationIfNeeded___() ) * fuNbFebsPerCrob;
465 uFebIdx += (fuCurrDpbIdx * fNrCrobPerDpb) * fNrFebsPerCrob; //no Crob index calculation for now
466
467 // Get the asic index
468 uint32_t uAsicIdx = getAsicIndex(fuCurrDpbIdx, uCrobIdx, usElinkIdx);
469
470 const uint16_t usChan = mess.GetHitChannel();
471 const uint16_t usRawAdc = mess.GetHitAdc();
472 const uint16_t usRawTs = mess.GetHitTimeBinning();
473 const uint32_t uChanInFeb = usChan + fNrChsPerAsic * (uAsicIdx % fNrAsicsPerFeb);
474
475 // Compute the Full time stamp
476 const uint64_t ulHitTime = getFullTimeStamp(usRawTs);
477
478 if (fMonitor) fMonitor->CountRawHit(uFebIdx, uChanInFeb);
479
481 if (fviFebAddress[uFebIdx] != 0 && fvbFebAdcCut[uFebIdx] < usRawAdc) {
484 if (false == fbUseChannelMask || false == fvvbMaskedChannels[uFebIdx][uChanInFeb]) {
485 // If you want to store this as well, add it to the template as TOptOut, otherwise I do not see a reason to create it at all
486 // auto finalhit = stsxyter::FinalHit(ulHitTime, usRawAdc, uAsicIdx, usChan, fuCurrDpbIdx, uCrobIdx);
487
490 if (usRawTs == fvvusLastTsChan[uAsicIdx][usChan]
491 && (fbDupliWithoutAdc || usRawAdc == fvvusLastAdcChan[uAsicIdx][usChan])
492 && fulTsMsbIndexInTs[fuCurrDpbIdx] == fvvulLastTsMsbChan[uAsicIdx][usChan]) {
494 LOG(debug1) << "CbmStsUnpackAlgo::processHitInfo => "
495 << Form("Rejecting duplicate on Asic %3u channel %3u, TS %3u, ADC %2u", uAsicIdx, usChan, usRawTs,
496 usRawAdc);
497
498 if (fMonitor) fMonitor->FillDuplicateHitsAdc(uFebIdx, uChanInFeb, usRawAdc);
499 return;
500 } // if same TS, (ADC,) TS MSB, TS MSB cycle, reject
501 fvvusLastTsChan[uAsicIdx][usChan] = usRawTs;
502 fvvusLastAdcChan[uAsicIdx][usChan] = usRawAdc;
504 } // if (fbRejectDuplicateDigis)
505
506 uint32_t uChanInMod = usChan + fNrChsPerAsic * (uAsicIdx % fNrAsicsPerFeb);
507
511
512 if (0 == fviFebSide[uFebIdx])
513 uChanInMod = fNrChsPerFeb - uChanInMod - 1 // Invert channel order
514 + fNrChsPerFeb; // Offset for P (back) side
515
516 /*
517 // Get the time relative to the Timeslice time, I hope that the cast here works as expected. Otherwise Sts will also get into trouble with the size of UTC here
518 auto tsreltime =
519 static_cast<uint64_t>((ulHitTime - (fTsStartTime / stsxyter::kdClockCycleNs)) * stsxyter::kdClockCycleNs);
520*/
521 const double_t tsreltime = static_cast<double_t>(ulHitTime) * stsxyter::kdClockCycleNs;
522 double dTimeInNs = tsreltime - fSystemTimeOffset;
523
524 // Time-Walk correction or Asic-byAsic offsetting, depending on availability
525 if (fbUseTimeWalkCorrection == true && fWalkLookup.count(fviFebAddress[uFebIdx])) {
526 dTimeInNs += fWalkLookup[fviFebAddress[uFebIdx]][uChanInMod / fNrChsPerAsic][usRawAdc - 1];
527 }
528 else if (uAsicIdx < fvdTimeOffsetNsAsics.size()) {
529 dTimeInNs -= fvdTimeOffsetNsAsics[uAsicIdx];
530 }
531
532
533 const uint64_t ulTimeInNs = static_cast<uint64_t>(dTimeInNs);
534 const double dCalAdc = fvdFebAdcOffs[uFebIdx] + (usRawAdc - 1) * fvdFebAdcGain[uFebIdx];
535
536 if (0 == fviFebAddress[uFebIdx] || -1 == fviFebSide[uFebIdx]) {
537 LOG(error) << Form("Digi on disabled FEB %02u has address 0x%08x and side %d", uFebIdx, fviFebAddress[uFebIdx],
538 fviFebSide[uFebIdx]);
539 }
540
541 if (fMonitor) fMonitor->CountDigi(uFebIdx, uChanInFeb);
542
544 if (fvbFebPulser[uFebIdx]) {
545 if (fOptOutAVec) {
546 fOptOutAVec->emplace_back(CbmStsDigi(fviFebAddress[uFebIdx], uChanInMod, ulTimeInNs, dCalAdc));
547 } // if (fOptOutAVec)
548 } // if (fvbFebPulser[uFebIdx])
549 else {
550 fOutputVec.emplace_back(CbmStsDigi(fviFebAddress[uFebIdx], uChanInMod, ulTimeInNs, dCalAdc));
551 } // else of if (fvbFebPulser[uFebIdx])
552
554 if (mess.IsHitMissedEvts())
555 if (fOptOutBVec)
556 fOptOutBVec->emplace_back(CbmErrorMessage(ECbmModuleId::kSts, dTimeInNs, fviFebAddress[uFebIdx],
557 1 << stsxyter::kusLenStatStatus, uChanInMod));
558 }
559 }
560
561 if (fMonitor) {
562 // Convert the Hit time in bins within the TS to Hit time in secondes within Unix frame (UTC or TAI)
563 const double dHitTimeAbsSec =
564 (static_cast<double_t>(ulHitTime) * stsxyter::kdClockCycleNs - fSystemTimeOffset + fTsStartTime) * 1e-9;
565
566 // Prepare monitoring values
567 const uint32_t uAsicInFeb = uAsicIdx % fNrAsicsPerFeb;
568 const double dCalAdc = fvdFebAdcOffs[uFebIdx] + (usRawAdc - 1) * fvdFebAdcGain[uFebIdx];
569
570 fMonitor->FillHitMonitoringHistos(uFebIdx, usChan, uChanInFeb, usRawAdc, dCalAdc, usRawTs, mess.IsHitMissedEvts());
571 fMonitor->FillHitEvoMonitoringHistos(uFebIdx, uAsicIdx, uAsicInFeb, uChanInFeb, dHitTimeAbsSec,
572 mess.IsHitMissedEvts());
573
574 if (fMonitor->GetDebugMode()) {
575 fMonitor->FillHitDebugMonitoringHistos(uAsicIdx, usChan, usRawAdc, usRawTs, mess.IsHitMissedEvts());
576 }
577 }
578}
579
580// ---- processStatusInfo ----
582{
583 // again fMonitor settings used for debugging printouts, I would propose to separat this
584 if (fMonitor)
585 if (fMonitor->GetDebugMode()) {
586 std::cout << Form("DPB %2u TS %12lu mess %5u ", fuCurrDpbIdx, fTsIndex, uIdx);
588 }
589
590 const uint16_t usElinkIdx = mess.GetStatusLink();
591 const uint32_t uCrobIdx = usElinkIdx / fNrElinksPerCrob;
592 const int32_t uFebIdx = fElinkIdxToFebIdxVec.at(usElinkIdx);
593 if (-1 == uFebIdx) {
594 LOG(warning) << "CbmStsUnpackAlgo::processStatusInfo => "
595 << "Wrong elink Idx! Elink raw " << Form("%d remap %d", usElinkIdx, uFebIdx);
596 return;
597 }
598 const uint32_t uAsicIdx = getAsicIndex(fuCurrDpbIdx, uCrobIdx, usElinkIdx);
599 if (fMonitor) {
600 const uint16_t usStatusField = mess.GetStatusStatus();
601 fMonitor->FillStsStatusMessType(uAsicIdx, usStatusField);
602 }
604 const int64_t ulTime = getFullTimeStamp(0);
605
607 const double dTimeNs = ulTime * stsxyter::kdClockCycleNs;
608 if (fOptOutBVec)
609 fOptOutBVec->emplace_back(
610 CbmErrorMessage(ECbmModuleId::kSts, dTimeNs, uAsicIdx, mess.GetStatusStatus(), mess.GetData()));
611}
612
613
614// ---- processTsMsbInfo ----
615void CbmStsUnpackAlgo::processTsMsbInfo(const stsxyter::Message& mess, uint32_t uMessIdx, uint32_t uMsIdx)
616{
617 const uint32_t uVal = mess.GetTsMsbValBinning();
618
619 // Update Status counters
620 if (uVal < fvulCurrentTsMsb[fuCurrDpbIdx]) {
621
622 LOG(debug) << " TS " << std::setw(12) << fTsIndex << " MS Idx " << std::setw(4) << uMsIdx << " Msg Idx "
623 << std::setw(5) << uMessIdx << " DPB " << std::setw(2) << fuCurrDpbIdx << " Old TsMsb " << std::setw(5)
624 << fvulCurrentTsMsb[fuCurrDpbIdx] << " Old MsbCy " << std::setw(5) << fvuCurrentTsMsbCycle[fuCurrDpbIdx]
625 << " new TsMsb " << std::setw(5) << uVal;
626
628 }
629 if (uVal != fvulCurrentTsMsb[fuCurrDpbIdx] + 1
633 && !(1 == uMessIdx && 0 == uMsIdx)
635 && !(uVal == fvulCurrentTsMsb[fuCurrDpbIdx] && 2 == uMessIdx)
637 && uVal < fvulCurrentTsMsb[fuCurrDpbIdx]) {
638 LOG(debug) << "TS MSB Jump in "
639 << " TS " << std::setw(12) << fTsIndex << " MS Idx " << std::setw(4) << uMsIdx << " Msg Idx "
640 << std::setw(5) << uMessIdx << " DPB " << std::setw(2) << fuCurrDpbIdx << " => Old TsMsb "
641 << std::setw(5) << fvulCurrentTsMsb[fuCurrDpbIdx] << " new TsMsb " << std::setw(5) << uVal;
642 }
643
645
646 LOG(debug1) << " TS " << std::setw(12) << fTsIndex << " MS Idx " << std::setw(4) << uMsIdx << " Msg Idx "
647 << std::setw(5) << uMessIdx << " DPB " << std::setw(2) << fuCurrDpbIdx << " TsMsb " << std::setw(5)
648 << fvulCurrentTsMsb[fuCurrDpbIdx] << " MsbCy " << std::setw(5) << fvuCurrentTsMsbCycle[fuCurrDpbIdx];
649
652 + (fvuCurrentTsMsbCycle[fuCurrDpbIdx] * static_cast<uint64_t>(1 << stsxyter::kusLenTsMsbValBinning));
654 LOG(fatal) << "CbmStsUnpackAlgo::processTsMsbInfo => "
655 << "Value computed from TS_MSB and TS_MSB cycle smaller than Timeslice start in TS_MSB, "
656 << "would lead to a negative value so it cannot be recovered!!!!"
657 << std::endl
659 << "TS_MSB: " << fvulCurrentTsMsb[fuCurrDpbIdx] << " Cycle: " << fvuCurrentTsMsbCycle[fuCurrDpbIdx]
660 << " Full TS_MSB: " << fulTsMsbIndexInTs[fuCurrDpbIdx] << " TS Start offset: " << fulTsStartInTsMsb;
661 }
663
664 if (fMonitor)
665 if (fMonitor->GetDebugMode()) { //also if( 1 < uMessIdx )?
666 fMonitor->FillStsDpbRawTsMsb(fuCurrDpbIdx, fvulCurrentTsMsb[fuCurrDpbIdx]);
667 fMonitor->FillStsDpbRawTsMsbSx(fuCurrDpbIdx, fvulCurrentTsMsb[fuCurrDpbIdx]);
668 fMonitor->FillStsDpbRawTsMsbDpb(fuCurrDpbIdx, fvulCurrentTsMsb[fuCurrDpbIdx]);
669 }
670}
671
672// ---- refreshTsMsbFields ----
673void CbmStsUnpackAlgo::refreshTsMsbFields(const uint32_t imslice, const size_t mstime)
674{
675 const uint32_t uTsMsbCycleHeader =
677 const uint32_t uTsMsbHeader =
678 std::floor((mstime - uTsMsbCycleHeader * (stsxyter::kulTsCycleNbBinsBinning * stsxyter::kdClockCycleNs))
680
681 LOG(debug1) << " TS " << std::setw(12) << fTsIndex << " MS " << std::setw(12) << mstime << " MS Idx " << std::setw(4)
682 << imslice << " Msg Idx " << std::setw(5) << 0 << " DPB " << std::setw(2) << fuCurrDpbIdx << " Old TsMsb "
683 << std::setw(5) << fvulCurrentTsMsb[fuCurrDpbIdx] << " Old MsbCy " << std::setw(5)
684 << fvuCurrentTsMsbCycle[fuCurrDpbIdx] << " header TsMsb " << uTsMsbHeader << " New MsbCy "
685 << uTsMsbCycleHeader;
686
687 if (0 == imslice) {
688 if (uTsMsbCycleHeader != fvuCurrentTsMsbCycle[fuCurrDpbIdx])
689 LOG(debug) << " TS " << std::setw(12) << fTsIndex << " MS " << std::setw(12) << mstime << " MS Idx "
690 << std::setw(4) << imslice << " Msg Idx " << std::setw(5) << 0 << " DPB " << std::setw(2)
691 << fuCurrDpbIdx << " Old TsMsb " << std::setw(5) << fvulCurrentTsMsb[fuCurrDpbIdx] << " Old MsbCy "
692 << std::setw(5) << fvuCurrentTsMsbCycle[fuCurrDpbIdx] << " New TsMsb " << uTsMsbHeader << " New MsbCy "
693 << uTsMsbCycleHeader;
694 fvuCurrentTsMsbCycle[fuCurrDpbIdx] = uTsMsbCycleHeader;
695 fvulCurrentTsMsb[fuCurrDpbIdx] = uTsMsbHeader;
696
699 + (fvuCurrentTsMsbCycle[fuCurrDpbIdx] * static_cast<uint64_t>(1 << stsxyter::kusLenTsMsbValBinning));
701 LOG(fatal) << "CbmStsUnpackAlgo::refreshTsMsbFields => "
702 << "Value computed from TS_MSB and TS_MSB cycle smaller than Timeslice start in TS_MSB, "
703 << "would lead to a negative value so it cannot be recovered!!!!"
704 << std::endl
706 << "TS_MSB: " << fvulCurrentTsMsb[fuCurrDpbIdx] << " Cycle: " << fvuCurrentTsMsbCycle[fuCurrDpbIdx]
707 << " Full TS_MSB: " << fulTsMsbIndexInTs[fuCurrDpbIdx] << " TS Start offset: " << fulTsStartInTsMsb;
708 }
710 }
711 else if (uTsMsbCycleHeader != fvuCurrentTsMsbCycle[fuCurrDpbIdx]) {
714 LOG(debug) << " TS " << std::setw(12) << fTsIndex << " MS " << std::setw(12) << mstime << " MS Idx "
715 << std::setw(4) << imslice << " Msg Idx " << std::setw(5) << 0 << " DPB " << std::setw(2)
716 << fuCurrDpbIdx << " Old TsMsb " << std::setw(5) << fvulCurrentTsMsb[fuCurrDpbIdx] << " Old MsbCy "
717 << std::setw(5) << fvuCurrentTsMsbCycle[fuCurrDpbIdx] << " New MsbCy " << uTsMsbCycleHeader;
718 }
719 else {
720 LOG(warning) << "TS MSB cycle from MS header does not match current cycle from data "
721 << "for TS " << std::setw(12) << fTsIndex << " MS " << std::setw(12) << mstime << " MsInTs "
722 << std::setw(3) << imslice << " ====> " << fvuCurrentTsMsbCycle[fuCurrDpbIdx] << " (cnt) VS "
723 << uTsMsbCycleHeader << " (header)";
724 fvuCurrentTsMsbCycle[fuCurrDpbIdx] = uTsMsbCycleHeader;
725 }
726 }
727}
728
729// ---- unpack ----
730bool CbmStsUnpackAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp, UInt_t imslice)
731{
732 auto msDescriptor = ts->descriptor(icomp, imslice);
733
737 if (fMonitor && 0 == imslice && 0 < fMsStartTime && msDescriptor.idx == ts->start_time()
738 && fMsStartTime < msDescriptor.idx) {
739 fMonitor->FillPerTimesliceCountersHistos(static_cast<double_t>(fMsStartTime) / 1e9);
740 }
741
742 //Current equipment ID, tells from which DPB the current MS is originating
743 const uint32_t uCurrentEquipmentId = msDescriptor.eq_id;
744 const uint8_t* msContent = reinterpret_cast<const uint8_t*>(ts->content(icomp, imslice));
745 const uint32_t uSize = msDescriptor.size;
746
747 fMsStartTime = msDescriptor.idx;
748 LOG(debug) << "Microslice: " << fMsStartTime << " from EqId " << std::hex << uCurrentEquipmentId << std::dec
749 << " has size: " << uSize << " (index " << imslice << ")";
750
751 if (0 == fvbMaskedComponents.size()) fvbMaskedComponents.resize(ts->num_components(), false);
752
753 //Temp holder until current equipment ID is properly filled in MS
754 const uint32_t uCurrDpbId = static_cast<uint32_t>(uCurrentEquipmentId & 0xFFFF);
755
756 if (fMonitor)
757 if (fMonitor->GetDebugMode()) {
758 const double dMsTime = (1e-9) * static_cast<double>(fMsStartTime);
759 if (icomp < fMonitor->GetMaxNbFlibLinks()) {
760 fMonitor->CreateMsComponentSizeHistos(icomp);
761 fMonitor->FillMsSize(icomp, uSize);
762 fMonitor->FillMsSizeTime(icomp, dMsTime, uSize);
763 }
764 }
765
767 auto it = fDpbIdIndexMap.find(uCurrDpbId);
768 if (it == fDpbIdIndexMap.end()) {
769 if (false == fvbMaskedComponents[icomp]) {
770 // LOG(debug) << "---------------------------------------------------------------";
771 // Had to remove this line otherwise we would get circle dependencies in the current stage of cbmroot, since we still have Unpackers in the fles folders, which require the reco folders
772 // LOG(debug) << FormatMsHeaderPrintout(msDescriptor);
773 LOG(warning) << fName << "::unpack(...)::Could not find the sDPB index for AFCK id 0x" << std::hex << uCurrDpbId
774 << std::dec << " in timeslice " << fNrProcessedTs << " in microslice " << imslice << " component "
775 << icomp << "\n"
776 << "If valid this index has to be added in the STS "
777 "parameter file in the DbpIdArray field";
778 fvbMaskedComponents[icomp] = true;
779
782 if (1 == fNrProcessedTs) return true;
783 }
784 else
785 return true;
786
787 // REMARK please check experts, but I think this point can never be reached PR 072021
788 return false;
789 }
790 else
791 fuCurrDpbIdx = fDpbIdIndexMap[uCurrDpbId];
792
793 if (fMonitor) fMonitor->FillMsCntEvo(fMsStartTime);
794
795 if (0 == imslice) {
798 static_cast<uint64_t>(fTsStartTime / (stsxyter::kuHitNbTsBinsBinning * stsxyter::kdClockCycleNs));
799 }
800
801 // Check the current TS_MSb cycle and correct it if wrong
803
804 //Reset internal monitor variables for debugging info
805 if (fMonitor) {
806 if (fMonitor->GetDebugMode()) {
807 fMonitor->ResetDebugInfo();
808 }
809 }
810
811 //Main processing of MS content
812 loopMsMessages(msContent, uSize, imslice);
813
814 //Output debugging info
815 if (fMonitor) {
816 if (fMonitor->GetDebugMode()) {
817 fMonitor->PrintDebugInfo(fMsStartTime, fNrProcessedTs, msDescriptor.flags, uSize);
818 }
819 for (auto itHit = fOutputVec.begin(); itHit != fOutputVec.end(); ++itHit) {
820 fMonitor->FillDigisTimeInRun(itHit->GetTime());
821 }
822 fMonitor->FillVectorSize(ts->index(), fOutputVec.size());
823 //fMonitor->DrawCanvases();
824 }
825 return true;
826}
827
ClassImp(CbmConverterManager)
@ kSts
Silicon Tracking System.
Baseclass for the STS unpacker algorithms.
CbmRoot (+externals) headers.
Double_t GetFebAdcGain(UInt_t uDpbIdx, UInt_t uCrobIdx, UInt_t uFebIdx)
UInt_t GetDpbId(UInt_t uDpbIdx)
Int_t ElinkIdxToFebIdx(UInt_t uElink)
Int_t GetFebModuleIdx(UInt_t uDpbIdx, UInt_t uCrobIdx, UInt_t uFebIdx)
UInt_t GetModuleType(UInt_t uModuleIdx)
static constexpr UInt_t GetNbFebsPerCrob()
static constexpr UInt_t GetNbAsicsPerFeb()
static constexpr UInt_t GetNbElinkPerCrob()
Double_t GetFebAdcOffset(UInt_t uDpbIdx, UInt_t uCrobIdx, UInt_t uFebIdx)
static constexpr UInt_t GetNbAsicsPerCrob()
Bool_t IsCrobActive(UInt_t uDpbIdx, UInt_t uCrobIdx)
static constexpr UInt_t GetNbCrobsPerDpb()
UInt_t ElinkIdxToAsicIdxFebA(UInt_t uElink)
UInt_t ElinkIdxToAsicIdxFebB(UInt_t uElink)
UInt_t GetModuleAddress(UInt_t uModuleIdx)
Bool_t IsFebPulser(UInt_t uFebInSystIdx)
Int_t GetFebModuleSide(UInt_t uDpbIdx, UInt_t uCrobIdx, UInt_t uFebIdx)
static constexpr UInt_t GetNbChanPerAsic()
static constexpr UInt_t GetNbChanPerFeb()
Data class for a single-channel message in the STS.
Definition CbmStsDigi.h:40
std::vector< double > fvdTimeOffsetNsAsics
Time offsets per Asic???
bool fbUseTimeWalkCorrection
Enable/Disable time-walk correction.
bool fbUseFwBinning
Enables firmware binning (some implementations ignore this)
uint32_t fdAdcCut
Minimum adc cut to store a hit.
std::map< uint32_t, std::vector< std::vector< double > > > fWalkLookup
Per-ASIC's sensors Time-Walk correction mapping.
bool fbRejectDuplicateDigis
Enables the rejection of duplicate digis.
std::shared_ptr< CbmStsUnpackMonitor > fMonitor
Potential (online) monitor for the unpacking process.
std::map< uint32_t, uint32_t > fdAdcCut_perFeb
Minimum adc cut per Feb to store a hit.
bool fbDupliWithoutAdc
If rejecting duplicate digis, enables rejection even if ADC differs.
uint32_t fuCurrDpbIdx
Current dpb id.
std::vector< std::vector< bool > > fvvbMaskedChannels
Vector of channel masks, [ NbFeb ][ NbCHanInFeb ], used only if fbUseChannelMask is true.
std::vector< double > fvdFebAdcOffs
ADC offset in e-, [ NbDpb * NbCrobPerDpb * NbFebsPerCrob ].
void initInternalStatus(CbmMcbm2018StsPar *parset)
experts please add description here
std::vector< int32_t > fviFebSide
Module side for each FEB, [ NbDpb * NbCrobPerDpb * NbFebsPerCrob ].
std::vector< uint32_t > fvuCurrentTsMsbCycle
Current TS MSB cycle for DPB.
void initDpbIdIndexMap(CbmMcbm2018StsPar *parset)
Initialize the DpbIdIndexMap with the information from the parset.
uint32_t fNrAsicsPerFeb
Number of ASICs per FEB.
uint32_t fNrCrobPerDpb
Number of CROBs per DPB.
std::vector< uint64_t > fvulCurrentTsMsb
Current TS MSB for each DPB.
Bool_t initParSet(FairParGenericSet *parset)
Handles the distribution of the hidden derived classes to their explicit functions.
void processEpochInfo(const stsxyter::Message &)
experts please add description marked as not used currently
std::vector< std::vector< uint64_t > > fvvulLastTsMsbChan
TS MSB in TS of last hit message for each channel, [ AsicIdx ][ Chan ].
std::vector< bool > fvbMaskedComponents
Masked components to print out missing component only once.
void processErrorInfo(const stsxyter::Message &mess)
experts please add description
std::vector< int > fElinkIdxToFebIdxVec
Vector used for the translation between eLink index and FEB index.
virtual ~CbmStsUnpackAlgo()
Destroy the Cbm Sts Unpack Task object.
void loopMsMessages(const uint8_t *msContent, const uint32_t uSize, const size_t uMsIdx)
Main loop over the sts xyter messages in the µSlices.
uint32_t fNrFebsPerCrob
Number of FEBs per CROB.
CbmStsUnpackAlgo()
Create the Cbm Sts Unpack AlgoBase object.
std::map< uint32_t, uint32_t > fDpbIdIndexMap
Map of DPB Identifier to DPB index.
uint32_t fNrElinksPerCrob
Number of eLinks per CROB.
std::vector< std::pair< uint32_t, uint32_t > > fElinkIdxToAsicIdxVec
Vector used for the translation between eLink index and Asic index first is feb type A second is feb ...
virtual void MaskNoisyChannel(const uint32_t uFeb, const uint32_t uChan, const bool bMasked=true)
Mask a Noisy Channel.
Bool_t init()
Intialisation at begin of run. Special inits of the derived algos.
uint32_t getAsicIndex(uint32_t dpbidx, uint32_t crobidx, uint16_t elinkidx)
Get the Asic Index.
uint64_t fulTsStartInTsMsb
Start time of the TS expressed in TS_MSB instead of ns.
uint64_t getFullTimeStamp(const uint16_t usRawTs)
Get the Full Time Stamp from raw time stamp.
bool fbUseChannelMask
flag if channel mask is to be used or not. Set automatically via MaskNoisyChannels
bool unpack(const fles::Timeslice *ts, std::uint16_t icomp, UInt_t imslice)
Unpack a given microslice. To be implemented in the derived unpacker algos.
void processStatusInfo(const stsxyter::Message &mess, uint32_t uIdx)
experts please add description
std::vector< bool > fvbFebPulser
Pulser flag for each FEB, [ NbDpb * NbCrobPerDpb * NbFebsPerCrob ].
uint32_t fNrChsPerAsic
Number of Channels per Asic.
std::vector< std::vector< std::vector< int32_t > > > fviFebType
FEB type, [ NbDpb ][ NbCrobPerDpb ][ NbFebsPerCrob ], 0 = A, 1 = B, -1 if inactive.
std::vector< std::vector< uint16_t > > fvvusLastAdcChan
ADC of last hit message for each channel, [ AsicIdx ][ Chan ].
uint32_t fuNbFebs
Number of FEBs with StsXyter ASICs.
std::vector< std::vector< uint16_t > > fvvusLastTsChan
TS of last hit message for each channel, [ AsicIdx ][ Chan ].
void processTsMsbInfo(const stsxyter::Message &mess, uint32_t uMessIdx, uint32_t uMsIdx)
experts please add description
std::vector< uint64_t > fulTsMsbIndexInTs
Current TS MSB cycle for DPB relative to TS start.
void printActiveCrobs(CbmMcbm2018StsPar *parset, const std::vector< std::vector< bool > > &vbCrobActiveFlag)
experts please add description
uint64_t fMsStartTime
Current µSlice time.
uint32_t fNrAsicsPerCrob
Number of ASICs per CROB.
std::vector< int32_t > fviFebAddress
STS address for each FEB, [ NbDpb * NbCrobPerDpb * NbFebsPerCrob ].
uint32_t fNrChsPerFeb
Number of Channels per FEB.
void initTempVectors(CbmMcbm2018StsPar *parset, std::vector< int32_t > *viModuleType, std::vector< int32_t > *viModAddress, std::vector< std::vector< std::vector< int32_t > > > *viFebModuleIdx, std::vector< std::vector< bool > > *vbCrobActiveFlag, std::vector< std::vector< std::vector< int32_t > > > *viFebModuleSide)
Initialize and transfer the informations to the parameters storage vectors.
void printAddressMaps(CbmMcbm2018StsPar *parset, const std::vector< std::vector< std::vector< int32_t > > > &viFebModuleIdx, const std::vector< std::vector< std::vector< int32_t > > > &viFebModuleSide)
experts please add description
void refreshTsMsbFields(const uint32_t imslice, const size_t mstime)
experts please add description here
void processHitInfo(const stsxyter::Message &mess)
Process the information of the hit message and create a StsDigi from it.
std::vector< uint32_t > fvbFebAdcCut
ADC cuts for FEBs.
std::vector< double > fvdFebAdcGain
ADC gain in e-/b, [ NbDpb * NbCrobPerDpb * NbFebsPerCrob ].
XPU_D bool IsHitMissedEvts() const
For Hit data: Returns Missed event flag (1 bit field)
XPU_D uint32_t GetTsMsbValBinning() const
For TS MSB data: Returns the TS MSB 29 bit field)
XPU_D uint16_t GetHitAdc() const
For Hit data: Returns ADC value (5 bit field)
XPU_D uint16_t GetHitChannel() const
For Hit data: Returns StsXYTER channel number (7 bit field)
bool PrintMess(std::ostream &os, MessagePrintMask ctrl=MessagePrintMask::msg_print_Human, bool bBinning=true) const
XPU_D uint16_t GetStatusStatus() const
For Status data: Returns the Status field from ACK frame (4 bit field)
XPU_D MessType GetMessType() const
Returns the message type, see enum MessType.
XPU_D uint16_t GetLinkIndexHitBinning() const
XPU_D uint32_t GetData() const
XPU_D uint16_t GetHitTimeBinning() const
XPU_D uint16_t GetStatusLink() const
For Status data: Returns the Link Inedx (9 bit field)
static std::string PrintMessType(MessType type)
XPU_D uint16_t GetMsErrorType() const
For End of MS data: Returns the MS error type field (2 bit field)
XPU_D bool IsMsErrorFlagOn() const
For End of MS data: Returns the MS error flag (1 bit field)
static constexpr uint32_t kuHitNbTsBinsBinning
static constexpr uint64_t kulTsCycleNbBinsBinning
static constexpr double kdClockCycleNs
MessType
Message types.
static constexpr uint16_t kusLenTsMsbValBinning
static constexpr uint16_t kusLenStatStatus
static constexpr uint32_t kuTsMsbNbTsBinsBinning