CbmRoot
Loading...
Searching...
No Matches
CbmMcbm2018UnpackerAlgoRich.cxx
Go to the documentation of this file.
1/* Copyright (C) 2019-2020 Justus-Liebig-Universitaet Giessen, Giessen
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Egor Ovcharenko [committer], Semen Lebedev, Pierre-Alain Loizeau */
4
13
14// ROOT
15#include <Logger.h>
16
17#include <TCanvas.h>
18#include <TList.h>
19
20// CbmRoot
21#include "CbmMcbm2018RichPar.h"
22
23#include <iostream>
24
26{
27 this->Init(); //TODO why this is not called by the framework?
28}
29
31{
32 if (nullptr != fParCList) delete fParCList;
33 if (nullptr != fUnpackPar) delete fUnpackPar;
34}
35
36Bool_t CbmMcbm2018UnpackerAlgoRich::Init() { return kTRUE; }
37
39
41
43{
44 LOG(info) << "Init parameter containers for CbmMcbm2018UnpackerAlgoRich";
45 Bool_t initOK = ReInitContainers();
46
47 return initOK;
48}
49
51{
52 LOG(info) << "ReInit parameter containers for CbmMcbm2018UnpackerAlgoRich";
53
54 fUnpackPar = (CbmMcbm2018RichPar*) fParCList->FindObject("CbmMcbm2018RichPar");
55 if (fUnpackPar == nullptr) { return kFALSE; }
56
57 Bool_t initOK = InitParameters();
58
59 return initOK;
60}
61
63{
64 if (fParCList == nullptr) { fParCList = new TList(); }
65 fUnpackPar = new CbmMcbm2018RichPar("CbmMcbm2018RichPar");
67
68 return fParCList;
69}
70
72{
74 return kTRUE;
75}
76
78
79void CbmMcbm2018UnpackerAlgoRich::AddMsComponentToList(size_t component, UShort_t usDetectorId)
80{
82 for (UInt_t uCompIdx = 0; uCompIdx < fvMsComponentsList.size(); ++uCompIdx) {
83 if (component == fvMsComponentsList[uCompIdx]) { return; }
84 }
85
87 fvMsComponentsList.push_back(component);
88
89 if (fvMsComponentsList.size() == 1) { fRICHcompIdx = component; }
90 else {
91 LOG(warning) << "fvMsComponentsList.size() > 1 for RICH. Unpacking may not work due to implementation limitations.";
92 }
93
94 LOG(info) << "CbmMcbm2018UnpackerAlgoRich::AddMsComponentToList => Component " << component << " with detector ID 0x"
95 << std::hex << usDetectorId << std::dec << " added to list";
96}
97
98Bool_t CbmMcbm2018UnpackerAlgoRich::ProcessTs(const fles::Timeslice& /*ts*/)
99{
100 LOG(debug2) << "CbmMcbm2018UnpackerAlgoRich::ProcessTs(ts): this method do not have implementation.";
101 return kTRUE;
102}
103
104Bool_t CbmMcbm2018UnpackerAlgoRich::ProcessTs(const fles::Timeslice& ts, size_t component)
105{
106
107 // Get reference TS time
108 fdTsStartTime = ts.start_time();
109
111 if (0 == ts.index()) { return kTRUE; }
112
113 LOG(debug2) << "CbmMcbm2018UnpackerAlgoRich::ProcessTs(ts, " << component << ")";
114
115 if (1 != fvMsComponentsList.size()) {
117 if (0 == fvMsComponentsList.size()) return kTRUE;
118
120 TString sCompList = "";
121 for (UInt_t uMsCompIdx = 0; uMsCompIdx < fvMsComponentsList.size(); ++uMsCompIdx) {
122 sCompList += Form(" %2lu ", fvMsComponentsList[uMsCompIdx]);
123 }
124 LOG(fatal)
125 << "CbmMcbm2018UnpackerAlgoRich::ProcessTs => More than 1 component in list, unpacking impossible! List is "
126 << sCompList;
127 }
128 component = fvMsComponentsList[0];
129
130 LOG(debug) << "Components: " << ts.num_components();
131 LOG(debug) << "Microslices: " << ts.num_microslices(component);
132
133 const uint64_t compSize = ts.size_component(component);
134 LOG(debug) << "Component " << component << " has size " << compSize;
135
137 if (-1.0 == fdTsCoreSizeInNs) {
138 fuNbCoreMsPerTs = ts.num_core_microslices();
139 fuNbOverMsPerTs = ts.num_microslices(0) - ts.num_core_microslices();
142 LOG(info) << "Timeslice parameters: each TS has " << fuNbCoreMsPerTs << " Core MS and " << fuNbOverMsPerTs
143 << " Overlap MS, for a core duration of " << fdTsCoreSizeInNs << " ns and a full duration of "
144 << fdTsFullSizeInNs << " ns";
145
149 LOG(info) << "In each TS " << fuNbMsLoop << " MS will be looped over";
150 } // if( -1.0 == fdTsCoreSizeInNs )
151
152 for (size_t iMS = 0; iMS < fuNbMsLoop; ++iMS) {
153 fMsInd = iMS;
154 if (IsLog()) LOG(debug) << "=======================================================";
155 const fles::MicrosliceView mv = ts.get_microslice(component, iMS);
156 const fles::MicrosliceDescriptor& msDesc = mv.desc();
157
158 fCurMSidx = msDesc.idx;
159 if (IsLog()) LOG(debug) << "msDesc.size=" << msDesc.size << " msDesc.idx=" << msDesc.idx;
160
161 if (!fRawDataMode) ProcessMs(ts, component, iMS);
162 if (fRawDataMode) DebugMs(ts, component, iMS);
163 }
164
165 FinalizeTs();
166
167 if (0 == fTsCounter % 1000) { LOG(info) << "Processed " << fTsCounter << " TS"; }
168
169 fTsCounter++;
170
172 std::sort(fDigiVect.begin(), fDigiVect.end(),
173 [](const CbmRichDigi& a, const CbmRichDigi& b) -> bool { return a.GetTime() < b.GetTime(); });
174
175 return kTRUE;
176}
177
178
180{
181 std::stringstream stream;
182 stream << "[" << fTsCounter << "-" << fMsInd << "-" << reader.GetWordCounter() << "/" << reader.GetSize() / 4 << " "
183 << reader.GetWordAsHexString(reader.GetCurWord()) << "] ";
184 return stream.str();
185}
186
188{
189 //if (fTsCounter == 25215) return true;
190 return false;
191}
192
193Bool_t CbmMcbm2018UnpackerAlgoRich::ProcessMs(const fles::Timeslice& ts, size_t uMsCompIdx, size_t uMsIdx)
194{
195 const fles::MicrosliceView mv = ts.get_microslice(uMsCompIdx, uMsIdx);
196 const fles::MicrosliceDescriptor& msDesc = mv.desc();
197
199 reader.SetData(mv.content(), msDesc.size);
200
201 // There are a lot of MS with 8 bytes size
202 // Does one need these MS?
203 if (reader.GetSize() <= 8) return true;
204
205 while (true) {
206 ProcessTrbPacket(reader);
207 // -4*2 for 2 last words which contain microslice index
208 if (reader.GetOffset() >= reader.GetSize() - 8) break;
209 // -4*3 for 0xffffffff padding and 2 last words which contain microslice index
210 if (reader.IsNextPadding() && reader.GetOffset() >= reader.GetSize() - 12) break;
211 }
212
213 uint32_t msIndexWord1 = reader.NextWord();
214 if (IsLog()) LOG(debug4) << GetLogHeader(reader) << "Microslice Index 1:" << reader.GetWordAsHexString(msIndexWord1);
215
216 uint32_t msIndexWord2 = reader.NextWord();
217 if (IsLog()) LOG(debug4) << GetLogHeader(reader) << "Microslice Index 2:" << reader.GetWordAsHexString(msIndexWord2);
218
219 return kTRUE;
220}
221
223{
224 ProcessMbs(reader, false); // Current MBS
225 ProcessMbs(reader, true); // Previous MBS
226
227 uint32_t trbNum = reader.NextWord(); // TRB trigger number
228 if (IsLog()) LOG(debug4) << GetLogHeader(reader) << "TRB Num:" << reader.GetWordAsHexString(trbNum);
229
230 ProcessHubBlock(reader);
231}
232
234{
235 uint32_t word = reader.NextWord();
236 uint32_t mbsNum = word & 0xffffff; //24 bits
237 uint32_t nofCtsCh = (word >> 24) & 0xff; // 8 bits
238 if (IsLog())
239 LOG(debug4) << GetLogHeader(reader) << "MBS mbsNum:0x" << std::hex << mbsNum << std::dec
240 << " nofCtsCh:" << nofCtsCh;
241
242 for (uint32_t i = 0; i < nofCtsCh; i++) {
243 uint32_t wordEpoch = reader.NextWord();
244 uint32_t epoch = CbmMcbm2018RichTdcWordReader::ProcessEpoch(wordEpoch);
245 if (IsLog()) LOG(debug4) << GetLogHeader(reader) << "MBS ch:" << i << " epoch:" << epoch;
246
247 uint32_t wordTime = reader.NextWord();
250 if (IsLog()) LOG(debug4) << GetLogHeader(reader) << "MBS ch:" << i << " " << td.ToString();
251
252 double fullTime = CalculateTime(epoch, td.fCoarse, td.fFine);
253
254 if (isPrev && td.fChannel == 0) fMbsPrevTimeCh0 = fullTime;
255 if (isPrev && td.fChannel == 1) fMbsPrevTimeCh1 = fullTime;
256 }
257
258 double mbsCorr = fMbsPrevTimeCh1 - fMbsPrevTimeCh0;
259 if (IsLog())
260 LOG(debug4) << GetLogHeader(reader) << "MBS Prev ch1:" << std::setprecision(15) << fMbsPrevTimeCh1
261 << " ch0:" << fMbsPrevTimeCh0 << " corr:" << mbsCorr;
262}
263
265{
266 uint32_t word = reader.NextWord();
267 uint32_t hubId = word & 0xffff; // 16 bits
268 uint32_t hubSize = (word >> 16) & 0xffff; // 16 bits
269 if (IsLog())
270 LOG(debug4) << GetLogHeader(reader) << "hubId:0x" << std::hex << hubId << std::dec << " hubSize:" << hubSize;
271
272 //if ((HubId == 0xc001) || (HubId == 0xc000)) //CTS subevent?
273 //if (HubId == 0x5555)
274 //if (((HubId >> 8) & 0xff) == 0x82) // TRB subevent? // TODO: check if it starts from 0x82
275
276 // if true then it is CTS sub-sub-event
277 bool isLast = false;
278 size_t counter = 0;
279 size_t totalSize = 0;
280 while (!isLast) {
281 word = reader.NextWord();
282 uint32_t subSubEventId = word & 0xffff; // 16 bits
283 uint32_t subSubEventSize = (word >> 16) & 0xffff; // 16 bits
284 isLast = reader.IsLastSubSubEvent(subSubEventSize); // if true then it is CTS sub-sub-event
285 counter++;
286 totalSize += (1 + subSubEventSize);
287
288 if (IsLog())
289 LOG(debug4) << GetLogHeader(reader) << counter << ((isLast) ? " CTS" : " DiRICH") << " subSubEventId:0x"
290 << std::hex << subSubEventId << std::dec << " subSubEventSize:" << subSubEventSize;
291
292 if (!isLast) { // DiRICH event
293 // check correctness of subsub event, for safety reasons
294 if (((subSubEventId >> 12) & 0xF) != 0x7) {
295 LOG(error) << GetLogHeader(reader) << "ERROR: subSubEventId has strange value:0x" << std::hex << subSubEventId
296 << std::dec;
297 }
298 ProcessSubSubEvent(reader, subSubEventSize, subSubEventId);
299 }
300 else { // CTS event
301 ProcessCtsSubSubEvent(reader, subSubEventSize, subSubEventId);
302 }
303
304 if (fbDebugMonitorMode) {
305 //This address calculation is just for mCBM; will be a problem when using full CBM RICH acceptance
306 uint16_t histAddr = ((subSubEventId >> 8) & 0xF) * 18 + ((subSubEventId >> 4) & 0xF) * 2 + (subSubEventId & 0xF);
307 fhSubSubEventSize->Fill(histAddr, subSubEventSize); // Words in a DiRICH
308 }
309
310 if ((totalSize == hubSize && !isLast) || (totalSize != hubSize && isLast)) {
311 if (IsLog()) LOG(error) << "ERROR: totalSize OR isLast is wrong";
312 }
313
314 if (totalSize >= hubSize || isLast) break;
315 }
316
317 // read last words
318 int lastWordsCounter = 0;
319 while (true) {
320 lastWordsCounter++;
321 word = reader.NextWord();
322 if (IsLog()) LOG(debug4) << GetLogHeader(reader);
323 if (word == 0x600dda7a) break;
324 if (lastWordsCounter >= 7) {
325 LOG(error) << GetLogHeader(reader)
326 << "CbmMcbm2018UnpackerAlgoRich::ProcessHubBlock() ERROR: No word == 0x600dda7a";
327 }
328 }
329}
330
332 uint32_t subSubEventSize, uint32_t subSubEventId)
333{
334 uint32_t word = reader.NextWord();
335 uint32_t ctsState = word & 0xffff; // 16 bits
336 uint32_t nofInputs = (word >> 16) & 0xf; // 4 bits
337 uint32_t nofTrigCh = (word >> 20) & 0x1f; // 5 bits
338 uint32_t inclLastIdle = (word >> 25) & 0x1; // 1 bit
339 uint32_t inclTrigInfo = (word >> 26) & 0x1; // 1 bit
340 uint32_t inclTime = (word >> 27) & 0x1; // 1 bit
341 uint32_t ETM = (word >> 28) & 0x3; // 2 bits
342 uint32_t ctsInfoSize = 2 * nofInputs + 2 * nofTrigCh + 2 * inclLastIdle + 3 * inclTrigInfo + inclTime; // in words
343 switch (ETM) {
344 case 0: break;
345 case 1: ctsInfoSize += 1; break;
346 case 2: ctsInfoSize += 4; break;
347 case 3: break;
348 }
349 if (IsLog()) LOG(debug4) << GetLogHeader(reader) << "CTS ctsState:" << ctsState << " ctsInfoSize:" << ctsInfoSize;
350 for (uint32_t i = 0; i < ctsInfoSize; i++) {
351 word = reader.NextWord(); // do nothing?
352 if (IsLog()) LOG(debug4) << GetLogHeader(reader) << "CTS info words";
353 }
354 int nofTimeWords = subSubEventSize - ctsInfoSize - 1;
355 ProcessSubSubEvent(reader, nofTimeWords, subSubEventId);
356}
357
359 uint32_t subSubEventId)
360{
361 // Store if a certain TDC word type was analysed,
362 // later one can check if the order is correct
363 bool wasHeader = false;
364 bool wasEpoch = false;
365 bool wasTime = false;
366 bool wasTrailer = false;
367 uint32_t epoch = 0; // store last epoch obtained in sub-sub-event
368 bool errorInData = false;
369
370 // Store last raising edge time for each channel or -1. if no time
371 // this array is used to match raising and falling edges
372 std::vector<double> raisingTime(33, -1.);
373
374 for (int i = 0; i < nofTimeWords; i++) {
375 uint32_t word = reader.NextWord();
377
379 if (!wasHeader || !wasEpoch || wasTrailer) {
380 LOG(error) << GetLogHeader(reader) << "illegal position of TDC Time (before header/epoch or after trailer)";
381 errorInData = true;
382 continue;
383 }
384 wasTime = true;
385 ProcessTimeDataWord(reader, i, epoch, word, subSubEventId, raisingTime);
386 }
387 else if (type == CbmMcbm2018RichTdcWordType::Epoch) {
388 if (!wasHeader || wasTrailer) {
389 LOG(error) << GetLogHeader(reader) << "illegal position of TDC Epoch (before header or after trailer)";
390 errorInData = true;
391 continue;
392 }
393 wasEpoch = true;
395 if (IsLog()) LOG(debug4) << GetLogHeader(reader) << "SubSubEv[" << i << "] epoch:" << epoch;
396 }
397 else if (type == CbmMcbm2018RichTdcWordType::Header) {
398 if (wasEpoch || wasTime || wasTrailer) {
399 LOG(error) << GetLogHeader(reader) << "illegal position of TDC Header (after time/epoch/trailer)";
400 errorInData = true;
401 continue;
402 }
403 wasHeader = true;
404 uint16_t errorBits = CbmMcbm2018RichTdcWordReader::ProcessHeader(word);
405 ErrorMsg(errorBits, CbmMcbm2018RichErrorType::tdcHeader, subSubEventId);
406 if (IsLog()) LOG(debug4) << GetLogHeader(reader) << "SubSubEv[" << i << "] header";
407 }
408 else if (type == CbmMcbm2018RichTdcWordType::Trailer) {
409 if (!wasEpoch || !wasTime || !wasHeader) {
410 LOG(error) << GetLogHeader(reader) << "illegal position of TDC Trailer (before time/epoch/header)";
411 errorInData = true;
412 continue;
413 }
414 wasTrailer = true;
415 uint16_t errorBits = CbmMcbm2018RichTdcWordReader::ProcessTrailer(word);
416 ErrorMsg(errorBits, CbmMcbm2018RichErrorType::tdcTrailer, subSubEventId);
417 if (IsLog()) LOG(debug4) << GetLogHeader(reader) << "SubSubEv[" << i << "] trailer";
418 }
419 else if (type == CbmMcbm2018RichTdcWordType::Debug) {
420 // for the moment do nothing
421 }
422 else if (type == CbmMcbm2018RichTdcWordType::Error) {
423 LOG(error) << GetLogHeader(reader) << "Wrong TDC word!!! marker:" << ((word >> 29) & 0x7);
424 errorInData = true;
425 }
426 }
427
428 if (errorInData) {
429 //TODO:
430 }
431}
432
433double CbmMcbm2018UnpackerAlgoRich::CalculateTime(uint32_t epoch, uint32_t coarse, uint32_t fine)
434{
435 return ((double) epoch) * 2048. * 5. + ((double) coarse) * 5. - ((double) fine) * 0.005;
436}
437
439 uint32_t tdcWord, uint32_t subSubEventId,
440 std::vector<double>& raisingTime)
441{
444 double fullTime = CalculateTime(epoch, td.fCoarse, td.fFine);
445 // TODO: I do not use unpacker parameters, I use std::map to store full time
446 // int idx = fUnpackPar->GetAddressIdx(subSubEventId);
447 // if (idx == -1) {
448 // LOG(error) << "ERROR: No AddressIdx found for subSubEventId:0x" << std::hex << subSubEventId << std::dec;
449 // return;
450 // }
451
452 if (td.fChannel == 0) {
453 if (td.IsRisingEdge()) {
454 fPrevLastCh0ReTime[subSubEventId] = fLastCh0ReTime[subSubEventId];
455 fLastCh0ReTime[subSubEventId] = fullTime;
456 if (IsLog())
457 LOG(debug4) << GetLogHeader(reader) << "SubSubEv[" << iTdc << "] " << td.ToString()
458 << " CH0 Last:" << std::setprecision(15) << fLastCh0ReTime[subSubEventId]
459 << " PrevLast:" << fPrevLastCh0ReTime[subSubEventId]
460 << " diff:" << fLastCh0ReTime[subSubEventId] - fPrevLastCh0ReTime[subSubEventId];
461 }
462 }
463 else {
464 double dT = fullTime - fPrevLastCh0ReTime[subSubEventId];
465 double mbsCorr = fMbsPrevTimeCh1 - fMbsPrevTimeCh0;
466 double fullTimeCorr = dT - mbsCorr;
467 if (IsLog())
468 LOG(debug4) << GetLogHeader(reader) << "SubSubEv[" << iTdc << "] " << td.ToString()
469 << " time:" << std::setprecision(15) << fullTime << " fullTimeCorr:" << fullTimeCorr;
470
471 if (td.fChannel < 1 || td.fChannel >= raisingTime.size()) {
472 LOG(error) << "ERROR: channel number is out of limit. Channel:" << td.fChannel;
473 }
474
475 if (td.IsRisingEdge()) {
476 // always store the latest raising edge. It means that in case RRFF situation only middle RF will be matched.
477 raisingTime[td.fChannel] = fullTimeCorr;
478 }
479 else {
480 if (raisingTime[td.fChannel] == -1.) {
481 //No raising channel was found before. Skip this falling edge time.
482 if (IsLog())
483 LOG(debug4) << GetLogHeader(reader) << "SubSubEv[" << iTdc << "] "
484 << "No raising channel was found before. Skip this falling edge time.";
485 }
486 else {
487 // Matching was found, calculate ToT, if tot is in a good range -> create digi
488 double ToT = fullTimeCorr - raisingTime[td.fChannel];
489 if (IsLog())
490 LOG(debug4) << GetLogHeader(reader) << "SubSubEv[" << iTdc << "] "
491 << "ToT:" << ToT;
492 if (ToT >= fToTMin && ToT <= fToTMax) {
493 if (fbMonitorMode) {
494 TH1D* h = GetTotH1(subSubEventId, td.fChannel);
495 if (h != nullptr) h->Fill(ToT);
496
497 TH2D* h2 = GetTotH2(subSubEventId);
498 if (h2 != nullptr) h2->Fill(td.fChannel, ToT);
499 }
500 WriteOutputDigi(subSubEventId, td.fChannel, raisingTime[td.fChannel], ToT, fCurMSidx);
501 }
502 // pair was created, set raising edge to -1.
503 raisingTime[td.fChannel] = -1.;
504 }
505 }
506 }
507}
508
509void CbmMcbm2018UnpackerAlgoRich::WriteOutputDigi(Int_t fpgaID, Int_t channel, Double_t time, Double_t tot,
510 uint64_t MSidx)
511{
512 Double_t ToTcorr = fbDoToTCorr ? fUnpackPar->GetToTshift(fpgaID, channel) : 0.;
513 Int_t pixelUID = this->GetPixelUID(fpgaID, channel);
514 //check ordering
515 uint64_t msRefTS = 0;
516 if (MSidx >= fdTsStartTime) { msRefTS = MSidx - fdTsStartTime; }
517 else {
518 std::cout << "MS before TS Start: " << MSidx << " " << fdTsStartTime << std::endl;
519 }
520
521 Double_t finalTime = time + (Double_t) msRefTS - fdTimeOffsetNs;
522 // Double_t finalTime = time + (Double_t) MSidx - fdTimeOffsetNs;
523
524 if (msRefTS == 0) return; // Problems in data in current version. time is too large
525
526 Double_t lastTime = 0.;
527
528 if (fDigiVect.size() < 1) { fDigiVect.emplace_back(pixelUID, finalTime, tot - ToTcorr); }
529 else {
530 lastTime = fDigiVect[fDigiVect.size() - 1].GetTime();
531 if (fDigiVect[0].GetTime() > finalTime) {
532 fDigiVect.emplace(fDigiVect.begin(), pixelUID, finalTime, tot - ToTcorr);
533 }
534 else if (lastTime > finalTime) {
535 for (int i = fDigiVect.size() - 1; i >= 0; i--) {
536 lastTime = fDigiVect[i].GetTime();
537 if (lastTime <= finalTime) {
538 fDigiVect.emplace(fDigiVect.begin() + i + 1, pixelUID, finalTime, tot - ToTcorr);
539 break;
540 }
541 }
542 }
543 else {
544 fDigiVect.emplace_back(pixelUID, finalTime, tot - ToTcorr);
545 }
546 }
547 // LOG(debug4) << "CbmMcbm2018UnpackerAlgoRich::WriteOutputDigi fDigiVect.size=" << fDigiVect.size();
548}
549
551
553{
554 int nofTdc = fUnpackPar->GetNaddresses();
555
556 std::vector<std::string> tdcErrorLabels = {"RingBuffOverw.", "noRefTime", "refTimePrecedes",
557 "trigW/oRefTime", "markMisRefTime", "multiRefTime",
558 "refTime<40ns", "noValidation", "trigger!=0x1"};
559 fhTdcErrors = new TH2D("fhTdcErrors", "Errors in TDC msgs;;", nofTdc, -0.5, nofTdc - 0.5, tdcErrorLabels.size(), -0.5,
560 (double) tdcErrorLabels.size() - 0.5);
561 for (size_t i = 0; i < tdcErrorLabels.size(); i++) {
562 fhTdcErrors->GetYaxis()->SetBinLabel(i + 1, tdcErrorLabels[i].c_str());
563 }
564 fhTdcErrors->GetXaxis()->LabelsOption("v");
565 fhTdcErrors->GetYaxis()->SetTickSize(0.0);
566 fhTdcErrors->GetXaxis()->SetTickSize(0.0);
567
568 for (Int_t iTdc = 0; iTdc < nofTdc; iTdc++) {
569 Int_t tdcId = fUnpackPar->GetAddress(iTdc);
570 fMapFEE[tdcId] = iTdc;
571 fhTdcErrors->GetXaxis()->SetBinLabel(iTdc + 1, Form("0x%4x", tdcId));
572
573 // init ToT histogramms
574 for (Int_t iCh = 0; iCh <= 32; iCh++) {
575 GetTotH1(tdcId, iCh);
576 }
577 GetTotH2(tdcId);
578
579 {
580 std::stringstream cName, cTitle;
581 int tdc = fUnpackPar->GetAddress(iTdc);
582 cName << "cToT2d_TDC_0x" << std::hex << tdc;
583 cTitle << "ToTs of TDC 0x" << std::hex << tdc;
584 TCanvas* c = new TCanvas(cName.str().c_str(), cTitle.str().c_str(), 10, 10);
585 TH2D* h2 = GetTotH2(tdc);
586 h2->Draw("colz");
587 fcTot2d.push_back(c);
588 AddCanvasToVector(c, "ToT_Canvases");
589 }
590 }
591
593
594 if (fbDebugMonitorMode) {
595 fhEventSize = new TH1I("fhEventSize", "Size of the Event from TrbNet; Size [bytes]", 350, 0., 70000.);
597
599 new TH2I("fhSubEventSize", "fhSubEventSize; HubId ; Size [bytes]; Entries", 6, 0, 6, 10000, 0., 10000.);
601
603 new TH2I("fhSubSubEventSize", "fhSubSubEventSize; DiRICH ; Size [words]; Entries", 72, 0, 72, 510, 0., 510.);
605
606 fhChnlSize = new TH2I("fhChnlSize", "fhChnlSize; channel; Size [words]; Entries", 33, 0, 33, 25, 0, 25.);
608 }
609
610 return kTRUE;
611}
612
613TH1D* CbmMcbm2018UnpackerAlgoRich::GetTotH1(uint32_t tdc, uint32_t channel)
614{
615 TH1D* h = fhTotMap[tdc][channel];
616 if (h == nullptr) {
617 std::stringstream name, subFolder;
618 name << "ToT_tdc0x" << std::hex << tdc << std::dec << "_ch" << channel;
619 std::string title = name.str() + ";ToT [ns];Entries";
620 subFolder << "ToT/tdc0x" << std::hex << tdc;
621 h = new TH1D(name.str().c_str(), title.c_str(), 100, -1., 49.);
622 AddHistoToVector(h, subFolder.str());
623 fhTotMap[tdc][channel] = h;
624 }
625 return h;
626}
627
629{
630 TH2D* h = fhTot2dMap[tdc];
631 if (h == nullptr) {
632 std::stringstream name;
633 name << "ToT_2d_tdc0x" << std::hex << tdc;
634 std::string title = name.str() + ";channels;ToT [ns]";
635 std::string subFolder = "ToT2d";
636 h = new TH2D(name.str().c_str(), title.c_str(), 33, 0, 32, 200, -1., 49.);
637 AddHistoToVector(h, subFolder);
638 fhTot2dMap[tdc] = h;
639 }
640 return h;
641}
642
643Bool_t CbmMcbm2018UnpackerAlgoRich::DebugMs(const fles::Timeslice& ts, size_t uMsCompIdx, size_t uMsIdx)
644{
645 const fles::MicrosliceView mv = ts.get_microslice(uMsCompIdx, uMsIdx);
646 const fles::MicrosliceDescriptor& msDesc = mv.desc();
647 const uint8_t* ptr = mv.content();
648 const size_t size = msDesc.size;
649
650 if (size == 0) return kTRUE;
651 Debug(ptr, size);
652
653 return kTRUE;
654}
655
656Int_t CbmMcbm2018UnpackerAlgoRich::Debug(const uint8_t* /*ptr*/, const size_t /*size*/) { return 0; }
657
658
659void CbmMcbm2018UnpackerAlgoRich::ErrorMsg(uint16_t errbits, CbmMcbm2018RichErrorType type, uint16_t tdcId)
660{
661 if (!fbMonitorMode) return;
662
664 // Errors description in TRB manual section 11.3.2. TDC HEADER
665 // Bit 0: min. 1 rinĒµ buffer overwritten
666 int nofHeaderErrorBits = 1;
667 int histBinOffsetHeaderError = 0;
668 for (int i = 0; i < nofHeaderErrorBits; i++) {
669 if (((errbits >> i) & 0x1) == 1) fhTdcErrors->Fill(fMapFEE[tdcId], i + histBinOffsetHeaderError);
670 }
671 }
672 else if (type == CbmMcbm2018RichErrorType::tdcTrailer) {
673 // Errors description in TRB manual section 11.3.5. TDC TRAILER
674 // Bit 0: no reference time in trigger handler in TDC
675 // Bit 1: reference time precedes a non-timing trigger
676 // Bit 2: timing trigger is delivered without a reference time
677 // Bit 3: Set with the bit 2 to mark the missing reference time
678 // Bit 4: there are more than one detected reference time
679 // Bit 5: reference time was too short (<40 ns)
680 // Bit 6: no trigger validation arrives from the endpoint after a valid reference time
681 // Bit 7: any timing trigger type except 0x1 is send
682 int nofTrailerErrorBits = 8;
683 int histBinOffsetTrailerError = 1;
684 for (int i = 0; i < nofTrailerErrorBits; i++) {
685 if (((errbits >> i) & 0x1) == 1) fhTdcErrors->Fill(fMapFEE[tdcId], i + histBinOffsetTrailerError);
686 }
687 }
688 else if (type == CbmMcbm2018RichErrorType::ctsHeader) {
689 // To be implemented
690 }
691 else if (type == CbmMcbm2018RichErrorType::ctsTrailer) {
692 // To be implemented
693 }
694 else {
695 }
696}
697
699
ClassImp(CbmConverterManager)
static constexpr size_t size()
Definition KfSimdPseudo.h:2
bool IsLastSubSubEvent(uint32_t subSubEventSize)
std::string GetWordAsHexString(uint32_t word)
void SetData(const uint8_t *data, size_t size)
Int_t GetNaddresses(void) const
Double_t GetToTshift(Int_t tdc, Int_t ch) const
Int_t GetAddress(Int_t ind) const
static uint16_t ProcessHeader(uint32_t tdcWord)
static CbmMcbm2018RichTdcWordType GetTdcWordType(uint32_t tdcWord)
static uint32_t ProcessEpoch(uint32_t tdcWord)
static void ProcessTimeData(uint32_t tdcWord, CbmMcbm2018RichTdcTimeData &outData)
static uint16_t ProcessTrailer(uint32_t tdcWord)
TH1D * GetTotH1(uint32_t fpgaID, uint32_t channel)
std::map< uint16_t, uint16_t > fMapFEE
std::string GetLogHeader(CbmMcbm2018RichMicrosliceReader &reader)
void AddMsComponentToList(size_t component, UShort_t usDetectorId)
void ProcessMbs(CbmMcbm2018RichMicrosliceReader &reader, bool isPrev)
Bool_t DebugMs(const fles::Timeslice &ts, size_t uMsCompIdx, size_t uMsIdx)
std::map< uint32_t, double > fPrevLastCh0ReTime
std::map< uint32_t, std::map< Int_t, TH1D * > > fhTotMap
std::map< uint32_t, TH2D * > fhTot2dMap
void ProcessTrbPacket(CbmMcbm2018RichMicrosliceReader &reader)
void WriteOutputDigi(Int_t fpgaID, Int_t channel, Double_t time, Double_t tot, uint64_t MSidx)
double CalculateTime(uint32_t epoch, uint32_t coarse, uint32_t fine)
void ErrorMsg(uint16_t errbits, CbmMcbm2018RichErrorType type, uint16_t tdcId=0)
virtual Bool_t ProcessMs(const fles::Timeslice &ts, size_t uMsCompIdx, size_t uMsIdx)
void ProcessHubBlock(CbmMcbm2018RichMicrosliceReader &reader)
std::map< uint32_t, double > fLastCh0ReTime
void ProcessTimeDataWord(CbmMcbm2018RichMicrosliceReader &reader, int iTdc, uint32_t epoch, uint32_t tdcWord, uint32_t subSubEventId, std::vector< double > &raisingTime)
virtual Bool_t ProcessTs(const fles::Timeslice &ts)
void ProcessCtsSubSubEvent(CbmMcbm2018RichMicrosliceReader &reader, uint32_t subSubEventSize, uint32_t subSubEventId)
Int_t Debug(const uint8_t *ptr, const size_t size)
Int_t GetPixelUID(Int_t fpgaID, Int_t ch) const
void ProcessSubSubEvent(CbmMcbm2018RichMicrosliceReader &reader, int nofTimeWords, uint32_t subSubEventId)
void AddHistoToVector(TNamed *pointer, std::string sFolder="")
std::vector< size_t > fvMsComponentsList
void AddCanvasToVector(TCanvas *pointer, std::string sFolder="")
std::vector< CbmRichDigi > fDigiVect
Data class with information on a STS local track.