CbmRoot
Loading...
Searching...
No Matches
CbmMcbm2018UnpackerAlgoMuch.cxx
Go to the documentation of this file.
1/* Copyright (C) 2019-2020 Facility for Antiproton and Ion Research in Europe, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Pierre-Alain Loizeau [committer] */
4
5// -----------------------------------------------------------------------------
6// ----- -----
7// ----- CbmMcbm2018UnpackerAlgoMuch -----
8// ----- Created 02.02.2019 by P.-A. Loizeau -----
9// ----- -----
10// -----------------------------------------------------------------------------
11
13
15#include "CbmMcbm2018MuchPar.h"
16
17#include <Logger.h>
18
19#include "TCanvas.h"
20#include "TH1.h"
21#include "TH2.h"
22#include "TList.h"
23#include "TProfile.h"
24#include "TROOT.h"
25#include "TString.h"
26
27#include <fstream>
28#include <iomanip>
29#include <iostream>
30
31#include <stdint.h>
32
33// -------------------------------------------------------------------------
36 ,
38 fbMonitorMode(kFALSE)
39 , fbDebugMonitorMode(kFALSE)
40 , fvbMaskedComponents()
41 , fiFlag(0)
42 , fUnpackPar(nullptr)
43 , fuNrOfDpbs(0)
44 , fDpbIdIndexMap()
45 , fvbCrobActiveFlag()
46 , fuNbFebs(0)
47 ,
48 //fviFebAddress(),
49 fuNbStsXyters(0)
50 , fdTimeOffsetNs(0.0)
51 , fvdTimeOffsetNsAsics()
52 , fbUseChannelMask(kFALSE)
53 , fvvbMaskedChannels()
54 , fdAdcCut(0)
55 , fulCurrentTsIdx(0)
56 , fulCurrentMsIdx(0)
57 , fdTsStartTime(-1.0)
58 , fdTsStopTimeCore(-1.0)
59 , fdMsTime(-1.0)
60 , fuMsIndex(0)
61 , fmMsgCounter()
62 , fuCurrentEquipmentId(0)
63 , fuCurrDpbId(0)
64 , fuCurrDpbIdx(0)
65 , fiRunStartDateTimeSec(-1)
66 , fiBinSizeDatePlots(-1)
67 , fvulCurrentTsMsb()
68 , fvuCurrentTsMsbCycle()
69 , fdStartTime(0.0)
70 , fdStartTimeMsSz(0.0)
71 , ftStartTimeUnix(std::chrono::steady_clock::now())
72 , fvmHitsInMs()
73 , fvvusLastTsChan()
74 , fvvusLastAdcChan()
75 , fvvusLastTsMsbChan()
76 , fvvusLastTsMsbCycleChan()
77 , fhDigisTimeInRun(nullptr)
78/*
79 fvhHitsTimeToTriggerRaw(),
80 fvhMessDistributionInMs(),
81 fhEventNbPerTs( nullptr ),
82 fcTimeToTrigRaw( nullptr )
83*/
84{
85}
87{
89 fvmHitsInMs.clear();
90 /*
91 for( UInt_t uDpb = 0; uDpb < fuNrOfDpbs; ++uDpb )
92 {
93 fvmHitsInMs[ uDpb ].clear();
94 } // for( UInt_t uDpb = 0; uDpb < fuNrOfDpbs; ++uDpb )
95*/
96
97 if (nullptr != fParCList) delete fParCList;
98 if (nullptr != fUnpackPar) delete fUnpackPar;
99}
100
101// -------------------------------------------------------------------------
103{
104 LOG(info) << "Initializing mCBM MUCH 2019 unpacker algo";
105
106 return kTRUE;
107}
115
116// -------------------------------------------------------------------------
118{
119 LOG(info) << "Init parameter containers for CbmMcbm2018UnpackerAlgoMuch";
120 Bool_t initOK = ReInitContainers();
121
122 return initOK;
123}
125{
126 LOG(info) << "**********************************************";
127 LOG(info) << "ReInit parameter containers for CbmMcbm2018UnpackerAlgoMuch";
128
129 fUnpackPar = (CbmMcbm2018MuchPar*) fParCList->FindObject("CbmMcbm2018MuchPar");
130 if (nullptr == fUnpackPar) return kFALSE;
131
132 Bool_t initOK = InitParameters();
133
134 return initOK;
135}
137{
138 if (nullptr == fParCList) fParCList = new TList();
139 fUnpackPar = new CbmMcbm2018MuchPar("CbmMcbm2018MuchPar");
140 fParCList->Add(fUnpackPar);
141
142 return fParCList;
143}
145{
147 LOG(info) << "Nr. of MUCH DPBs: " << fuNrOfDpbs;
148
149 fDpbIdIndexMap.clear();
150 for (UInt_t uDpb = 0; uDpb < fuNrOfDpbs; ++uDpb) {
151 fDpbIdIndexMap[fUnpackPar->GetDpbId(uDpb)] = uDpb;
152 LOG(info) << "Eq. ID for DPB #" << std::setw(2) << uDpb << " = 0x" << std::setw(4) << std::hex
153 << fUnpackPar->GetDpbId(uDpb) << std::dec << " => " << fDpbIdIndexMap[fUnpackPar->GetDpbId(uDpb)];
154 } // for( UInt_t uDpb = 0; uDpb < fuNrOfDpbs; ++uDpb )
155
157 LOG(info) << "Nr. of FEBs: " << fuNbFebs;
158
160 LOG(info) << "Nr. of StsXyter ASICs: " << fuNbStsXyters;
161
162 if (fvdTimeOffsetNsAsics.size() < fuNbStsXyters) {
164 } // if( fvdTimeOffsetNsAsics.size() < fuNbStsXyters )
165
167 for (UInt_t uDpb = 0; uDpb < fuNrOfDpbs; ++uDpb) {
169 for (UInt_t uCrobIdx = 0; uCrobIdx < fUnpackPar->GetNbCrobsPerDpb(); ++uCrobIdx) {
170 fvbCrobActiveFlag[uDpb][uCrobIdx] = fUnpackPar->IsCrobActive(uDpb, uCrobIdx);
171 } // for( UInt_t uCrobIdx = 0; uCrobIdx < fUnpackPar->GetNbCrobsPerDpb(); ++uCrobIdx )
172 } // for( UInt_t uDpb = 0; uDpb < fuNrOfDpbs; ++uDpb )
173
174 for (UInt_t uDpb = 0; uDpb < fuNrOfDpbs; ++uDpb) {
175 TString sPrintoutLine = Form("DPB #%02u CROB Active ?: ", uDpb);
176 for (UInt_t uCrobIdx = 0; uCrobIdx < fUnpackPar->GetNbCrobsPerDpb(); ++uCrobIdx) {
177 sPrintoutLine += Form("%1u", (fvbCrobActiveFlag[uDpb][uCrobIdx] == kTRUE));
178 } // for( UInt_t uCrobIdx = 0; uCrobIdx < fUnpackPar->GetNbCrobsPerDpb(); ++uCrobIdx )
179 LOG(info) << sPrintoutLine;
180 } // for( UInt_t uDpb = 0; uDpb < fuNrOfDpbs; ++uDpb )
181 /*
182 for( UInt_t uDpb = 0; uDpb < fuNrOfDpbs; ++uDpb )
183 {
184 for( UInt_t uCrobIdx = 0; uCrobIdx < fUnpackPar->GetNbCrobsPerDpb(); ++uCrobIdx )
185 {
186 LOG(info) << Form( "DPB #%02u CROB #%u: ", uDpb, uCrobIdx);
187 for( UInt_t uFebIdx = 0; uFebIdx < fUnpackPar->GetNbFebsPerCrob(); ++ uFebIdx )
188 if( 0 <= fviFebModuleIdx[ uDpb ][ uCrobIdx ][ uFebIdx ] )
189 {
190 LOG(info) << Form( " FEB #%02u: Mod. Idx = %03d Side %c (%2d) Type %c (%2d) ADC gain %4.0f e- ADC Offs %5.0f e-",
191 uFebIdx,
192 fviFebModuleIdx[ uDpb ][ uCrobIdx ][ uFebIdx ],
193 1 == fviFebModuleSide[ uDpb ][ uCrobIdx ][ uFebIdx ] ? 'N': 'P',
194 fviFebModuleSide[ uDpb ][ uCrobIdx ][ uFebIdx ],
195 1 == fviFebType[ uDpb ][ uCrobIdx ][ uFebIdx ] ? 'B' : 'A',
196 fviFebType[ uDpb ][ uCrobIdx ][ uFebIdx ],
197 fvdFebAdcGain[ uDpb ][ uCrobIdx ][ uFebIdx ],
198 fvdFebAdcOffs[ uDpb ][ uCrobIdx ][ uFebIdx ]
199 );
200 } // for( UInt_t uFebIdx = 0; uFebIdx < fUnpackPar->GetNbFebsPerCrob(); ++ uFebIdx )
201 } // for( UInt_t uCrobIdx = 0; uCrobIdx < fUnpackPar->GetNbCrobsPerDpb(); ++uCrobIdx )
202 } // for( UInt_t uDpb = 0; uDpb < fuNrOfDpbs; ++uDpb )
203*/
204
205 if (fbBinningFw) LOG(info) << "Unpacking data in bin sorter FW mode";
206 else
207 LOG(info) << "Unpacking data in full time sorter FW mode (legacy)";
208
209 // Internal status initialization
212 for (UInt_t uDpb = 0; uDpb < fuNrOfDpbs; ++uDpb) {
213 fvulCurrentTsMsb[uDpb] = 0;
214 fvuCurrentTsMsbCycle[uDpb] = 0;
215 } // for( UInt_t uDpb = 0; uDpb < fuNrOfDpbs; ++uDpb )
216
221 for (UInt_t uAsicIdx = 0; uAsicIdx < fuNbStsXyters; ++uAsicIdx) {
222 fvvusLastTsChan[uAsicIdx].resize(fUnpackPar->GetNbChanPerAsic(), 0);
223 fvvusLastAdcChan[uAsicIdx].resize(fUnpackPar->GetNbChanPerAsic(), 0);
224 fvvusLastTsMsbChan[uAsicIdx].resize(fUnpackPar->GetNbChanPerAsic(), 0);
226 } // for( UInt_t uAsicIdx = 0; uAsicIdx < fuNbStsXyters; ++ uAsicIdx )
227
228 return kTRUE;
229}
230// -------------------------------------------------------------------------
231
232void CbmMcbm2018UnpackerAlgoMuch::AddMsComponentToList(size_t component, UShort_t usDetectorId)
233{
235 for (UInt_t uCompIdx = 0; uCompIdx < fvMsComponentsList.size(); ++uCompIdx)
236 if (component == fvMsComponentsList[uCompIdx]) return;
237
239 fvMsComponentsList.push_back(component);
240
241 LOG(info) << "CbmMcbm2018UnpackerAlgoMuch::AddMsComponentToList => Component " << component << " with detector ID 0x"
242 << std::hex << usDetectorId << std::dec << " added to list";
243}
244// -------------------------------------------------------------------------
245
246Bool_t CbmMcbm2018UnpackerAlgoMuch::ProcessTs(const fles::Timeslice& ts)
247{
248 fulCurrentTsIdx = ts.index();
249 fdTsStartTime = static_cast<Double_t>(ts.descriptor(0, 0).idx);
250
252 if (0 == fulCurrentTsIdx) { return kTRUE; } // if( 0 == fulCurrentTsIdx )
253
255 if (-1.0 == fdTsCoreSizeInNs) {
256 fuNbCoreMsPerTs = ts.num_core_microslices();
257 fuNbOverMsPerTs = ts.num_microslices(0) - ts.num_core_microslices();
260 LOG(info) << "Timeslice parameters: each TS has " << fuNbCoreMsPerTs << " Core MS and " << fuNbOverMsPerTs
261 << " Overlap MS, for a core duration of " << fdTsCoreSizeInNs << " ns and a full duration of "
262 << fdTsFullSizeInNs << " ns";
263
267 LOG(info) << "In each TS " << fuNbMsLoop << " MS will be looped over";
268 } // if( -1.0 == fdTsCoreSizeInNs )
269
272 // LOG(info) << Form( "TS %5d Start %12f Stop %12f", fulCurrentTsIdx, fdTsStartTime, fdTsStopTimeCore );
273
275 for (fuMsIndex = 0; fuMsIndex < fuNbMsLoop; fuMsIndex++) {
277 for (UInt_t uMsCompIdx = 0; uMsCompIdx < fvMsComponentsList.size(); ++uMsCompIdx) {
278 UInt_t uMsComp = fvMsComponentsList[uMsCompIdx];
279
280 if (kFALSE == ProcessMs(ts, uMsComp, fuMsIndex)) {
281 LOG(error) << "Failed to process ts " << fulCurrentTsIdx << " MS " << fuMsIndex << " for component " << uMsComp;
282 return kFALSE;
283 } // if( kFALSE == ProcessMs( ts, uMsCompIdx, fuMsIndex ) )
284 } // for( UInt_t uMsCompIdx = 0; uMsCompIdx < fvMsComponentsList.size(); ++uMsCompIdx )
285
288 // std::sort( fvmHitsInMs.begin(), fvmHitsInMs.end() );
289
291 for (auto itHitIn = fvmHitsInMs.begin(); itHitIn < fvmHitsInMs.end(); ++itHitIn) {
293
294 CbmMuchBeamTimeDigi* digi = CreateMuchDigi(&(*itHitIn));
295 if (digi == NULL) continue;
296 fDigiVect.push_back(*digi);
297 delete digi;
298 } // for( auto itHitIn = fvmHitsInMs.begin(); itHitIn < fvmHitsInMs.end(); ++itHitIn )
299
301 fvmHitsInMs.clear();
302 } // for( fuMsIndex = 0; fuMsIndex < uNbMsLoop; fuMsIndex ++ )
303
305 fvmHitsInMs.clear();
306 /*
307 for( UInt_t uDpb = 0; uDpb < fuNrOfDpbs; ++uDpb )
308 {
309 fvmHitsInMs[ uDpb ].clear();
310 } // for( UInt_t uDpb = 0; uDpb < fuNrOfDpbs; ++uDpb )
311*/
312
314 std::sort(fDigiVect.begin(), fDigiVect.end(), [](const CbmMuchBeamTimeDigi& a, const CbmMuchBeamTimeDigi& b) -> bool {
315 return a.GetTime() < b.GetTime();
316 });
317
319 if (fbMonitorMode) {
320 if (kFALSE == FillHistograms()) {
321 LOG(error) << "Failed to fill histos in ts " << fulCurrentTsIdx;
322 return kFALSE;
323 } // if( kFALSE == FillHistograms() )
325 fhVectorCapacity->Fill(fulCurrentTsIdx, fDigiVect.capacity());
326 } // if( fbMonitorMode )
327
328 if (fuTsMaxVectorSize < fDigiVect.size()) {
330 fDigiVect.shrink_to_fit();
332 } // if( fuTsMaxVectorSize < fDigiVect.size() )
333
334 return kTRUE;
335}
336
337// -------------------------------------------------------------------------
339{
340 /*
341 UInt_t uFebIdx = itHitIn->GetAsic() / fUnpackPar->GetNbAsicsPerFeb()
342 + ( itHitIn->GetDpb() * fUnpackPar->GetNbCrobsPerDpb() + itHitIn->GetCrob() )
343 * fUnpackPar->GetNbFebsPerCrob();
344 UInt_t uChanInFeb = itHitIn->GetChan()
345 + fUnpackPar->GetNbChanPerAsic() * (itHitIn->GetAsic() % fUnpackPar->GetNbAsicsPerFeb());
346 */
347 UInt_t uAsicIdx = itHitIn->GetAsic();
349 Int_t iFebId = fUnpackPar->GetFebId(itHitIn->GetAsic());
350
351 Short_t station = 0; // for mCBM setup only one station
352 Short_t layer = fUnpackPar->GetModule(itHitIn->GetAsic()); // 0 for Module GEM-A and 1 for Module GEM-B
353 Short_t layerside = 0; // 0 in mCBM
354 Short_t module = 0; // 0 in mCBM
355 Short_t sSector = 0; //channel values are from 0-96 therefore as per CbmMuchAddress it is sector
356 Short_t sChannel = 0; //sector values are from 0-22 therefore as per CbmMuchAddress it is channel
357
358 Int_t usChan = itHitIn->GetChan();
359
360 // ----------------------------- //
361 // Channel flip in stsXYTER v2.1 : 0<->1, 2<->3, 3<->4 and so on...
362 if (fiFlag == 1) {
363 if (usChan % 2 == 0) usChan = usChan + 1;
364 else
365 usChan = usChan - 1;
366 }
367 // ---------------------------- //
368
369 // ---------------------------- //
370 //Due to two FLEX cable connected to single FEB; First Flex Connector number 1 - 63 and second flex connector number 64 - 127
371 //in few FEB positioned these flex connectors are flipped so below correction applied.
372 if (fiFlag == 1 && layer == 0) { // First layer (GEM1) has old readout PCB
373
374 if (iFebId == 0 || iFebId == 1 || iFebId == 2 || iFebId == 3 || iFebId == 4 || iFebId == 8 || iFebId == 9
375 || iFebId == 10 || iFebId == 11 || iFebId == 17) {
376 sSector = fUnpackPar->GetPadXA(iFebId, 127 - usChan);
377 sChannel = fUnpackPar->GetPadYA(iFebId, 127 - usChan);
378 }
379 else {
380 sSector = fUnpackPar->GetPadXA(iFebId, usChan);
381 sChannel = fUnpackPar->GetPadYA(iFebId, usChan);
382 }
383 } // if( fiFlag == 1 && layer == 0 )
384
385 else if (fiFlag == 1 && layer == 1) { // second layer (GEM2) has new readout PCB
386
387 if (iFebId == 0 || iFebId == 1 || iFebId == 2 || iFebId == 3 || iFebId == 4 || iFebId == 8 || iFebId == 9
388 || iFebId == 10 || iFebId == 11 || iFebId == 17) {
389 sSector = fUnpackPar->GetPadXB(iFebId, 127 - usChan);
390 sChannel = fUnpackPar->GetPadYB(iFebId, 127 - usChan);
391 }
392 else {
393 sSector = fUnpackPar->GetPadXB(iFebId, usChan);
394 sChannel = fUnpackPar->GetPadYB(iFebId, usChan);
395 }
396 } // else if( fiFlag == 1 && layer == 1 )
397
398 else { // Both layer with same type of PCB
399 if (iFebId == 0 || iFebId == 1 || iFebId == 2 || iFebId == 3 || iFebId == 4 || iFebId == 8 || iFebId == 9
400 || iFebId == 10 || iFebId == 11 || iFebId == 17) {
401 sSector = fUnpackPar->GetPadXA(iFebId, 127 - usChan);
402 sChannel = fUnpackPar->GetPadYA(iFebId, 127 - usChan);
403 }
404 else {
405 sSector = fUnpackPar->GetPadXA(iFebId, itHitIn->GetChan());
406 sChannel = fUnpackPar->GetPadYA(iFebId, itHitIn->GetChan());
407 }
408 } // else{
409 // ---------------------------- //
410
411 // Checking for the not connected or misconnected pads
412 if (sSector < 0 || sChannel < 0) {
413 LOG(debug) << "Sector " << sSector << " channel " << sChannel
414 << " is not connected or misconnected to pad. Skipping this hit message.";
415 return NULL;
416 }
417 //Creating Unique address of the particular channel of GEM
418 UInt_t address = CbmMuchAddress::GetAddress(station, layer, layerside, module, sChannel, sSector);
419 Double_t dTimeInNs = itHitIn->GetTs() * stsxyter::kdClockCycleNs - fdTimeOffsetNs;
420 if (uAsicIdx < fvdTimeOffsetNsAsics.size()) dTimeInNs -= fvdTimeOffsetNsAsics[uAsicIdx];
421 ULong64_t ulTimeInNs = static_cast<ULong64_t>(dTimeInNs);
422
424 // fDigiVect.push_back( CbmMuchDigi( address, itHitIn->GetAdc(), ulTimeInNs ) );
425
427 CbmMuchBeamTimeDigi* digi = new CbmMuchBeamTimeDigi(address, itHitIn->GetAdc(), ulTimeInNs);
428 LOG(debug) << "Sector " << sSector << " channel " << sChannel << " layer " << layer << " Address " << address
429 << " Time " << ulTimeInNs;
430
431 digi->SetPadX(sSector);
432 digi->SetPadY(sChannel);
433 digi->SetRocId(itHitIn->GetDpb());
434 digi->SetNxId(itHitIn->GetAsic());
435 digi->SetNxCh(itHitIn->GetChan());
436 // Add Elink also in the stsxyter::FinalHit as one more variable such that may be used.
437 //digi.SetElink(itHitIn->GetElink());
438
439 return digi;
440}
441// -------------------------------------------------------------------------
442
443Bool_t CbmMcbm2018UnpackerAlgoMuch::ProcessMs(const fles::Timeslice& ts, size_t uMsCompIdx, size_t uMsIdx)
444{
445 auto msDescriptor = ts.descriptor(uMsCompIdx, uMsIdx);
446 fuCurrentEquipmentId = msDescriptor.eq_id;
447 const uint8_t* msContent = reinterpret_cast<const uint8_t*>(ts.content(uMsCompIdx, uMsIdx));
448
449 uint32_t uSize = msDescriptor.size;
450 fulCurrentMsIdx = msDescriptor.idx;
451 // Double_t dMsTime = (1e-9) * static_cast<double>(fulCurrentMsIdx);
452 LOG(debug) << "Microslice: " << fulCurrentMsIdx << " from EqId " << std::hex << fuCurrentEquipmentId << std::dec
453 << " has size: " << uSize;
454
455 if (0 == fvbMaskedComponents.size()) fvbMaskedComponents.resize(ts.num_components(), kFALSE);
456
457 fuCurrDpbId = static_cast<uint32_t>(fuCurrentEquipmentId & 0xFFFF);
458 // fuCurrDpbIdx = fDpbIdIndexMap[ fuCurrDpbId ];
459
461 auto it = fDpbIdIndexMap.find(fuCurrDpbId);
462 if (it == fDpbIdIndexMap.end()) {
463 if (kFALSE == fvbMaskedComponents[uMsCompIdx]) {
464 LOG(info) << "---------------------------------------------------------------";
465 /*
466 LOG(info) << "hi hv eqid flag si sv idx/start crc size offset";
467 LOG(info) << Form( "%02x %02x %04x %04x %02x %02x %016llx %08x %08x %016llx",
468 static_cast<unsigned int>(msDescriptor.hdr_id),
469 static_cast<unsigned int>(msDescriptor.hdr_ver), msDescriptor.eq_id, msDescriptor.flags,
470 static_cast<unsigned int>(msDescriptor.sys_id),
471 static_cast<unsigned int>(msDescriptor.sys_ver), msDescriptor.idx, msDescriptor.crc,
472 msDescriptor.size, msDescriptor.offset );
473*/
474 LOG(info) << FormatMsHeaderPrintout(msDescriptor);
475 LOG(warning) << "Could not find the sDPB index for AFCK id 0x" << std::hex << fuCurrDpbId << std::dec
476 << " in timeslice " << fulCurrentTsIdx << " in microslice " << uMsIdx << " component " << uMsCompIdx
477 << "\n"
478 << "If valid this index has to be added in the MUCH "
479 "parameter file in the DbpIdArray field";
480 fvbMaskedComponents[uMsCompIdx] = kTRUE;
481
484 if (1 == fulCurrentTsIdx) return kTRUE;
485 } // if( kFALSE == fvbMaskedComponents[ uMsComp ] )
486 else
487 return kTRUE;
488
489 return kFALSE;
490 } // if( it == fDpbIdIndexMap.end() )
491 else
493
495 UInt_t uTsMsbCycleHeader = std::floor(fulCurrentMsIdx / (stsxyter::kulTsCycleNbBins * stsxyter::kdClockCycleNs));
496
498 if (kTRUE == fbBinningFw)
500
501 if (0 == uMsIdx) {
502 if (uTsMsbCycleHeader != fvuCurrentTsMsbCycle[fuCurrDpbIdx])
503 LOG(info) << " TS " << std::setw(12) << fulCurrentTsIdx << " MS " << std::setw(12) << fulCurrentMsIdx
504 << " MS Idx " << std::setw(4) << uMsIdx << " Msg Idx " << std::setw(5) << 0 << " DPB " << std::setw(2)
505 << fuCurrDpbIdx << " Old TsMsb " << std::setw(5) << fvulCurrentTsMsb[fuCurrDpbIdx] << " Old MsbCy "
506 << std::setw(5) << fvuCurrentTsMsbCycle[fuCurrDpbIdx] << " New MsbCy " << uTsMsbCycleHeader;
507 fvuCurrentTsMsbCycle[fuCurrDpbIdx] = uTsMsbCycleHeader;
509 } // if( 0 == uMsIdx )
510 else if (uTsMsbCycleHeader != fvuCurrentTsMsbCycle[fuCurrDpbIdx]) {
511 if (4194303 == fvulCurrentTsMsb[fuCurrDpbIdx]) {
512 LOG(info) << " TS " << std::setw(12) << fulCurrentTsIdx << " MS " << std::setw(12) << fulCurrentMsIdx
513 << " MS Idx " << std::setw(4) << uMsIdx << " Msg Idx " << std::setw(5) << 0 << " DPB " << std::setw(2)
514 << fuCurrDpbIdx << " Old TsMsb " << std::setw(5) << fvulCurrentTsMsb[fuCurrDpbIdx] << " Old MsbCy "
515 << std::setw(5) << fvuCurrentTsMsbCycle[fuCurrDpbIdx] << " New MsbCy " << uTsMsbCycleHeader;
516 }
517 else {
518 LOG(warning) << "TS MSB cycle from MS header does not match current cycle from data "
519 << "for TS " << std::setw(12) << fulCurrentTsIdx << " MS " << std::setw(12) << fulCurrentMsIdx
520 << " MsInTs " << std::setw(3) << uMsIdx << " ====> " << fvuCurrentTsMsbCycle[fuCurrDpbIdx] << " VS "
521 << uTsMsbCycleHeader;
522 } // else of if( 4194303 == fvulCurrentTsMsb[fuCurrDpbIdx] )
523 fvuCurrentTsMsbCycle[fuCurrDpbIdx] = uTsMsbCycleHeader;
524 } // else if( uTsMsbCycleHeader != fvuCurrentTsMsbCycle[ fuCurrDpbIdx ] )
525
526 // If not integer number of message in input buffer, print warning/error
527 if (0 != (uSize % sizeof(stsxyter::Message)))
528 LOG(error) << "The input microslice buffer does NOT "
529 << "contain only complete sDPB messages!";
530
531 // Compute the number of complete messages in the input microslice buffer
532 uint32_t uNbMessages = (uSize - (uSize % sizeof(stsxyter::Message))) / sizeof(stsxyter::Message);
533
534 // Prepare variables for the loop on contents
535 const stsxyter::Message* pMess = reinterpret_cast<const stsxyter::Message*>(msContent);
536 for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx++) {
538 stsxyter::MessType typeMess = pMess[uIdx].GetMessType();
539 fmMsgCounter[typeMess]++;
540 // fhStsMessType->Fill( static_cast< uint16_t > (typeMess) );
541 // fhStsMessTypePerDpb->Fill( fuCurrDpbIdx, static_cast< uint16_t > (typeMess) );
542
543 switch (typeMess) {
545 // Extract the eLink and Asic indices => Should GO IN the fill method now that obly hits are link/asic specific!
546 UShort_t usElinkIdx = pMess[uIdx].GetLinkIndex();
548 if (kTRUE == fbBinningFw) usElinkIdx = pMess[uIdx].GetLinkIndexHitBinning();
549 // fhStsMessTypePerElink->Fill( usElinkIdx, static_cast< uint16_t > (typeMess) );
550 // fhStsHitsElinkPerDpb->Fill( fuCurrDpbIdx, usElinkIdx );
551
552 UInt_t uCrobIdx = usElinkIdx / fUnpackPar->GetNbElinkPerCrob();
553 Int_t uFebIdx = fUnpackPar->ElinkIdxToFebIdx(usElinkIdx);
554
555 if (-1 == uFebIdx) {
556 LOG(warning) << "CbmMcbm2018UnpackerAlgoMuch::DoUnpack => "
557 << "Wrong elink Idx! Elink raw " << Form("%d remap %d", usElinkIdx, uFebIdx);
558 continue;
559 } // if( -1 == uFebIdx )
560
561 UInt_t uAsicIdx = (fuCurrDpbIdx * fUnpackPar->GetNbCrobsPerDpb() + uCrobIdx) * fUnpackPar->GetNbAsicsPerCrob()
562 + fUnpackPar->ElinkIdxToAsicIdx(usElinkIdx);
563
564 ProcessHitInfo(pMess[uIdx], usElinkIdx, uAsicIdx, uMsIdx);
565 break;
566 } // case stsxyter::MessType::Hit :
568 // fhStsMessTypePerElink->Fill( fuCurrDpbIdx * fUnpackPar->GetNbElinkPerDpb(), static_cast< uint16_t > (typeMess) );
569
570 ProcessTsMsbInfo(pMess[uIdx], uIdx, uMsIdx);
571 break;
572 } // case stsxyter::MessType::TsMsb :
574 // fhStsMessTypePerElink->Fill( fuCurrDpbIdx * fUnpackPar->GetNbElinkPerDpb(), static_cast< uint16_t > (typeMess) );
575
576 // The first message in the TS is a special ones: EPOCH
577 ProcessEpochInfo(pMess[uIdx]);
578
579 if (0 < uIdx)
580 LOG(info) << "CbmMcbm2018UnpackerAlgoMuch::DoUnpack => "
581 << "EPOCH message at unexpected position in MS: message " << uIdx << " VS message 0 expected!";
582 break;
583 } // case stsxyter::MessType::TsMsb :
586 UShort_t usElinkIdx = pMess[uIdx].GetStatusLink();
587 UInt_t uCrobIdx = usElinkIdx / fUnpackPar->GetNbElinkPerCrob();
588 Int_t uFebIdx = fUnpackPar->ElinkIdxToFebIdx(usElinkIdx);
589
590 if (-1 == uFebIdx) {
591 LOG(warning) << "CbmMcbm2018UnpackerAlgoMuch::DoUnpack => "
592 << "Wrong elink Idx! Elink raw " << Form("%d remap %d", usElinkIdx, uFebIdx);
593 continue;
594 } // if( -1 == uFebIdx )
595
596 UInt_t uAsicIdx = (fuCurrDpbIdx * fUnpackPar->GetNbCrobsPerDpb() + uCrobIdx) * fUnpackPar->GetNbAsicsPerCrob()
597 + fUnpackPar->ElinkIdxToAsicIdx(usElinkIdx);
598
599 ProcessStatusInfo(pMess[uIdx], uAsicIdx);
600 break;
601 } // case stsxyter::MessType::Status
603 // fhStsMessTypePerElink->Fill( fuCurrDpbIdx * fUnpackPar->GetNbElinkPerDpb(), static_cast< uint16_t > (typeMess) );
604 // FillTsMsbInfo( pMess[uIdx] );
605 break;
606 } // case stsxyter::MessType::Empty :
608 if (pMess[uIdx].IsMsErrorFlagOn()) {
609 fErrVect.push_back(
610 CbmErrorMessage(ECbmModuleId::kMuch, fulCurrentMsIdx, fuCurrDpbIdx, 0x20, pMess[uIdx].GetMsErrorType()));
611 } // if( pMess[uIdx].IsMsErrorFlagOn() )
612 break;
613 } // case stsxyter::MessType::EndOfMs :
615 // fhStsMessTypePerElink->Fill( fuCurrDpbIdx * fUnpackPar->GetNbElinkPerDpb(), static_cast< uint16_t > (typeMess) );
616 break;
617 } // case stsxyter::MessType::Dummy / ReadDataAck / Ack :
618 default: {
619 LOG(fatal) << "CbmMcbm2018UnpackerAlgoMuch::DoUnpack => "
620 << "Unknown message type, should never happen, stopping "
621 "here! Type found was: "
622 << static_cast<int>(typeMess);
623 }
624 } // switch( typeMess )
625 } // for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx ++)
626
627 return kTRUE;
628}
629
630// -------------------------------------------------------------------------
631void CbmMcbm2018UnpackerAlgoMuch::ProcessHitInfo(const stsxyter::Message& mess, const UShort_t& usElinkIdx,
632 const UInt_t& uAsicIdx, const UInt_t& /*uMsIdx*/)
633{
634 UShort_t usChan = mess.GetHitChannel();
635 UShort_t usRawAdc = mess.GetHitAdc();
636 // UShort_t usFullTs = mess.GetHitTimeFull();
637 // UShort_t usTsOver = mess.GetHitTimeOver();
638 UShort_t usRawTs = mess.GetHitTime();
639
641 if (kTRUE == fbBinningFw) usRawTs = mess.GetHitTimeBinning();
642
644 // usChan = 127 - usChan;
645
646 /*
647 fhStsChanCntRaw[ uAsicIdx ]->Fill( usChan );
648 fhStsChanAdcRaw[ uAsicIdx ]->Fill( usChan, usRawAdc );
649 fhStsChanAdcRawProf[ uAsicIdx ]->Fill( usChan, usRawAdc );
650 fhStsChanRawTs[ uAsicIdx ]->Fill( usChan, usRawTs );
651 fhStsChanMissEvt[ uAsicIdx ]->Fill( usChan, mess.IsHitMissedEvts() );
652*/
653 UInt_t uCrobIdx = usElinkIdx / fUnpackPar->GetNbElinkPerCrob();
654 // UInt_t uFebIdx = uAsicIdx / fUnpackPar->GetNbAsicsPerFeb();
655 // UInt_t uAsicInFeb = uAsicIdx % fUnpackPar->GetNbAsicsPerFeb();
656 // UInt_t uChanInFeb = usChan + fUnpackPar->GetNbChanPerAsic() * (uAsicIdx % fUnpackPar->GetNbAsicsPerFeb());
657
659 if (usRawTs == fvvusLastTsChan[uAsicIdx][usChan] &&
660 // usRawAdc == fvvusLastAdcChan[ uAsicIdx ][ usChan ] &&
664 return;
665 } // if same TS, ADC, TS MSB, TS MSB cycle!
666 fvvusLastTsChan[uAsicIdx][usChan] = usRawTs;
667 fvvusLastAdcChan[uAsicIdx][usChan] = usRawAdc;
670
671 /*
672 Double_t dCalAdc = fvdFebAdcOffs[ fuCurrDpbIdx ][ uCrobIdx ][ uFebIdx ]
673 + (usRawAdc - 1)* fvdFebAdcGain[ fuCurrDpbIdx ][ uCrobIdx ][ uFebIdx ];
674*/
675 /*
676 fhStsFebChanCntRaw[ uFebIdx ]->Fill( uChanInFeb );
677 fhStsFebChanAdcRaw[ uFebIdx ]->Fill( uChanInFeb, usRawAdc );
678 fhStsFebChanAdcRawProf[ uFebIdx ]->Fill( uChanInFeb, usRawAdc );
679 fhStsFebChanAdcCal[ uFebIdx ]->Fill( uChanInFeb, dCalAdc );
680 fhStsFebChanAdcCalProf[ uFebIdx ]->Fill( uChanInFeb, dCalAdc );
681 fhStsFebChanRawTs[ uFebIdx ]->Fill( usChan, usRawTs );
682 fhStsFebChanMissEvt[ uFebIdx ]->Fill( usChan, mess.IsHitMissedEvts() );
683*/
684 // Compute the Full time stamp
685 // Use TS w/o overlap bits as they will anyway come from the TS_MSB
686 Long64_t ulHitTime = usRawTs;
687 ulHitTime +=
688 static_cast<ULong64_t>(stsxyter::kuHitNbTsBins) * static_cast<ULong64_t>(fvulCurrentTsMsb[fuCurrDpbIdx])
689 + static_cast<ULong64_t>(stsxyter::kulTsCycleNbBins) * static_cast<ULong64_t>(fvuCurrentTsMsbCycle[fuCurrDpbIdx]);
690
692 if (kTRUE == fbBinningFw)
693 ulHitTime =
694 usRawTs
695 + static_cast<ULong64_t>(stsxyter::kuHitNbTsBinsBinning) * static_cast<ULong64_t>(fvulCurrentTsMsb[fuCurrDpbIdx])
696 + static_cast<ULong64_t>(stsxyter::kulTsCycleNbBinsBinning)
697 * static_cast<ULong64_t>(fvuCurrentTsMsbCycle[fuCurrDpbIdx]);
698
699 // Convert the Hit time in bins to Hit time in ns
700 Double_t dHitTimeNs = ulHitTime * stsxyter::kdClockCycleNs;
701
703 //if( 0 != fviFebAddress[ uFebIdx ] && fdAdcCut < usRawAdc )
704 if (fdAdcCut < usRawAdc) {
707 if (kFALSE == fbUseChannelMask || false == fvvbMaskedChannels[uAsicIdx][usChan])
708 fvmHitsInMs.push_back(stsxyter::FinalHit(ulHitTime, usRawAdc, uAsicIdx, usChan, fuCurrDpbIdx, uCrobIdx));
709 } // if( 0 != fviFebAddress[ uFebIdx ] )
710
711 // fvmHitsInMs.push_back( stsxyter::FinalHit( ulHitTime, usRawAdc, uAsicIdx, usChan, fuCurrDpbIdx, uCrobIdx ) );
712
714 if (mess.IsHitMissedEvts())
715 fErrVect.push_back(
716 CbmErrorMessage(ECbmModuleId::kMuch, dHitTimeNs, uAsicIdx, 1 << stsxyter::kusLenStatStatus, usChan));
717
718 // Check Starting point of histos with time as X axis
719 if (-1 == fdStartTime) fdStartTime = dHitTimeNs;
720 /*
721 // Fill histos with time as X axis
722 Double_t dTimeSinceStartSec = (dHitTimeNs - fdStartTime)* 1e-9;
723 Double_t dTimeSinceStartMin = dTimeSinceStartSec / 60.0;
724
725 fviFebCountsSinceLastRateUpdate[uFebIdx]++;
726 fvdFebChanCountsSinceLastRateUpdate[uFebIdx][uChanInFeb] += 1;
727
728 fhStsFebChanHitRateEvo[ uFebIdx ]->Fill( dTimeSinceStartSec, uhanInFeb );
729 fhStsFebAsicHitRateEvo[ uFebIdx ]->Fill( dTimeSinceStartSec, uAsicInFeb );
730 fhStsFebHitRateEvo[ uFebIdx ]->Fill( dTimeSinceStartSec );
731 fhStsFebChanHitRateEvoLong[ uFebIdx ]->Fill( dTimeSinceStartMin, uChanInFeb, 1.0/60.0 );
732 fhStsFebAsicHitRateEvoLong[ uFebIdx ]->Fill( dTimeSinceStartMin, uAsicInFeb, 1.0/60.0 );
733 fhStsFebHitRateEvoLong[ uFebIdx ]->Fill( dTimeSinceStartMin, 1.0/60.0 );
734 if( mess.IsHitMissedEvts() )
735 {
736 fhStsFebChanMissEvtEvo[ uFebIdx ]->Fill( dTimeSinceStartSec, uChanInFeb );
737 fhStsFebAsicMissEvtEvo[ uFebIdx ]->Fill( dTimeSinceStartSec, uAsicInFeb );
738 fhStsFebMissEvtEvo[ uFebIdx ]->Fill( dTimeSinceStartSec );
739 } // if( mess.IsHitMissedEvts() )
740*/
741 /*
742 if( kTRUE == fbLongHistoEnable )
743 {
744 std::chrono::steady_clock::time_point tNow = std::chrono::steady_clock::now();
745 Double_t dUnixTimeInRun = std::chrono::duration_cast< std::chrono::seconds >(tNow - ftStartTimeUnix).count();
746 fhFebRateEvoLong[ uAsicIdx ]->Fill( dUnixTimeInRun , 1.0 / fuLongHistoBinSizeSec );
747 fhFebChRateEvoLong[ uAsicIdx ]->Fill( dUnixTimeInRun , usChan, 1.0 / fuLongHistoBinSizeSec );
748 } // if( kTRUE == fbLongHistoEnable )
749*/
750}
751
752void CbmMcbm2018UnpackerAlgoMuch::ProcessTsMsbInfo(const stsxyter::Message& mess, UInt_t uMessIdx, UInt_t uMsIdx)
753{
754 UInt_t uVal = mess.GetTsMsbVal();
755
757 if (kTRUE == fbBinningFw) uVal = mess.GetTsMsbValBinning();
758
759 /*
760 if( (uVal != fvulCurrentTsMsb[fuCurrDpbIdx] + 1) && 0 < uVal &&
761 !( 1 == uMessIdx && usVal == fvulCurrentTsMsb[fuCurrDpbIdx] ) ) // 1st TS_MSB in MS is always a repeat of the last one in previous MS!
762 {
763 LOG(info) << "TS MSB not increasing by 1! TS " << std::setw( 12 ) << fulCurrentTsIdx
764 << " MS " << std::setw( 12 ) << fulCurrentMsIdx
765 << " MsInTs " << std::setw( 3 ) << uMsIdx
766 << " DPB " << std::setw( 2 ) << fuCurrDpbIdx
767 << " Mess " << std::setw( 5 ) << uMessIdx
768 << " Old TsMsb " << std::setw( 5 ) << fvulCurrentTsMsb[fuCurrDpbIdx]
769 << " new TsMsb " << std::setw( 5 ) << uVal
770 << " Diff " << std::setw( 5 ) << uVal - fvulCurrentTsMsb[fuCurrDpbIdx]
771 << " Old MsbCy " << std::setw( 5 ) << fvuCurrentTsMsbCycle[fuCurrDpbIdx];
772 } // if( (uVal != fvulCurrentTsMsb[fuCurrDpbIdx] + 1) && 0 < uVal )
773*/
774
775 // Update Status counters
776 if (uVal < fvulCurrentTsMsb[fuCurrDpbIdx]) {
777
778 LOG(info) << " TS " << std::setw(12) << fulCurrentTsIdx << " MS " << std::setw(12) << fulCurrentMsIdx << " MS Idx "
779 << std::setw(4) << uMsIdx << " Msg Idx " << std::setw(5) << uMessIdx << " DPB " << std::setw(2)
780 << fuCurrDpbIdx << " Old TsMsb " << std::setw(5) << fvulCurrentTsMsb[fuCurrDpbIdx] << " Old MsbCy "
781 << std::setw(5) << fvuCurrentTsMsbCycle[fuCurrDpbIdx] << " new TsMsb " << std::setw(5) << uVal;
782
784 } // if( uVal < fvulCurrentTsMsb[fuCurrDpbIdx] )
785 if (
786 uVal != fvulCurrentTsMsb[fuCurrDpbIdx] + 1 && !(0 == uVal && 4194303 == fvulCurrentTsMsb[fuCurrDpbIdx])
787 &&
788 1 != uMessIdx &&
789 !(0 == uVal && 0 == fvulCurrentTsMsb[fuCurrDpbIdx] && 2 == uMessIdx) &&
790 uVal < fvulCurrentTsMsb
791 [fuCurrDpbIdx]
792 ) {
793 LOG(info) << "TS MSb Jump in "
794 << " TS " << std::setw(12) << fulCurrentTsIdx << " MS " << std::setw(12) << fulCurrentMsIdx << " MS Idx "
795 << std::setw(4) << uMsIdx << " Msg Idx " << std::setw(5) << uMessIdx << " DPB " << std::setw(2)
796 << fuCurrDpbIdx << " => Old TsMsb " << std::setw(5) << fvulCurrentTsMsb[fuCurrDpbIdx] << " new TsMsb "
797 << std::setw(5) << uVal;
798 } // if( uVal + 1 != fvulCurrentTsMsb[fuCurrDpbIdx] && 4194303 != uVal && 0 != fvulCurrentTsMsb[fuCurrDpbIdx] )
799
802 if (4194303 == uVal && 1 == uMessIdx) fvulCurrentTsMsb[fuCurrDpbIdx] = 0;
803 else
805 /*
806 if( 1 < uMessIdx )
807 {
808 fhStsDpbRawTsMsb->Fill( fuCurrDpbIdx, fvulCurrentTsMsb[fuCurrDpbIdx] );
809 fhStsDpbRawTsMsbSx->Fill( fuCurrDpbIdx, ( fvulCurrentTsMsb[fuCurrDpbIdx] & 0x1F ) );
810 fhStsDpbRawTsMsbDpb->Fill( fuCurrDpbIdx, ( fvulCurrentTsMsb[fuCurrDpbIdx] >> 5 ) );
811 } // if( 0 < uMessIdx )
812*/
813 // fhStsAsicTsMsb->Fill( fvulCurrentTsMsb[fuCurrDpbIdx], uAsicIdx );
814 /*
815 ULong64_t ulNewTsMsbTime = static_cast< ULong64_t >( stsxyter::kuHitNbTsBins )
816 * static_cast< ULong64_t >( fvulCurrentTsMsb[fuCurrDpbIdx])
817 + static_cast< ULong64_t >( stsxyter::kulTsCycleNbBins )
818 * static_cast< ULong64_t >( fvuCurrentTsMsbCycle[fuCurrDpbIdx] );
819*/
820}
821
823{
824 // UInt_t uVal = mess.GetEpochVal();
825 // UInt_t uCurrentCycle = uVal % stsxyter::kulTsCycleNbBins;
826
827 /*
828 // Update Status counters
829 if( usVal < fvulCurrentTsMsb[fuCurrDpbIdx] )
830 fvuCurrentTsMsbCycle[fuCurrDpbIdx] ++;
831 fvulCurrentTsMsb[fuCurrDpbIdx] = usVal;
832
833// fhStsAsicTsMsb->Fill( fvulCurrentTsMsb[fuCurrDpbIdx], uAsicIdx );
834*/
835}
836
838{
839 /*
840 UShort_t usStatusField = mess.GetStatusStatus();
841
842 fhPulserStatusMessType->Fill( uAsicIdx, usStatusField );
844 if( fbPrintMessages )
845 {
846 std::cout << Form("DPB %2u TS %12u MS %12u mess %5u ", fuCurrDpbIdx, fulCurrentTsIdx, fulCurrentMsIdx, uIdx );
847 mess.PrintMess( std::cout, fPrintMessCtrl );
848 } // if( fbPrintMessages )
849*/
852 Long64_t ulTime =
853 static_cast<ULong64_t>(stsxyter::kuHitNbTsBins) * static_cast<ULong64_t>(fvulCurrentTsMsb[fuCurrDpbIdx])
854 + static_cast<ULong64_t>(stsxyter::kulTsCycleNbBins) * static_cast<ULong64_t>(fvuCurrentTsMsbCycle[fuCurrDpbIdx]);
855
857 if (kTRUE == fbBinningFw)
858 ulTime =
859 static_cast<ULong64_t>(stsxyter::kuHitNbTsBinsBinning) * static_cast<ULong64_t>(fvulCurrentTsMsb[fuCurrDpbIdx])
860 + static_cast<ULong64_t>(stsxyter::kulTsCycleNbBinsBinning)
861 * static_cast<ULong64_t>(fvuCurrentTsMsbCycle[fuCurrDpbIdx]);
862
864 Double_t dTimeNs = ulTime * stsxyter::kdClockCycleNs;
865
866 fErrVect.push_back(CbmErrorMessage(ECbmModuleId::kMuch, dTimeNs, uAsicIdx, mess.GetStatusStatus(), mess.GetData()));
867}
868
869// -------------------------------------------------------------------------
870
871// -------------------------------------------------------------------------
872
874{
877 new TH1I("hMuchDigisTimeInRun", "Digis Nb vs Time in Run; Time in run [s]; Digis Nb []", 36000, 0, 3600);
879
880 fhVectorSize = new TH1I("fhVectorSize", "Size of the vector VS TS index; TS index; Size [bytes]", 10000, 0., 10000.);
882 new TH1I("fhVectorCapacity", "Size of the vector VS TS index; TS index; Size [bytes]", 10000, 0., 10000.);
885
886 /*
888 for( UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; ++uGdpb )
889 {
890 UInt_t uSector = fUnpackPar->GetGdpbToSectorOffset() + uGdpb;
891 std::string sFolder = Form( "sector%2u", uSector);
892
893 LOG(info) << "gDPB " << uGdpb << " is " << sFolder;
894
895 fvhHitsTimeToTriggerRaw.push_back( new TH1D(
896 Form( "hHitsTimeToTriggerRawSect%2u", uSector ),
897 Form( "Time to trigger for all neighboring hits in sector %2u; t - Ttrigg [ns]; Hits []", uSector ),
898 2000, -5000, 5000 ) );
899
900 UInt_t uNbBinsDtSel = fdStarTriggerWinSize[ uGdpb ];
901 Double_t dMaxDtSel = fdStarTriggerDelay[ uGdpb ] + fdStarTriggerWinSize[ uGdpb ];
902 fvhHitsTimeToTriggerSel.push_back( new TH1D(
903 Form( "hHitsTimeToTriggerSelSect%2u", uSector ),
904 Form( "Time to trigger for all selected hits in sector %2u; t - Ttrigg [ns]; Hits []", uSector ),
905 uNbBinsDtSel, fdStarTriggerDelay[ uGdpb ], dMaxDtSel ) );
906
908 AddHistoToVector( fvhHitsTimeToTriggerRaw[ uGdpb ], sFolder );
909 AddHistoToVector( fvhHitsTimeToTriggerSel[ uGdpb ], sFolder );
910
911 if( kTRUE == fbDebugMonitorMode )
912 {
913 fvhHitsTimeToTriggerSelVsDaq.push_back( new TH2D(
914 Form( "hHitsTimeToTriggerSelVsDaqSect%2u", uSector ),
915 Form( "Time to trigger for all selected hits vs DAQ CMD in sector %2u; t - Ttrigg [ns]; DAQ CMD []; Hits []", uSector ),
916 uNbBinsDtSel, fdStarTriggerDelay[ uGdpb ], dMaxDtSel,
917 16, 0., 16. ) );
918
919 fvhHitsTimeToTriggerSelVsTrig.push_back( new TH2D(
920 Form( "hHitsTimeToTriggerSelVsTrigSect%2u", uSector ),
921 Form( "Time to trigger for all selected hits vs TRIG CMD in sector %2u; t - Ttrigg [ns]; TRIG CMD []; Hits []", uSector ),
922 uNbBinsDtSel, fdStarTriggerDelay[ uGdpb ], dMaxDtSel,
923 16, 0., 16. ) );
924
925 fvhTriggerDt.push_back( new TH1I(
926 Form( "hTriggerDtSect%2u", uSector ),
927 Form( "Trigger time difference between sector %2u and the first sector, full events only; Ttrigg%2u - TtriggRef [Clk]; events []",
928 uSector, uSector ),
929 200, -100, 100 ) );
930
933 UInt_t uNbBinsInTs = fdMsSizeInNs * 111 / 1000. / 10.;
934 UInt_t uNbBinsInMs = fdMsSizeInNs * 20 / 1000. / 10.;
935
936 fvhTriggerDistributionInTs.push_back( new TH1I( Form( "hTriggerDistInTsSect%2u", uSector ),
937 Form( "Trigger distribution inside TS in sector %2u; Time in TS [us]; Trigger [];", uSector ),
938 uNbBinsInTs, -0.5 - fdMsSizeInNs * 10 / 1000., fdMsSizeInNs * 101 / 1000. - 0.5 ) );
939
940 fvhTriggerDistributionInMs.push_back( new TH1I( Form( "hTriggerDistInMsSect%2u", uSector ),
941 Form( "Trigger distribution inside MS in sector %2u; Time in MS [us]; Trigger [];", uSector ),
942 uNbBinsInMs, -0.5 - fdMsSizeInNs * 10 / 1000., fdMsSizeInNs * 10 / 1000. - 0.5 ) );
943
944 fvhMessDistributionInMs.push_back( new TH1I( Form( "hMessDistInMsSect%2u", uSector ),
945 Form( "Messages distribution inside MS in sector %2u; Time in MS [us]; Trigger [];", uSector ),
946 uNbBinsInMs, -0.5 - fdMsSizeInNs * 10 / 1000., fdMsSizeInNs * 10 / 1000. - 0.5 ) );
947
949 AddHistoToVector( fvhHitsTimeToTriggerSelVsDaq[ uGdpb ], sFolder );
950 AddHistoToVector( fvhHitsTimeToTriggerSelVsTrig[ uGdpb ], sFolder );
951 AddHistoToVector( fvhTriggerDt[ uGdpb ], sFolder );
952 AddHistoToVector( fvhTriggerDistributionInTs[ uGdpb ], sFolder );
953 AddHistoToVector( fvhTriggerDistributionInMs[ uGdpb ], sFolder );
954 AddHistoToVector( fvhMessDistributionInMs[ uGdpb ], sFolder );
955 } // if( kTRUE == fbDebugMonitorMode )
956 } // for( UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; ++uGdpb )
957
959 fhEventNbPerTs = new TH1I( "hEventNbPerTs",
960 "Number of Events per TS; Events []; TS []",
961 1000 , 0, 1000 );
962
963 fhEventSizeDistribution = new TH1I( "hEventSizeDistribution",
964 "Event size distribution; Event size [byte]; Events []",
965 CbmTofStarSubevent2019::GetMaxOutputSize()/8 , 0, CbmTofStarSubevent2019::GetMaxOutputSize() );
966
967 fhEventSizeEvolution = new TProfile( "hEventSizeEvolution",
968 "Event size evolution; Time in run [min]; mean Event size [byte];",
969 14400, 0, 14400 );
970
971 fhEventNbEvolution = new TH1I( "hEventNbEvolution",
972 "Event number evolution; Time in run [min]; Events [];",
973 14400, 0, 14400 );
974
976 AddHistoToVector( fhEventNbPerTs, "eventbuilder" );
977 AddHistoToVector( fhEventSizeDistribution, "eventbuilder" );
978 AddHistoToVector( fhEventSizeEvolution, "eventbuilder" );
979 AddHistoToVector( fhEventNbEvolution, "eventbuilder" );
980
981 if( kTRUE == fbDebugMonitorMode )
982 {
985 UInt_t uNbBinsInTs = fdMsSizeInNs * 101 / 1000. / 10.;
986
987 fhEventNbDistributionInTs = new TH1I( "hEventNbDistributionInTs",
988 "Event number distribution inside TS; Time in TS [us]; Events [];",
989 uNbBinsInTs, -0.5, fdMsSizeInNs * 101 / 1000. - 0.5 );
990
991 fhEventSizeDistributionInTs = new TProfile( "hEventSizeDistributionInTs",
992 "Event size distribution inside TS; Time in TS [us]; mean Event size [Byte];",
993 uNbBinsInTs, -0.5, fdMsSizeInNs * 101 / 1000. - 0.5 );
994
995 fhRawTriggersStats = new TH2I(
996 "hRawTriggersStats",
997 "Raw triggers statistics per sector; ; Sector []; Messages []",
998 5, 0, 5,
999 12, 13, 25 );
1000 fhRawTriggersStats->GetXaxis()->SetBinLabel( 1, "A");
1001 fhRawTriggersStats->GetXaxis()->SetBinLabel( 2, "B");
1002 fhRawTriggersStats->GetXaxis()->SetBinLabel( 3, "C");
1003 fhRawTriggersStats->GetXaxis()->SetBinLabel( 4, "D");
1004 fhRawTriggersStats->GetXaxis()->SetBinLabel( 5, "F");
1005
1006 fhMissingTriggersEvolution = new TH2I(
1007 "hMissingTriggersEvolution",
1008 "Missing trigger counts per sector vs time in run; Time in run [min]; Sector []; Missing triggers []",
1009 14400, 0, 14400,
1010 12, 13, 25 );
1011
1013 AddHistoToVector( fhEventNbDistributionInTs, "eventbuilder" );
1014 AddHistoToVector( fhEventSizeDistributionInTs, "eventbuilder" );
1015 AddHistoToVector( fhRawTriggersStats, "eventbuilder" );
1016 AddHistoToVector( fhMissingTriggersEvolution, "eventbuilder" );
1017 } // if( kTRUE == fbDebugMonitorMode )
1018
1020 Double_t w = 10;
1021 Double_t h = 10;
1022
1024 fcTimeToTrigRaw = new TCanvas( "cTimeToTrigRaw", "Raw Time to trig for all sectors", w, h);
1025 fcTimeToTrigRaw->Divide( 2, fuNrOfGdpbs / 2 );
1026 for( UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; ++uGdpb )
1027 {
1028 fcTimeToTrigRaw->cd( 1 + uGdpb );
1029 gPad->SetGridx();
1030 gPad->SetGridy();
1031 gPad->SetLogy();
1032 fvhHitsTimeToTriggerRaw[ uGdpb ]->Draw();
1033 } // for( UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; ++uGdpb )
1034
1036 fcTimeToTrigSel = new TCanvas( "cTimeToTrigSel", "Selected Time to trig for all sectors", w, h);
1037 fcTimeToTrigSel->Divide( 2, fuNrOfGdpbs / 2 );
1038 for( UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; ++uGdpb )
1039 {
1040 fcTimeToTrigSel->cd( 1 + uGdpb );
1041 gPad->SetGridx();
1042 gPad->SetGridy();
1043 gPad->SetLogy();
1044 fvhHitsTimeToTriggerSel[ uGdpb ]->Draw();
1045 } // for( UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; ++uGdpb )
1046
1047 if( kTRUE == fbDebugMonitorMode )
1048 {
1050 fcTrigDistMs = new TCanvas( "cTrigDistMs", "Trigger time to MS start for all sectors", w, h);
1051 fcTrigDistMs->Divide( 2, fuNrOfGdpbs / 2 );
1052 for( UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; ++uGdpb )
1053 {
1054 fcTrigDistMs->cd( 1 + uGdpb );
1055 gPad->SetGridx();
1056 gPad->SetGridy();
1057 gPad->SetLogy();
1058 fvhTriggerDistributionInMs[ uGdpb ]->Draw();
1059 } // for( UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; ++uGdpb )
1060
1062 fcMessDistMs = new TCanvas( "cMessDistMs", "Message time to MS start for all sectors", w, h);
1063 fcMessDistMs->Divide( 2, fuNrOfGdpbs / 2 );
1064 for( UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; ++uGdpb )
1065 {
1066 fcMessDistMs->cd( 1 + uGdpb );
1067 gPad->SetGridx();
1068 gPad->SetGridy();
1069 gPad->SetLogy();
1070 fvhMessDistributionInMs[ uGdpb ]->Draw();
1071 } // for( UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; ++uGdpb )
1072 } // if( kTRUE == fbDebugMonitorMode )
1073
1075 fcEventBuildStats = new TCanvas( "cEvtBuildStats", "Event building statistics", w, h);
1076 if( kTRUE == fbDebugMonitorMode )
1077 fcEventBuildStats->Divide( 2, 3 );
1078 else fcEventBuildStats->Divide( 2, 2 );
1079
1080 fcEventBuildStats->cd( 1 );
1081 gPad->SetGridx();
1082 gPad->SetGridy();
1083 gPad->SetLogy();
1084 fhEventNbPerTs->Draw();
1085
1086 fcEventBuildStats->cd( 2 );
1087 gPad->SetGridx();
1088 gPad->SetGridy();
1089 gPad->SetLogy();
1090 fhEventSizeDistribution->Draw();
1091
1092 fcEventBuildStats->cd( 3 );
1093 gPad->SetGridx();
1094 gPad->SetGridy();
1095 gPad->SetLogy();
1096 fhEventSizeEvolution->Draw();
1097
1098 fcEventBuildStats->cd( 4 );
1099 gPad->SetGridx();
1100 gPad->SetGridy();
1101 gPad->SetLogy();
1102 fhEventNbEvolution->Draw();
1103
1104 if( kTRUE == fbDebugMonitorMode )
1105 {
1106 fcEventBuildStats->cd( 5 );
1107 gPad->SetGridx();
1108 gPad->SetGridy();
1109 gPad->SetLogy();
1110 fhEventNbDistributionInTs->Draw();
1111
1112 fcEventBuildStats->cd( 6 );
1113 gPad->SetGridx();
1114 gPad->SetGridy();
1115 gPad->SetLogy();
1116 fhEventSizeDistributionInTs->Draw();
1117 } // if( kTRUE == fbDebugMonitorMode )
1118
1119 AddCanvasToVector( fcEventBuildStats, "canvases" );
1120*/
1121 return kTRUE;
1122}
1124{
1125 for (auto itHit = fDigiVect.begin(); itHit != fDigiVect.end(); ++itHit) {
1126 fhDigisTimeInRun->Fill(itHit->GetTime() * 1e-9);
1127 } // for( auto itHit = fDigiVect.begin(); itHit != fDigiVect.end(); ++itHit)
1128 return kTRUE;
1129}
1131{
1132 fhDigisTimeInRun->Reset();
1133 /*
1134 for( UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; ++uGdpb )
1135 {
1136 fvhHitsTimeToTriggerRaw[ uGdpb ]->Reset();
1137 fvhHitsTimeToTriggerSel[ uGdpb ]->Reset();
1138
1139 if( kTRUE == fbDebugMonitorMode )
1140 {
1141 fvhHitsTimeToTriggerSelVsDaq[ uGdpb ]->Reset();
1142 fvhHitsTimeToTriggerSelVsTrig[ uGdpb ]->Reset();
1143 fvhTriggerDt[ uGdpb ]->Reset();
1144 fvhTriggerDistributionInTs[ uGdpb ]->Reset();
1145 fvhTriggerDistributionInMs[ uGdpb ]->Reset();
1146 fvhMessDistributionInMs[ uGdpb ]->Reset();
1147 } // if( kTRUE == fbDebugMonitorMode )
1148 } // for( UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; ++uGdpb )
1149
1151 fhEventNbPerTs->Reset();
1152 fhEventSizeDistribution->Reset();
1153 fhEventSizeEvolution->Reset();
1154 fhEventNbEvolution->Reset();
1155
1156 if( kTRUE == fbDebugMonitorMode )
1157 {
1158 fhEventNbDistributionInTs->Reset();
1159 fhEventSizeDistributionInTs->Reset();
1160 fhRawTriggersStats->Reset();
1161 fhMissingTriggersEvolution->Reset();
1162 } // if( kTRUE == fbDebugMonitorMode )
1163*/
1164 return kTRUE;
1165}
1166// -------------------------------------------------------------------------
1167
1168void CbmMcbm2018UnpackerAlgoMuch::SetTimeOffsetNsAsic(UInt_t uAsicIdx, Double_t dOffsetIn)
1169{
1170 if (uAsicIdx >= fvdTimeOffsetNsAsics.size()) {
1171 fvdTimeOffsetNsAsics.resize(uAsicIdx + 1, 0.0);
1172 } // if( uAsicIdx < fvdTimeOffsetNsAsics.size() )
1173
1174 fvdTimeOffsetNsAsics[uAsicIdx] = dOffsetIn;
1175}
1176// -------------------------------------------------------------------------
1177void CbmMcbm2018UnpackerAlgoMuch::MaskNoisyChannel(UInt_t uFeb, UInt_t uChan, Bool_t bMasked)
1178{
1179 if (kFALSE == fbUseChannelMask) {
1180 fbUseChannelMask = kTRUE;
1182 for (UInt_t uFebIdx = 0; uFebIdx < fuNbFebs; ++uFebIdx) {
1183 fvvbMaskedChannels[uFebIdx].resize(fUnpackPar->GetNbChanPerFeb(), false);
1184 } // for( UInt_t uFeb = 0; uFeb < fuNbFebs; ++uFeb )
1185 } // if( kFALSE == fbUseChannelMask )
1186 if (uFeb < fuNbFebs && uChan < fUnpackPar->GetNbChanPerFeb()) fvvbMaskedChannels[uFeb][uChan] = bMasked;
1187 else
1188 LOG(fatal) << "CbmMcbm2018UnpackerAlgoMuch::MaskNoisyChannel => Invalid "
1189 "FEB and/or CHAN index:"
1190 << Form(" %u vs %u and %u vs %u", uFeb, fuNbFebs, uChan, fUnpackPar->GetNbChanPerFeb());
1191}
1192// -------------------------------------------------------------------------
@ kMuch
Muon detection system.
std::string FormatMsHeaderPrintout(const fles::MicrosliceDescriptor &msDescriptor)
CbmRoot (+externals) headers.
Int_t ElinkIdxToFebIdx(UInt_t uElink)
static constexpr UInt_t GetNbElinkPerCrob()
Short_t GetPadXA(UShort_t febid, UShort_t channelid)
static constexpr UInt_t GetNbChanPerAsic()
static constexpr UInt_t GetNbAsicsPerCrob()
Short_t GetPadXB(UShort_t febid, UShort_t channelid)
static constexpr UInt_t GetNbChanPerFeb()
UInt_t GetDpbId(UInt_t uDpbIdx)
Short_t GetPadYB(UShort_t febid, UShort_t channelid)
UInt_t ElinkIdxToAsicIdx(UInt_t uElink)
Short_t GetPadYA(UShort_t febid, UShort_t channelid)
Bool_t IsCrobActive(UInt_t uDpbIdx, UInt_t uCrobIdx)
static constexpr UInt_t GetNbCrobsPerDpb()
std::map< UInt_t, UInt_t > fDpbIdIndexMap
Total number of STS DPBs in system.
std::vector< std::vector< UShort_t > > fvvusLastTsChan
Limit how many different TS_MSB are checked for same duplicate hit => set to 1 uS.
CbmMuchBeamTimeDigi * CreateMuchDigi(stsxyter::FinalHit *)
void ProcessTsMsbInfo(const stsxyter::Message &mess, UInt_t uMessIdx=0, UInt_t uMsIdx=0)
CbmMcbm2018MuchPar * fUnpackPar
Switch to smx2.0/smx2.1 data-> fiFlag = 0 for 2.0 and fiFlag = 1 for 2.1.
Bool_t fbBinningFw
=> Quick and dirty hack for binning FW!!!
void MaskNoisyChannel(UInt_t uFeb, UInt_t uChan, Bool_t bMasked=kTRUE)
Bool_t ProcessMs(const fles::Timeslice &ts, size_t uMsCompIdx, size_t uMsIdx)
std::vector< Bool_t > fvbMaskedComponents
Switch ON the filling of a additional set of histograms.
UInt_t fuNbFebs
Array to hold the active flag for all CROBs, [ NbDpb ][ NbCrobPerDpb ].
std::vector< std::vector< UShort_t > > fvvusLastTsMsbChan
ADC of last hit message for each channel, [ AsicIdx ][ Chan ].
Double_t fdTimeOffsetNs
Number of StsXyter ASICs.
std::vector< std::vector< UShort_t > > fvvusLastTsMsbCycleChan
TS MSB of last hit message for each channel, [ AsicIdx ][ Chan ].
UInt_t fuCurrDpbId
Current equipment ID, tells from which DPB the current MS is originating.
void SetTimeOffsetNsAsic(UInt_t uAsicIdx, Double_t dOffsetIn=0.0)
std::vector< UInt_t > fvuCurrentTsMsbCycle
Current TS MSB for each DPB.
UInt_t fuNbStsXyters
Number of FEBs with StsXyter ASICs.
std::vector< std::vector< Bool_t > > fvbCrobActiveFlag
Map of DPB Identifier to DPB index.
std::vector< std::vector< bool > > fvvbMaskedChannels
Bool_t ProcessTs(const fles::Timeslice &ts)
std::vector< Double_t > fvdTimeOffsetNsAsics
std::vector< stsxyter::FinalHit > fvmHitsInMs
Hits time-sorting.
std::map< stsxyter::MessType, UInt_t > fmMsgCounter
void AddMsComponentToList(size_t component, UShort_t usDetectorId)
void ProcessStatusInfo(const stsxyter::Message &mess, const UInt_t &uAsicIdx)
UInt_t fdAdcCut
Vector of channel masks, [ NbFeb ][ NbCHanInFeb ], used only if fbUseChannelMask is true.
TH1 * fhDigisTimeInRun
TS MSB cycle of last hit message for each channel, [ AsicIdx ][ Chan ].
std::vector< std::vector< UShort_t > > fvvusLastAdcChan
TS of last hit message for each channel, [ AsicIdx ][ Chan ].
void ProcessHitInfo(const stsxyter::Message &mess, const UShort_t &usElinkIdx, const UInt_t &uAsicIdx, const UInt_t &uMsIdx)
void ProcessEpochInfo(const stsxyter::Message &mess)
static const UInt_t kuMaxTsMsbDiffDuplicates
All hits (time in bins, ADC in bins, asic, channel) in last MS, sorted with "<" operator.
UInt_t fuMsIndex
Start Time in ns of current MS from its index field in header.
UInt_t fuCurrDpbIdx
Temp holder until Current equipment ID is properly filled in MS.
Double_t fdTsStopTimeCore
Time in ns of current TS from the index of the first MS first component.
std::vector< ULong64_t > fvulCurrentTsMsb
static uint32_t GetAddress(int32_t station=0, int32_t layer=0, int32_t side=0, int32_t module=0, int32_t sector=0, int32_t channel=0)
void SetNxId(int32_t nxId)
void SetPadX(int32_t padX)
void SetPadY(int32_t padY)
void SetRocId(int32_t rocId)
void SetNxCh(int32_t nxCh)
std::vector< CbmErrorMessage > fErrVect
void AddHistoToVector(TNamed *pointer, std::string sFolder="")
std::vector< CbmMuchBeamTimeDigi > fDigiVect
uint16_t GetDpb() const
uint16_t GetAsic() const
uint16_t GetChan() const
uint64_t GetTs() const
uint16_t GetAdc() const
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)
XPU_D uint16_t GetLinkIndex() const
For all data: Returns the (global) index of the eLink on which the message was received (n bit field)
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 GetHitTime() const
For Hit data: Returns timestamp (8 bit field, 2 MSB bits overlap removed)
XPU_D uint32_t GetTsMsbVal() const
For TS MSB data: Returns the TS MSB 22 bit field)
XPU_D uint16_t GetHitTimeBinning() const
XPU_D uint16_t GetStatusLink() const
For Status data: Returns the Link Inedx (9 bit field)
Hash for CbmL1LinkKey.
static constexpr uint32_t kuHitNbTsBinsBinning
static constexpr uint64_t kulTsCycleNbBins
static constexpr uint64_t kulTsCycleNbBinsBinning
static constexpr uint32_t kuHitNbTsBins
static constexpr double kdClockCycleNs
MessType
Message types.
static constexpr uint16_t kusLenStatStatus