CbmRoot
Loading...
Searching...
No Matches
CbmMcbm2018MonitorAlgoTofPulser.cxx
Go to the documentation of this file.
1/* Copyright (C) 2019-2021 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// ----- CbmMcbm2018MonitorAlgoTofPulser -----
8// ----- Created 12.10.2019 by P.-A. Loizeau -----
9// ----- -----
10// -----------------------------------------------------------------------------
11
13
15#include "CbmMcbm2018TofPar.h"
16
17#include "FairRootManager.h"
18#include "FairRun.h"
19#include "FairRunOnline.h"
20#include "FairRuntimeDb.h"
21#include <Logger.h>
22
23#include "TCanvas.h"
24#include "TH1.h"
25#include "TH2.h"
26#include "TList.h"
27#include "TPaveStats.h"
28#include "TProfile.h"
29#include "TROOT.h"
30#include "TString.h"
31
32#include <fstream>
33#include <iomanip>
34#include <iostream>
35
36#include <stdint.h>
37
38// -------------------------------------------------------------------------
41 ,
43 fvbMaskedComponents()
44 , fiGdpbIndex(-1)
45 , fuUpdateFreqTs(100)
46 , fUnpackPar(nullptr)
47 , fuNrOfGdpbs(0)
48 , fGdpbIdIndexMap()
49 , fuNrOfFeePerGdpb(0)
50 , fuNrOfGet4PerFee(0)
51 , fuNrOfChannelsPerGet4(0)
52 , fuNrOfChannelsPerFee(0)
53 , fuNrOfGet4(0)
54 , fuNrOfGet4PerGdpb(0)
55 , fuNrOfChannelsPerGdpb(0)
56 , fuPulserMinTot(90)
57 , fuPulserMaxTot(110)
58 , fuPulserChannel(3)
59 , fulCurrentTsIdx(0)
60 , fulCurrentMsIdx(0)
61 , fdTsStartTime(-1.0)
62 , fdTsStopTimeCore(-1.0)
63 , fdMsTime(-1.0)
64 , fuMsIndex(0)
65 , fuCurrentEquipmentId(0)
66 , fuCurrDpbId(0)
67 , fuCurrDpbIdx(0)
68 , fuGet4Id(0)
69 , fuGet4Nr(0)
70 , fvulCurrentEpoch()
71 , fvulCurrentEpochCycle()
72 , fvulCurrentEpochFull()
73 , fvmEpSupprBuffer()
74 , fvvbFeeHitFound()
75 , fvvdFeeHits()
76 , dMinDt(0.0)
77 , dMaxDt(0.0)
78 , fdStartTime(-1.0)
79 , fuHistoryHistoSize(1800)
80 , fvvhFeePairPulserTimeDiff()
81 , fhPulserTimeDiffMean(nullptr)
82 , fhPulserTimeDiffRms(nullptr)
83 , fhPulserTimeDiffRmsZoom(nullptr)
84 , fhPulserRmsGdpbToRefEvo(nullptr)
85 , fhPulserRmsGbtxToRefEvo(nullptr)
86{
87}
93
94// -------------------------------------------------------------------------
96{
97 LOG(info) << "Initializing mCBM T0 2019 monitor algo";
98
99 return kTRUE;
100}
108
109// -------------------------------------------------------------------------
111{
112 LOG(info) << "Init parameter containers for CbmMcbm2018MonitorAlgoTofPulser";
113 Bool_t initOK = ReInitContainers();
114
115 return initOK;
116}
118{
119 LOG(info) << "**********************************************";
120 LOG(info) << "ReInit parameter containers for CbmMcbm2018MonitorAlgoTofPulser";
121
122 fUnpackPar = (CbmMcbm2018TofPar*) fParCList->FindObject("CbmMcbm2018TofPar");
123 if (nullptr == fUnpackPar) return kFALSE;
124
125 Bool_t initOK = InitParameters();
126
127 return initOK;
128}
130{
131 if (nullptr == fParCList) fParCList = new TList();
132 fUnpackPar = new CbmMcbm2018TofPar("CbmMcbm2018TofPar");
133 fParCList->Add(fUnpackPar);
134
135 return fParCList;
136}
138{
139
141 LOG(info) << "Nr. of Tof GDPBs: " << fuNrOfGdpbs;
142
144 LOG(info) << "Nr. of FEES per Tof GDPB: " << fuNrOfFeePerGdpb;
145
147 LOG(info) << "Nr. of GET4 per Tof FEE: " << fuNrOfGet4PerFee;
148
150 LOG(info) << "Nr. of channels per GET4: " << fuNrOfChannelsPerGet4;
151
153 LOG(info) << "Nr. of channels per FEE: " << fuNrOfChannelsPerFee;
154
156 LOG(info) << "Nr. of GET4s: " << fuNrOfGet4;
157
159 LOG(info) << "Nr. of GET4s per GDPB: " << fuNrOfGet4PerGdpb;
160
162 LOG(info) << "Nr. of channels per GDPB: " << fuNrOfChannelsPerGdpb;
163
164 fGdpbIdIndexMap.clear();
165 for (UInt_t i = 0; i < fuNrOfGdpbs; ++i) {
167 LOG(info) << "GDPB Id of TOF " << i << " : " << std::hex << fUnpackPar->GetGdpbId(i) << std::dec;
168 } // for( UInt_t i = 0; i < fuNrOfGdpbs; ++i )
169
172 LOG(info) << "Timeslice parameters: each MS is " << fdMsSizeInNs << " ns";
173
175 if (-1 < fiGdpbIndex) {
176 if (fuNrOfGdpbs <= static_cast<UInt_t>(fiGdpbIndex))
177 LOG(fatal) << "Selected gDPB out of bounds relative to parameter file: " << fiGdpbIndex << " VS " << fuNrOfGdpbs;
178 else
179 LOG(info) << "Selected gDPB " << fiGdpbIndex << " for single gDPB analysis";
180 fuNrOfGdpbs = 1;
181 fGdpbIdIndexMap.clear();
183 } // if( -1 < fiGdpbIndex )
184
186 fvulCurrentEpoch.resize(fuNrOfGdpbs, 0);
190 fvvdFeeHits.resize(fuNrOfGdpbs);
191 for (UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; ++uGdpb) {
192 fvvbFeeHitFound[uGdpb].resize(fuNrOfFeePerGdpb, kFALSE);
193 fvvdFeeHits[uGdpb].resize(fuNrOfFeePerGdpb, 0.0);
194 } // for( UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; ++uGdpb )
195
196
197 return kTRUE;
198}
199// -------------------------------------------------------------------------
200
201void CbmMcbm2018MonitorAlgoTofPulser::AddMsComponentToList(size_t component, UShort_t usDetectorId)
202{
204 for (UInt_t uCompIdx = 0; uCompIdx < fvMsComponentsList.size(); ++uCompIdx)
205 if (component == fvMsComponentsList[uCompIdx]) return;
206
208 fvMsComponentsList.push_back(component);
209
210 LOG(info) << "CbmMcbm2018MonitorAlgoTofPulser::AddMsComponentToList => Component " << component
211 << " with detector ID 0x" << std::hex << usDetectorId << std::dec << " added to list";
212}
213// -------------------------------------------------------------------------
214
215Bool_t CbmMcbm2018MonitorAlgoTofPulser::ProcessTs(const fles::Timeslice& ts)
216{
217 fulCurrentTsIdx = ts.index();
218 fdTsStartTime = static_cast<Double_t>(ts.descriptor(0, 0).idx);
219
221 if (0 == fulCurrentTsIdx) return kTRUE;
222
224 if (-1.0 == fdTsCoreSizeInNs) {
225 fuNbCoreMsPerTs = ts.num_core_microslices();
226 fuNbOverMsPerTs = ts.num_microslices(0) - ts.num_core_microslices();
229 LOG(info) << "Timeslice parameters: each TS has " << fuNbCoreMsPerTs << " Core MS and " << fuNbOverMsPerTs
230 << " Overlap MS, for a core duration of " << fdTsCoreSizeInNs << " ns and a full duration of "
231 << fdTsFullSizeInNs << " ns";
232
236 LOG(info) << "In each TS " << fuNbMsLoop << " MS will be looped over";
237 } // if( -1.0 == fdTsCoreSizeInNs )
238
241 // LOG(info) << Form( "TS %5d Start %12f Stop %12f", fulCurrentTsIdx, fdTsStartTime, fdTsStopTimeCore );
242
244 for (fuMsIndex = 0; fuMsIndex < fuNbMsLoop; fuMsIndex++) {
246 for (UInt_t uMsCompIdx = 0; uMsCompIdx < fvMsComponentsList.size(); ++uMsCompIdx) {
247 UInt_t uMsComp = fvMsComponentsList[uMsCompIdx];
248
249 if (kFALSE == ProcessMs(ts, uMsComp, fuMsIndex)) {
250 LOG(error) << "Failed to process ts " << fulCurrentTsIdx << " MS " << fuMsIndex << " for component " << uMsComp;
251 return kFALSE;
252 } // if( kFALSE == ProcessMs( ts, uMsCompIdx, fuMsIndex ) )
253 } // for( UInt_t uMsCompIdx = 0; uMsCompIdx < fvMsComponentsList.size(); ++uMsCompIdx )
254
257 } // for( fuMsIndex = 0; fuMsIndex < uNbMsLoop; fuMsIndex ++ )
258
259 return kTRUE;
260}
261
262Bool_t CbmMcbm2018MonitorAlgoTofPulser::ProcessMs(const fles::Timeslice& ts, size_t uMsCompIdx, size_t uMsIdx)
263{
264 auto msDescriptor = ts.descriptor(uMsCompIdx, uMsIdx);
265 fuCurrentEquipmentId = msDescriptor.eq_id;
266 const uint8_t* msContent = reinterpret_cast<const uint8_t*>(ts.content(uMsCompIdx, uMsIdx));
267
268 uint32_t uSize = msDescriptor.size;
269 fulCurrentMsIdx = msDescriptor.idx;
270 fuCurrentMsSysId = static_cast<uint32_t>(msDescriptor.sys_id);
271 fdMsTime = (1e-9) * static_cast<double>(fulCurrentMsIdx);
272 LOG(debug) << "Microslice: " << fulCurrentMsIdx << " from EqId " << std::hex << fuCurrentEquipmentId << std::dec
273 << " has size: " << uSize;
274
275 if (-1.0 == fdStartTime) fdStartTime = fdMsTime;
276
277 if (0 == fvbMaskedComponents.size()) fvbMaskedComponents.resize(ts.num_components(), kFALSE);
278
279 fuCurrDpbId = static_cast<uint32_t>(fuCurrentEquipmentId & 0xFFFF);
280 // fuCurrDpbIdx = fDpbIdIndexMap[ fuCurrDpbId ];
281
283 auto it = fGdpbIdIndexMap.find(fuCurrDpbId);
284 if (it == fGdpbIdIndexMap.end()) {
285 if (kFALSE == fvbMaskedComponents[uMsCompIdx]) {
286 LOG(info) << "---------------------------------------------------------------";
287 LOG(info) << FormatMsHeaderPrintout(msDescriptor);
288 LOG(warning) << "Could not find the gDPB index for AFCK id 0x" << std::hex << fuCurrDpbId << std::dec
289 << " in timeslice " << fulCurrentTsIdx << " in microslice " << uMsIdx << " component " << uMsCompIdx
290 << "\n"
291 << "If valid this index has to be added in the TOF "
292 "parameter file in the DbpIdArray field";
293 fvbMaskedComponents[uMsCompIdx] = kTRUE;
294 } // if( kFALSE == fvbMaskedComponents[ uMsComp ] )
295 else
296 return kTRUE;
297
300
301 return kFALSE;
302 } // if( it == fGdpbIdIndexMap.end() )
303 else
305
306 // If not integer number of message in input buffer, print warning/error
307 if (0 != (uSize % kuBytesPerMessage))
308 LOG(error) << "The input microslice buffer does NOT "
309 << "contain only complete nDPB messages!";
310
311 // Compute the number of complete messages in the input microslice buffer
312 uint32_t uNbMessages = (uSize - (uSize % kuBytesPerMessage)) / kuBytesPerMessage;
313
314 // Prepare variables for the loop on contents
315 Int_t messageType = -111;
316 const uint64_t* pInBuff = reinterpret_cast<const uint64_t*>(msContent);
317 for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx++) {
318 // Fill message
319 uint64_t ulData = static_cast<uint64_t>(pInBuff[uIdx]);
320
322 if (0 == uIdx) {
323 ProcessEpochCycle(ulData);
324 continue;
325 } // if( 0 == uIdx )
326
327 gdpbv100::Message mess(ulData);
329 messageType = mess.getMessageType();
330
333 if (0x90 == fuCurrentMsSysId) fuGet4Id = mess.getGdpbGenChipId();
335
337 LOG(warning) << "Message with Get4 ID too high: " << fuGet4Id << " VS " << fuNrOfGet4PerGdpb
338 << " set in parameters.";
339
340 switch (messageType) {
341 case gdpbv100::MSG_HIT: {
342 if (mess.getGdpbHitIs24b()) {
344 LOG(fatal) << "This monitor does not support 24b hit messages!!!.";
345 continue;
346 } // if( getGdpbHitIs24b() )
347 else {
348 fvmEpSupprBuffer.push_back(mess);
349 } // else of if( getGdpbHitIs24b() )
350 break;
351 } // case gdpbv100::MSG_HIT:
352 case gdpbv100::MSG_EPOCH: {
354 ProcessEpoch(mess);
355 } // if this epoch message is a merged one valid for all chips
356 else {
358 LOG(fatal) << "This event builder does not support unmerged epoch "
359 "messages!!!.";
360 continue;
361 } // if single chip epoch message
362 break;
363 } // case gdpbv100::MSG_EPOCH:
371 break;
372 } // case not hit or epoch
373 default:
374 LOG(fatal) << "Message type " << std::hex << std::setw(2) << static_cast<uint16_t>(messageType)
375 << " not included in Get4 data format.";
376 } // switch( mess.getMessageType() )
377 } // for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx ++)
378
379 return kTRUE;
380}
381
382// -------------------------------------------------------------------------
384{
385 ULong64_t ulEpochCycleVal = ulCycleData & gdpbv100::kulEpochCycleFieldSz;
386
387 if (!(ulEpochCycleVal == fvulCurrentEpochCycle[fuCurrDpbIdx]
388 || ulEpochCycleVal == fvulCurrentEpochCycle[fuCurrDpbIdx] + 1)
389 && 0 < fulCurrentMsIdx) {
390 LOG(warning) << "CbmMcbm2018MonitorAlgoTofPulser::ProcessEpochCycle => "
391 << " Missmatch in epoch cycles detected for Gdpb " << fuCurrDpbIdx
392 << ", probably fake cycles due to epoch index corruption! "
393 << Form(" Current cycle 0x%09llX New cycle 0x%09llX", fvulCurrentEpochCycle[fuCurrDpbIdx],
394 ulEpochCycleVal);
395 } // if epoch cycle did not stay constant or increase by exactly 1, except if first MS of the TS
396 if (ulEpochCycleVal != fvulCurrentEpochCycle[fuCurrDpbIdx]) {
397 LOG(info) << "CbmMcbm2018MonitorAlgoTofPulser::ProcessEpochCycle => "
398 << " New epoch cycle for Gdpb " << fuCurrDpbIdx
399 << Form(": Current cycle 0x%09llX New cycle 0x%09llX", fvulCurrentEpochCycle[fuCurrDpbIdx],
400 ulEpochCycleVal);
401 } // if( ulEpochCycleVal != fvulCurrentEpochCycle[fuCurrDpbIdx] )
402 fvulCurrentEpochCycle[fuCurrDpbIdx] = ulEpochCycleVal;
403
404 return;
405}
407{
408 ULong64_t ulEpochNr = mess.getGdpbEpEpochNb();
409 /*
410 Bool_t bSyncFlag = ( 1 == mess.getGdpbEpSync() );
411 Bool_t bDataLoss = ( 1 == mess.getGdpbEpDataLoss() );
412 Bool_t bEpochLoss = ( 1 == mess.getGdpbEpEpochLoss() );
413 Bool_t bMissmMatch = ( 1 == mess.getGdpbEpMissmatch() );
414*/
415 fvulCurrentEpoch[fuCurrDpbIdx] = ulEpochNr;
418
421}
422// -------------------------------------------------------------------------
424{
425 Int_t iBufferSize = fvmEpSupprBuffer.size();
426
427 if (0 == iBufferSize) return;
428
429 LOG(debug) << "Now processing stored messages for for gDPB " << fuCurrDpbIdx << " with epoch number "
431
434 std::stable_sort(fvmEpSupprBuffer.begin(), fvmEpSupprBuffer.end());
435
437 ULong64_t ulCurEpochGdpbGet4 = fvulCurrentEpochFull[fuCurrDpbIdx];
438
440 if (0 == ulCurEpochGdpbGet4) return;
441
443 ulCurEpochGdpbGet4--;
444
445 Int_t messageType = -111;
446 for (Int_t iMsgIdx = 0; iMsgIdx < iBufferSize; iMsgIdx++) {
447 messageType = fvmEpSupprBuffer[iMsgIdx].getMessageType();
448
449 fuGet4Id = fUnpackPar->ElinkIdxToGet4Idx(fvmEpSupprBuffer[iMsgIdx].getGdpbGenChipId());
451 if (0x90 == fuCurrentMsSysId) fuGet4Id = fvmEpSupprBuffer[iMsgIdx].getGdpbGenChipId();
453
455 gdpbv100::FullMessage fullMess(fvmEpSupprBuffer[iMsgIdx], ulCurEpochGdpbGet4);
456
458 switch (messageType) {
459 case gdpbv100::MSG_HIT: {
460 ProcessHit(fullMess);
461 break;
462 } // case gdpbv100::MSG_HIT:
471 break;
472 default:
473 LOG(error) << "Message type " << std::hex << std::setw(2) << static_cast<uint16_t>(messageType)
474 << " not included in Get4 unpacker.";
475 } // switch( mess.getMessageType() )
476 } // for( Int_t iMsgIdx = 0; iMsgIdx < iBufferSize; iMsgIdx++ )
477
478 fvmEpSupprBuffer.clear();
479}
480// -------------------------------------------------------------------------
482{
483 UInt_t uChannel = mess.getGdpbHitChanId();
484 UInt_t uTot = mess.getGdpbHit32Tot();
485
489 // UInt_t uFts = mess.getGdpbHitFullTs() % 112;
490 // UInt_t uCts = mess.getGdpbHitFullTs() / 112;
491
492 // UInt_t uChannelNr = fuGet4Id * fuNrOfChannelsPerGet4 + uChannel;
493 UInt_t uChannelNrInFee = (fuGet4Id % fuNrOfGet4PerFee) * fuNrOfChannelsPerGet4 + uChannel;
494 UInt_t uFeeNr = (fuGet4Id / fuNrOfGet4PerFee);
495 // UInt_t uFeeNrInSys = fuCurrDpbIdx * fuNrOfFeePerGdpb + uFeeNr;
496 // UInt_t uRemappedChannelNr = uFeeNr * fuNrOfChannelsPerFee + fUnpackPar->Get4ChanToPadiChan( uChannelNrInFee );
497 UInt_t uRemappedChanNrInFee = fUnpackPar->Get4ChanToPadiChan(uChannelNrInFee);
498 // UInt_t uGbtxNr = (uFeeNr / fUnpackPar->GetNrOfFeePerGbtx());
499 // UInt_t uFeeInGbtx = (uFeeNr % fUnpackPar->GetNrOfFeePerGbtx());
500 // UInt_t uGbtxNrInSys = fuCurrDpbIdx * fUnpackPar->GetNrOfGbtxPerGdpb() + uGbtxNr;
501
502 // UInt_t uChanInSyst = fuCurrDpbIdx * fuNrOfChannelsPerGdpb + uChannelNr;
503 // UInt_t uRemappedChannelNrInSys = fuCurrDpbIdx * fuNrOfChannelsPerGdpb
504 // + uFeeNr * fuNrOfChannelsPerFee
505 // + fUnpackPar->Get4ChanToPadiChan( uChannelNrInFee );
506
507 // ULong_t ulHitTime = mess.getMsgFullTime( mess.getExtendedEpoch() );
508 Double_t dHitTime = mess.GetFullTimeNs();
509 // Double_t dHitTot = uTot; // in bins
510
512 if (0x90 == fuCurrentMsSysId) {
513 if ((0 == fuGet4Id / 2) && (185 < uTot && uTot < 190)) {
514 fvvbFeeHitFound[fuCurrDpbIdx][uFeeNr] = kTRUE;
515 fvvdFeeHits[fuCurrDpbIdx][uFeeNr] = dHitTime;
516 } // if( ( 0 == fuGet4Id / 2 ) && ( 185 < uTot && uTot < 190 ) )
517 } // if( 0x90 == fuCurrentMsSysId )
518 else if (fuPulserChannel == uRemappedChanNrInFee && fuPulserMinTot < uTot && uTot < fuPulserMaxTot) {
519 fvvbFeeHitFound[fuCurrDpbIdx][uFeeNr] = kTRUE;
520 fvvdFeeHits[fuCurrDpbIdx][uFeeNr] = dHitTime;
521 } // if( fuPulserChannel == uRemappedChanNrInFee && fuPulserMinTot < uTot && uTot < fuPulserMaxTot )
522}
523// -------------------------------------------------------------------------
524
526{
527 std::string sFolder = "mTofMoni";
528
529 LOG(info) << "create Histos for mTof monitoring ";
530
531 /*******************************************************************/
532 UInt_t uNbBinsDt = kuNbBinsDt + 1; // To account for extra bin due to shift by 1/2 bin of both ranges
535
536 std::cout << " Bin size " << gdpbv100::kdBinSize << std::endl;
537 std::cout << " Epo bins " << gdpbv100::kuEpochInBins << std::endl;
538 std::cout << " Epo size " << gdpbv100::kdEpochInPs << std::endl;
539 std::cout << " Epo size " << gdpbv100::kdEpochInNs << std::endl;
540 /*******************************************************************/
542 /* clang-format off */
545 for (UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; ++uFeeA) {
546 UInt_t uGdpbA = uFeeA / (fuNrOfFeePerGdpb);
547 if (-1 != fiGdpbIndex) uGdpbA = fiGdpbIndex;
549 UInt_t uFeeIndexA = uFeeA;
550 // UInt_t uFeeIdA = uFeeA - ( fuNrOfFeePerGdpb * uGdpbA );
551 UInt_t uFeeIdA = uFeeIndexA - (3 * 6 * uGdpbA);
552
554 for (UInt_t uFeeB = 0; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; ++uFeeB) {
555
556 if (uFeeA < uFeeB) {
558 UInt_t uFeeIndexB = uFeeB;
559
560 UInt_t uGdpbB = uFeeB / (fuNrOfFeePerGdpb);
561 if (-1 != fiGdpbIndex) uGdpbB = fiGdpbIndex;
562 // UInt_t uFeeIdB = uFeeB - ( fuNrOfFeePerGdpb * uGdpbB );
563 UInt_t uFeeIdB = uFeeIndexB - (3 * 6 * uGdpbB);
564 fvvhFeePairPulserTimeDiff[ uFeeA ][ uFeeB ] = new TH1I(
565 Form("hFeePairPulserTimeDiff_s%02u_f%1u_s%02u_f%1u", uGdpbA, uFeeIdA, uGdpbB, uFeeIdB),
566 Form("Time difference for pulser on gDPB %02u FEE %1u and gDPB %02u FEE %1u; DeltaT [ps]; Counts",
567 uGdpbA, uFeeIdA, uGdpbB, uFeeIdB ),
568 uNbBinsDt, dMinDt, dMaxDt);
569
571 Form("TofDt/s%03u", uFeeIndexA));
572 } // if( uFeeA < uFeeB )
573 else
574 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB] = NULL;
575 } // for( UInt_t uFeeB = 0; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; ++uFeeB )
576 } // for( UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; ++uFeeA )
577
579 UInt_t uTotalNbFee = fuNrOfFeePerGdpb * fuNrOfGdpbs;
580 // Double_t dGdpbMin = -0.5;
581 // Double_t dGdpbMax = fuNrOfGdpbs;
582 fhPulserTimeDiffMean = new TH2D( "hPulserTimeDiffMean",
583 "Time difference Mean for each FEE pairs; FEE A; FEE B ; Mean [ps]",
584 uTotalNbFee - 1, -0.5, uTotalNbFee - 1.5,
585 uTotalNbFee - 1, 0.5, uTotalNbFee - 0.5 );
586
587 fhPulserTimeDiffRms = new TH2D( "hPulserTimeDiffRms",
588 "Time difference RMS for each FEE pairs; FEE A; FEE B ; RMS [ps]",
589 uTotalNbFee - 1, -0.5, uTotalNbFee - 1.5,
590 uTotalNbFee - 1, 0.5, uTotalNbFee - 0.5 );
591
592 fhPulserTimeDiffRmsZoom = new TH2D( "hPulserTimeDiffRmsZoom",
593 "Time difference RMS for each FEE pairs after zoom on peak; FEE A; FEE B ; RMS [ps]",
594 uTotalNbFee - 1, -0.5, uTotalNbFee - 1.5,
595 uTotalNbFee - 1, 0.5, uTotalNbFee - 0.5 );
596
597
598 fhPulserRmsGdpbToRefEvo = new TH2D( "hPulserRmsGdpbToRefEvo",
599 "Evo. of Time difference RMS for selected FEE of each gDPb to the 1st; Time in run [s] A; gDPB ; RMS [ps]",
601 fuNrOfGdpbs - 1, 0.5, fuNrOfGdpbs - 0.5 );
602
603 fhPulserRmsGbtxToRefEvo = new TH2D( "hPulserTimeDiffRmsZoom",
604 "Evo. of Time difference RMS for selected FEE pairs of each GBTx to the 1st in same gDPB; Time in run [s] A; FEE ; RMS [ps]",
606 uTotalNbFee - 1, 0.5, uTotalNbFee - 0.5 );
608 /* clang-format on */
609
614 /*******************************************************************/
615
616 /*******************************************************************/
619 fcSummary = new TCanvas("cSummary", "Pulser Monitoring Summary");
620 fcSummary->Divide(3);
621
622 fcSummary->cd(1);
623 gPad->SetGridx();
624 gPad->SetGridy();
625 fhPulserTimeDiffMean->Draw("colz");
626
627 fcSummary->cd(2);
628 gPad->SetGridx();
629 gPad->SetGridy();
630 fhPulserTimeDiffRms->Draw("colz");
631
632 fcSummary->cd(3);
633 gPad->SetGridx();
634 gPad->SetGridy();
635 fhPulserTimeDiffRmsZoom->Draw("colz");
636
637 AddCanvasToVector(fcSummary, "canvases");
639 /*******************************************************************/
640
641 return kTRUE;
642}
644{
645 for (UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++) {
646 UInt_t uGdpbA = uFeeA / (fuNrOfFeePerGdpb);
647 UInt_t uFeeIdA = uFeeA - (fuNrOfFeePerGdpb * uGdpbA);
648
650 if (kFALSE == fvvbFeeHitFound[uGdpbA][uFeeIdA]) continue;
651
652 for (UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++) {
653 UInt_t uGdpbB = uFeeB / (fuNrOfFeePerGdpb);
654 UInt_t uFeeIdB = uFeeB - (fuNrOfFeePerGdpb * uGdpbB);
655
657 if (kFALSE == fvvbFeeHitFound[uGdpbB][uFeeIdB]) continue;
658
659 Double_t dTimeDiff = 1e3 * (fvvdFeeHits[uGdpbB][uFeeIdB] - fvvdFeeHits[uGdpbA][uFeeIdA]);
660 if (TMath::Abs(dTimeDiff) < kdMaxDtPulserPs) {
661 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Fill(dTimeDiff);
662 } // if( TMath::Abs( dTimeDiff ) < kdMaxDtPulserPs )
663 } // for( UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++)
664
666 fvvbFeeHitFound[uGdpbA][uFeeIdA] = kFALSE;
667 } // for( UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++)
668
672 LOG(info) << Form("Reseting stats histos for update on TS %5llu MS %3u", fulCurrentTsIdx, fuMsIndex);
673 fhPulserTimeDiffMean->Reset();
674 fhPulserTimeDiffRms->Reset();
676
677 for (UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++) {
678 for (UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++) {
679 if (0 == fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetEntries()) continue;
680
682 UInt_t uFeeIndexA = uFeeA;
683 UInt_t uFeeIndexB = uFeeB;
684 fhPulserTimeDiffMean->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetMean());
685 fhPulserTimeDiffRms->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetRMS());
686
688 Int_t iBinWithMax = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetMaximumBin();
689 Double_t dNbCounts = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Integral();
690
692 Double_t dPeakPos = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->GetBinCenter(iBinWithMax);
693 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->SetRangeUser(dPeakPos - kdFitZoomWidthPs,
694 dPeakPos + kdFitZoomWidthPs);
695
697 Double_t dZoomCounts = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Integral();
698
700 if ((dZoomCounts / dNbCounts) < 0.8) {
701 fhPulserTimeDiffRmsZoom->Fill(uFeeIndexA, uFeeIndexB, 0.0);
702 // LOG(warning) << "CbmMcbm2018MonitorAlgoTofPulser::FillHistograms => Zoom too strong, "
703 // << "more than 20% loss for FEE pair " << uFeeA << " and " << uFeeB << " !!! ";
704 } // if( ( dZoomCounts / dNbCounts ) < 0.8 )
705 else
706 fhPulserTimeDiffRmsZoom->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetRMS());
707
709 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->UnZoom();
710 /*
711 LOG(info) << "Stats FEE A " << std::setw(3) << uFeeA
712 << " FEE B " << std::setw(3) << uFeeB
713 << Form( " %5.0f %f", fvvhFeePairPulserTimeDiff[ uFeeA ][ uFeeB ]->GetMean(),
714 fvvhFeePairPulserTimeDiff[ uFeeA ][ uFeeB ]->GetRMS() );
715*/
716 } // for( UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++)
717 } // for( UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++)
718 } // if( 1 == fulCurrentTsIdx % fuUpdateFreqTs && fuNbCoreMsPerTs - 1 == fuMsIndex )
719
720 return kTRUE;
721}
723{
724 LOG(info) << Form("Reseting stats histos for final update on TS %5llu MS %3u", fulCurrentTsIdx, fuMsIndex);
725 fhPulserTimeDiffMean->Reset();
726 fhPulserTimeDiffRms->Reset();
728
729 for (UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++) {
730 for (UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++) {
731 if (nullptr == fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]) continue;
732
733 if (0 == fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetEntries()) continue;
734
736 UInt_t uFeeIndexA = uFeeA;
737 UInt_t uFeeIndexB = uFeeB;
738 fhPulserTimeDiffMean->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetMean());
739 fhPulserTimeDiffRms->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetRMS());
740
742 Int_t iBinWithMax = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetMaximumBin();
743 Double_t dNbCounts = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Integral();
744
746 Double_t dPeakPos = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->GetBinCenter(iBinWithMax);
747 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->SetRangeUser(dPeakPos - kdFitZoomWidthPs,
748 dPeakPos + kdFitZoomWidthPs);
749
751 Double_t dZoomCounts = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Integral();
752
754 if ((dZoomCounts / dNbCounts) < 0.8) {
755 fhPulserTimeDiffRmsZoom->Fill(uFeeIndexA, uFeeIndexB, 0.0);
756 LOG(warning) << "CbmMcbm2018MonitorAlgoTofPulser::FillHistograms => "
757 "Zoom too strong, "
758 << "more than 20% loss for FEE pair " << uFeeA << " and " << uFeeB << " !!! ";
759 continue;
760 } // if( ( dZoomCounts / dNbCounts ) < 0.8 )
761 else
762 fhPulserTimeDiffRmsZoom->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetRMS());
763
764
766 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->UnZoom();
767
768 LOG(info) << "Stats FEE A " << std::setw(3) << uFeeIndexA << " FEE B " << std::setw(3) << uFeeIndexB
769 << Form(" %5.0f %f", fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetMean(),
770 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetRMS());
771
772 } // for( UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++)
773 } // for( UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++)
774
775 return kTRUE;
776}
778{
779 LOG(info) << Form("Reseting stats histos on TS %5llu MS %3u", fulCurrentTsIdx, fuMsIndex);
780 for (UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++) {
781 for (UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++) {
782 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Reset();
783 } // for( UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++)
784 } // for( UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++)
785 fhPulserTimeDiffMean->Reset();
786 fhPulserTimeDiffRms->Reset();
788
789 fdStartTime = -1.0;
790
791 return kTRUE;
792}
793// -------------------------------------------------------------------------
std::string FormatMsHeaderPrintout(const fles::MicrosliceDescriptor &msDescriptor)
std::vector< std::vector< Double_t > > fvvdFeeHits
[ gDPB ][ FEE ]
UInt_t fuGet4Nr
running number (0 to fuNrOfGet4PerGdpb) of the Get4 chip of a unique GDPB for current message
std::vector< Bool_t > fvbMaskedComponents
Control flags.
UInt_t fuGet4Id
Index of the DPB from which the MS currently unpacked is coming.
UInt_t fuNrOfChannelsPerFee
Number of channels in each GET4.
std::vector< std::vector< TH1 * > > fvvhFeePairPulserTimeDiff
Size in seconds of the evolution histograms.
CbmMcbm2018TofPar * fUnpackPar
Settings from parameter file.
std::map< UInt_t, UInt_t > fGdpbIdIndexMap
Total number of GDPBs in the system.
std::vector< gdpbv100::Message > fvmEpSupprBuffer
Epoch + Epoch Cycle.
UInt_t fuNrOfChannelsPerGet4
Number of GET4s per FEE.
std::vector< ULong64_t > fvulCurrentEpochFull
Epoch cycle from the Ms Start message and Epoch counter flip.
UInt_t fuNrOfGet4PerFee
Number of FEBs per GDPB.
Bool_t ProcessMs(const fles::Timeslice &ts, size_t uMsCompIdx, size_t uMsIdx)
UInt_t fuCurrDpbIdx
Temp holder until Current equipment ID is properly filled in MS.
UInt_t fuPulserMinTot
Number of channels per GDPB.
std::vector< ULong64_t > fvulCurrentEpoch
Data format control: Current time references for each GDPB: merged epoch marker, epoch cycle,...
Bool_t ProcessTs(const fles::Timeslice &ts)
UInt_t fuCurrDpbId
Current equipment ID, tells from which DPB the current MS is originating.
Double_t fdTsStopTimeCore
Time in ns of current TS from the index of the first MS first component.
std::vector< ULong64_t > fvulCurrentEpochCycle
Current epoch index, per DPB.
Double_t fdStartTime
Starting time and time evolution book-keeping.
UInt_t fuNrOfGet4PerGdpb
Total number of Get4 chips in the system.
void AddMsComponentToList(size_t component, UShort_t usDetectorId)
Double_t fdTsStartTime
SysId of the current MS in TS (0 to fuTotalMsNb)
UInt_t fuNrOfGet4
Number of channels in each FEE.
UInt_t fuMsIndex
Start Time in ns of current MS from its index field in header.
Double_t fdMsTime
End Time in ns of current TS Core from the index of the first MS first component.
UInt_t fuNrOfChannelsPerGdpb
Number of GET4s per GDPB.
std::vector< std::vector< Bool_t > > fvvbFeeHitFound
Storing the time of the last hit for each MS in each of the FEE.
static constexpr UInt_t GetNrOfFeePerGdpb()
Int_t GetNrOfGdpbs()
FIXME: replace with method returning the correspondign constants! see Star2019 parameter.
Int_t GetGdpbId(Int_t i)
Int_t Get4ChanToPadiChan(UInt_t uChannelInFee)
Int_t ElinkIdxToGet4Idx(UInt_t uElink)
void AddHistoToVector(TNamed *pointer, std::string sFolder="")
std::vector< size_t > fvMsComponentsList
void AddCanvasToVector(TCanvas *pointer, std::string sFolder="")
double GetFullTimeNs() const
uint16_t getGdpbHitIs24b() const
uint32_t getGdpbEpEpochNb() const
uint16_t getGdpbHit32Tot() const
bool isStarTrigger() const
Returns true is message type is MSG_STAR_TRI_A, _B, _C, _D (STAR Trigger message)
uint16_t getGdpbGenChipId() const
uint8_t getMessageType() const
Returns the message type. Valid for all message types. 4 bit.
uint16_t getGdpbHitChanId() const
const double kdBinSize
const double kdEpochInPs
const uint32_t kuChipIdMergedEpoch
const uint32_t kuEpochCounterSz
const double kdEpochInNs
const uint64_t kulEpochCycleFieldSz
const uint32_t kuEpochInBins