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#include "FairRootManager.h"
17#include "FairRun.h"
18#include "FairRunOnline.h"
19#include "FairRuntimeDb.h"
20#include "TCanvas.h"
21#include "TH1.h"
22#include "TH2.h"
23#include "TList.h"
24#include "TPaveStats.h"
25#include "TProfile.h"
26#include "TROOT.h"
27#include "TString.h"
28
29#include <Logger.h>
30
31#include <cstdint>
32#include <fstream>
33#include <iomanip>
34#include <iostream>
35
36// -------------------------------------------------------------------------
91
92// -------------------------------------------------------------------------
94{
95 LOG(info) << "Initializing mCBM T0 2019 monitor algo";
96
97 return kTRUE;
98}
106
107// -------------------------------------------------------------------------
109{
110 LOG(info) << "Init parameter containers for CbmMcbm2018MonitorAlgoTofPulser";
111 Bool_t initOK = ReInitContainers();
112
113 return initOK;
114}
116{
117 LOG(info) << "**********************************************";
118 LOG(info) << "ReInit parameter containers for CbmMcbm2018MonitorAlgoTofPulser";
119
120 fUnpackPar = (CbmMcbm2018TofPar*) fParCList->FindObject("CbmMcbm2018TofPar");
121 if (nullptr == fUnpackPar) return kFALSE;
122
123 Bool_t initOK = InitParameters();
124
125 return initOK;
126}
128{
129 if (nullptr == fParCList) fParCList = new TList();
130 fUnpackPar = new CbmMcbm2018TofPar("CbmMcbm2018TofPar");
131 fParCList->Add(fUnpackPar);
132
133 return fParCList;
134}
136{
137
138 fuNrOfGdpbs = fUnpackPar->GetNrOfGdpbs();
139 LOG(info) << "Nr. of Tof GDPBs: " << fuNrOfGdpbs;
140
141 fuNrOfFeePerGdpb = fUnpackPar->GetNrOfFeePerGdpb();
142 LOG(info) << "Nr. of FEES per Tof GDPB: " << fuNrOfFeePerGdpb;
143
144 fuNrOfGet4PerFee = fUnpackPar->GetNrOfGet4PerFee();
145 LOG(info) << "Nr. of GET4 per Tof FEE: " << fuNrOfGet4PerFee;
146
147 fuNrOfChannelsPerGet4 = fUnpackPar->GetNrOfChannelsPerGet4();
148 LOG(info) << "Nr. of channels per GET4: " << fuNrOfChannelsPerGet4;
149
151 LOG(info) << "Nr. of channels per FEE: " << fuNrOfChannelsPerFee;
152
154 LOG(info) << "Nr. of GET4s: " << fuNrOfGet4;
155
157 LOG(info) << "Nr. of GET4s per GDPB: " << fuNrOfGet4PerGdpb;
158
160 LOG(info) << "Nr. of channels per GDPB: " << fuNrOfChannelsPerGdpb;
161
162 fGdpbIdIndexMap.clear();
163 for (UInt_t i = 0; i < fuNrOfGdpbs; ++i) {
164 fGdpbIdIndexMap[fUnpackPar->GetGdpbId(i)] = i;
165 LOG(info) << "GDPB Id of TOF " << i << " : " << std::hex << fUnpackPar->GetGdpbId(i) << std::dec;
166 } // for( UInt_t i = 0; i < fuNrOfGdpbs; ++i )
167
169 fdMsSizeInNs = fUnpackPar->GetSizeMsInNs();
170 LOG(info) << "Timeslice parameters: each MS is " << fdMsSizeInNs << " ns";
171
173 if (-1 < fiGdpbIndex) {
174 if (fuNrOfGdpbs <= static_cast<UInt_t>(fiGdpbIndex))
175 LOG(fatal) << "Selected gDPB out of bounds relative to parameter file: " << fiGdpbIndex << " VS " << fuNrOfGdpbs;
176 else
177 LOG(info) << "Selected gDPB " << fiGdpbIndex << " for single gDPB analysis";
178 fuNrOfGdpbs = 1;
179 fGdpbIdIndexMap.clear();
180 fGdpbIdIndexMap[fUnpackPar->GetGdpbId(fiGdpbIndex)] = 0;
181 } // if( -1 < fiGdpbIndex )
182
184 fvulCurrentEpoch.resize(fuNrOfGdpbs, 0);
188 fvvdFeeHits.resize(fuNrOfGdpbs);
189 for (UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; ++uGdpb) {
190 fvvbFeeHitFound[uGdpb].resize(fuNrOfFeePerGdpb, kFALSE);
191 fvvdFeeHits[uGdpb].resize(fuNrOfFeePerGdpb, 0.0);
192 } // for( UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; ++uGdpb )
193
194
195 return kTRUE;
196}
197// -------------------------------------------------------------------------
198
199void CbmMcbm2018MonitorAlgoTofPulser::AddMsComponentToList(size_t component, UShort_t usDetectorId)
200{
202 for (UInt_t uCompIdx = 0; uCompIdx < fvMsComponentsList.size(); ++uCompIdx)
203 if (component == fvMsComponentsList[uCompIdx]) return;
204
206 fvMsComponentsList.push_back(component);
207
208 LOG(info) << "CbmMcbm2018MonitorAlgoTofPulser::AddMsComponentToList => Component " << component
209 << " with detector ID 0x" << std::hex << usDetectorId << std::dec << " added to list";
210}
211// -------------------------------------------------------------------------
212
214{
215 fulCurrentTsIdx = ts.index();
216 fdTsStartTime = static_cast<Double_t>(ts.descriptor(0, 0).idx);
217
219 if (0 == fulCurrentTsIdx) return kTRUE;
220
222 if (-1.0 == fdTsCoreSizeInNs) {
223 fuNbCoreMsPerTs = ts.num_core_microslices();
224 fuNbOverMsPerTs = ts.num_microslices(0) - ts.num_core_microslices();
227 LOG(info) << "Timeslice parameters: each TS has " << fuNbCoreMsPerTs << " Core MS and " << fuNbOverMsPerTs
228 << " Overlap MS, for a core duration of " << fdTsCoreSizeInNs << " ns and a full duration of "
229 << fdTsFullSizeInNs << " ns";
230
234 LOG(info) << "In each TS " << fuNbMsLoop << " MS will be looped over";
235 } // if( -1.0 == fdTsCoreSizeInNs )
236
239 // LOG(info) << Form( "TS %5d Start %12f Stop %12f", fulCurrentTsIdx, fdTsStartTime, fdTsStopTimeCore );
240
242 for (fuMsIndex = 0; fuMsIndex < fuNbMsLoop; fuMsIndex++) {
244 for (UInt_t uMsCompIdx = 0; uMsCompIdx < fvMsComponentsList.size(); ++uMsCompIdx) {
245 UInt_t uMsComp = fvMsComponentsList[uMsCompIdx];
246
247 if (kFALSE == ProcessMs(ts, uMsComp, fuMsIndex)) {
248 LOG(error) << "Failed to process ts " << fulCurrentTsIdx << " MS " << fuMsIndex << " for component " << uMsComp;
249 return kFALSE;
250 } // if( kFALSE == ProcessMs( ts, uMsCompIdx, fuMsIndex ) )
251 } // for( UInt_t uMsCompIdx = 0; uMsCompIdx < fvMsComponentsList.size(); ++uMsCompIdx )
252
255 } // for( fuMsIndex = 0; fuMsIndex < uNbMsLoop; fuMsIndex ++ )
256
257 return kTRUE;
258}
259
260Bool_t CbmMcbm2018MonitorAlgoTofPulser::ProcessMs(const fles::Timeslice& ts, size_t uMsCompIdx, size_t uMsIdx)
261{
262 auto msDescriptor = ts.descriptor(uMsCompIdx, uMsIdx);
263 fuCurrentEquipmentId = msDescriptor.eq_id;
264 const uint8_t* msContent = reinterpret_cast<const uint8_t*>(ts.content(uMsCompIdx, uMsIdx));
265
266 uint32_t uSize = msDescriptor.size;
267 fulCurrentMsIdx = msDescriptor.idx;
268 fuCurrentMsSysId = static_cast<uint32_t>(msDescriptor.sys_id);
269 fdMsTime = (1e-9) * static_cast<double>(fulCurrentMsIdx);
270 LOG(debug) << "Microslice: " << fulCurrentMsIdx << " from EqId " << std::hex << fuCurrentEquipmentId << std::dec
271 << " has size: " << uSize;
272
273 if (-1.0 == fdStartTime) fdStartTime = fdMsTime;
274
275 if (0 == fvbMaskedComponents.size()) fvbMaskedComponents.resize(ts.num_components(), kFALSE);
276
277 fuCurrDpbId = static_cast<uint32_t>(fuCurrentEquipmentId & 0xFFFF);
278 // fuCurrDpbIdx = fDpbIdIndexMap[ fuCurrDpbId ];
279
281 auto it = fGdpbIdIndexMap.find(fuCurrDpbId);
282 if (it == fGdpbIdIndexMap.end()) {
283 if (kFALSE == fvbMaskedComponents[uMsCompIdx]) {
284 LOG(info) << "---------------------------------------------------------------";
285 LOG(info) << FormatMsHeaderPrintout(msDescriptor);
286 LOG(warning) << "Could not find the gDPB index for AFCK id 0x" << std::hex << fuCurrDpbId << std::dec
287 << " in timeslice " << fulCurrentTsIdx << " in microslice " << uMsIdx << " component " << uMsCompIdx
288 << "\n"
289 << "If valid this index has to be added in the TOF "
290 "parameter file in the DbpIdArray field";
291 fvbMaskedComponents[uMsCompIdx] = kTRUE;
292 } // if( kFALSE == fvbMaskedComponents[ uMsComp ] )
293 else
294 return kTRUE;
295
298
299 return kFALSE;
300 } // if( it == fGdpbIdIndexMap.end() )
301 else
303
304 // If not integer number of message in input buffer, print warning/error
305 if (0 != (uSize % kuBytesPerMessage))
306 LOG(error) << "The input microslice buffer does NOT "
307 << "contain only complete nDPB messages!";
308
309 // Compute the number of complete messages in the input microslice buffer
310 uint32_t uNbMessages = (uSize - (uSize % kuBytesPerMessage)) / kuBytesPerMessage;
311
312 // Prepare variables for the loop on contents
313 Int_t messageType = -111;
314 const uint64_t* pInBuff = reinterpret_cast<const uint64_t*>(msContent);
315 for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx++) {
316 // Fill message
317 uint64_t ulData = static_cast<uint64_t>(pInBuff[uIdx]);
318
320 if (0 == uIdx) {
321 ProcessEpochCycle(ulData);
322 continue;
323 } // if( 0 == uIdx )
324
325 gdpbv100::Message mess(ulData);
327 messageType = mess.getMessageType();
328
329 fuGet4Id = fUnpackPar->ElinkIdxToGet4Idx(mess.getGdpbGenChipId());
331 if (0x90 == fuCurrentMsSysId) fuGet4Id = mess.getGdpbGenChipId();
333
335 LOG(warning) << "Message with Get4 ID too high: " << fuGet4Id << " VS " << fuNrOfGet4PerGdpb
336 << " set in parameters.";
337
338 switch (messageType) {
339 case gdpbv100::MSG_HIT: {
340 if (mess.getGdpbHitIs24b()) {
342 LOG(fatal) << "This monitor does not support 24b hit messages!!!.";
343 continue;
344 } // if( getGdpbHitIs24b() )
345 else {
346 fvmEpSupprBuffer.push_back(mess);
347 } // else of if( getGdpbHitIs24b() )
348 break;
349 } // case gdpbv100::MSG_HIT:
350 case gdpbv100::MSG_EPOCH: {
352 ProcessEpoch(mess);
353 } // if this epoch message is a merged one valid for all chips
354 else {
356 LOG(fatal) << "This event builder does not support unmerged epoch "
357 "messages!!!.";
358 continue;
359 } // if single chip epoch message
360 break;
361 } // case gdpbv100::MSG_EPOCH:
369 break;
370 } // case not hit or epoch
371 default:
372 LOG(fatal) << "Message type " << std::hex << std::setw(2) << static_cast<uint16_t>(messageType)
373 << " not included in Get4 data format.";
374 } // switch( mess.getMessageType() )
375 } // for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx ++)
376
377 return kTRUE;
378}
379
380// -------------------------------------------------------------------------
382{
383 ULong64_t ulEpochCycleVal = ulCycleData & gdpbv100::kulEpochCycleFieldSz;
384
385 if (!(ulEpochCycleVal == fvulCurrentEpochCycle[fuCurrDpbIdx]
386 || ulEpochCycleVal == fvulCurrentEpochCycle[fuCurrDpbIdx] + 1)
387 && 0 < fulCurrentMsIdx) {
388 LOG(warning) << "CbmMcbm2018MonitorAlgoTofPulser::ProcessEpochCycle => "
389 << " Missmatch in epoch cycles detected for Gdpb " << fuCurrDpbIdx
390 << ", probably fake cycles due to epoch index corruption! "
391 << Form(" Current cycle 0x%09llX New cycle 0x%09llX", fvulCurrentEpochCycle[fuCurrDpbIdx],
392 ulEpochCycleVal);
393 } // if epoch cycle did not stay constant or increase by exactly 1, except if first MS of the TS
394 if (ulEpochCycleVal != fvulCurrentEpochCycle[fuCurrDpbIdx]) {
395 LOG(info) << "CbmMcbm2018MonitorAlgoTofPulser::ProcessEpochCycle => "
396 << " New epoch cycle for Gdpb " << fuCurrDpbIdx
397 << Form(": Current cycle 0x%09llX New cycle 0x%09llX", fvulCurrentEpochCycle[fuCurrDpbIdx],
398 ulEpochCycleVal);
399 } // if( ulEpochCycleVal != fvulCurrentEpochCycle[fuCurrDpbIdx] )
400 fvulCurrentEpochCycle[fuCurrDpbIdx] = ulEpochCycleVal;
401
402 return;
403}
405{
406 ULong64_t ulEpochNr = mess.getGdpbEpEpochNb();
407 /*
408 Bool_t bSyncFlag = ( 1 == mess.getGdpbEpSync() );
409 Bool_t bDataLoss = ( 1 == mess.getGdpbEpDataLoss() );
410 Bool_t bEpochLoss = ( 1 == mess.getGdpbEpEpochLoss() );
411 Bool_t bMissmMatch = ( 1 == mess.getGdpbEpMissmatch() );
412*/
413 fvulCurrentEpoch[fuCurrDpbIdx] = ulEpochNr;
416
419}
420// -------------------------------------------------------------------------
422{
423 Int_t iBufferSize = fvmEpSupprBuffer.size();
424
425 if (0 == iBufferSize) return;
426
427 LOG(debug) << "Now processing stored messages for for gDPB " << fuCurrDpbIdx << " with epoch number "
429
432 std::stable_sort(fvmEpSupprBuffer.begin(), fvmEpSupprBuffer.end());
433
435 ULong64_t ulCurEpochGdpbGet4 = fvulCurrentEpochFull[fuCurrDpbIdx];
436
438 if (0 == ulCurEpochGdpbGet4) return;
439
441 ulCurEpochGdpbGet4--;
442
443 Int_t messageType = -111;
444 for (Int_t iMsgIdx = 0; iMsgIdx < iBufferSize; iMsgIdx++) {
445 messageType = fvmEpSupprBuffer[iMsgIdx].getMessageType();
446
447 fuGet4Id = fUnpackPar->ElinkIdxToGet4Idx(fvmEpSupprBuffer[iMsgIdx].getGdpbGenChipId());
449 if (0x90 == fuCurrentMsSysId) fuGet4Id = fvmEpSupprBuffer[iMsgIdx].getGdpbGenChipId();
451
453 gdpbv100::FullMessage fullMess(fvmEpSupprBuffer[iMsgIdx], ulCurEpochGdpbGet4);
454
456 switch (messageType) {
457 case gdpbv100::MSG_HIT: {
458 ProcessHit(fullMess);
459 break;
460 } // case gdpbv100::MSG_HIT:
469 break;
470 default:
471 LOG(error) << "Message type " << std::hex << std::setw(2) << static_cast<uint16_t>(messageType)
472 << " not included in Get4 unpacker.";
473 } // switch( mess.getMessageType() )
474 } // for( Int_t iMsgIdx = 0; iMsgIdx < iBufferSize; iMsgIdx++ )
475
476 fvmEpSupprBuffer.clear();
477}
478// -------------------------------------------------------------------------
480{
481 UInt_t uChannel = mess.getGdpbHitChanId();
482 UInt_t uTot = mess.getGdpbHit32Tot();
483
487 // UInt_t uFts = mess.getGdpbHitFullTs() % 112;
488 // UInt_t uCts = mess.getGdpbHitFullTs() / 112;
489
490 // UInt_t uChannelNr = fuGet4Id * fuNrOfChannelsPerGet4 + uChannel;
491 UInt_t uChannelNrInFee = (fuGet4Id % fuNrOfGet4PerFee) * fuNrOfChannelsPerGet4 + uChannel;
492 UInt_t uFeeNr = (fuGet4Id / fuNrOfGet4PerFee);
493 // UInt_t uFeeNrInSys = fuCurrDpbIdx * fuNrOfFeePerGdpb + uFeeNr;
494 // UInt_t uRemappedChannelNr = uFeeNr * fuNrOfChannelsPerFee + fUnpackPar->Get4ChanToPadiChan( uChannelNrInFee );
495 UInt_t uRemappedChanNrInFee = fUnpackPar->Get4ChanToPadiChan(uChannelNrInFee);
496 // UInt_t uGbtxNr = (uFeeNr / fUnpackPar->GetNrOfFeePerGbtx());
497 // UInt_t uFeeInGbtx = (uFeeNr % fUnpackPar->GetNrOfFeePerGbtx());
498 // UInt_t uGbtxNrInSys = fuCurrDpbIdx * fUnpackPar->GetNrOfGbtxPerGdpb() + uGbtxNr;
499
500 // UInt_t uChanInSyst = fuCurrDpbIdx * fuNrOfChannelsPerGdpb + uChannelNr;
501 // UInt_t uRemappedChannelNrInSys = fuCurrDpbIdx * fuNrOfChannelsPerGdpb
502 // + uFeeNr * fuNrOfChannelsPerFee
503 // + fUnpackPar->Get4ChanToPadiChan( uChannelNrInFee );
504
505 // ULong_t ulHitTime = mess.getMsgFullTime( mess.getExtendedEpoch() );
506 Double_t dHitTime = mess.GetFullTimeNs();
507 // Double_t dHitTot = uTot; // in bins
508
510 if (0x90 == fuCurrentMsSysId) {
511 if ((0 == fuGet4Id / 2) && (185 < uTot && uTot < 190)) {
512 fvvbFeeHitFound[fuCurrDpbIdx][uFeeNr] = kTRUE;
513 fvvdFeeHits[fuCurrDpbIdx][uFeeNr] = dHitTime;
514 } // if( ( 0 == fuGet4Id / 2 ) && ( 185 < uTot && uTot < 190 ) )
515 } // if( 0x90 == fuCurrentMsSysId )
516 else if (fuPulserChannel == uRemappedChanNrInFee && fuPulserMinTot < uTot && uTot < fuPulserMaxTot) {
517 fvvbFeeHitFound[fuCurrDpbIdx][uFeeNr] = kTRUE;
518 fvvdFeeHits[fuCurrDpbIdx][uFeeNr] = dHitTime;
519 } // if( fuPulserChannel == uRemappedChanNrInFee && fuPulserMinTot < uTot && uTot < fuPulserMaxTot )
520}
521// -------------------------------------------------------------------------
522
524{
525 std::string sFolder = "mTofMoni";
526
527 LOG(info) << "create Histos for mTof monitoring ";
528
529 /*******************************************************************/
530 UInt_t uNbBinsDt = kuNbBinsDt + 1; // To account for extra bin due to shift by 1/2 bin of both ranges
533
534 std::cout << " Bin size " << gdpbv100::kdBinSize << std::endl;
535 std::cout << " Epo bins " << gdpbv100::kuEpochInBins << std::endl;
536 std::cout << " Epo size " << gdpbv100::kdEpochInPs << std::endl;
537 std::cout << " Epo size " << gdpbv100::kdEpochInNs << std::endl;
538 /*******************************************************************/
540 /* clang-format off */
543 for (UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; ++uFeeA) {
544 UInt_t uGdpbA = uFeeA / (fuNrOfFeePerGdpb);
545 if (-1 != fiGdpbIndex) uGdpbA = fiGdpbIndex;
547 UInt_t uFeeIndexA = uFeeA;
548 // UInt_t uFeeIdA = uFeeA - ( fuNrOfFeePerGdpb * uGdpbA );
549 UInt_t uFeeIdA = uFeeIndexA - (3 * 6 * uGdpbA);
550
552 for (UInt_t uFeeB = 0; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; ++uFeeB) {
553
554 if (uFeeA < uFeeB) {
556 UInt_t uFeeIndexB = uFeeB;
557
558 UInt_t uGdpbB = uFeeB / (fuNrOfFeePerGdpb);
559 if (-1 != fiGdpbIndex) uGdpbB = fiGdpbIndex;
560 // UInt_t uFeeIdB = uFeeB - ( fuNrOfFeePerGdpb * uGdpbB );
561 UInt_t uFeeIdB = uFeeIndexB - (3 * 6 * uGdpbB);
562 fvvhFeePairPulserTimeDiff[ uFeeA ][ uFeeB ] = new TH1I(
563 Form("hFeePairPulserTimeDiff_s%02u_f%1u_s%02u_f%1u", uGdpbA, uFeeIdA, uGdpbB, uFeeIdB),
564 Form("Time difference for pulser on gDPB %02u FEE %1u and gDPB %02u FEE %1u; DeltaT [ps]; Counts",
565 uGdpbA, uFeeIdA, uGdpbB, uFeeIdB ),
566 uNbBinsDt, dMinDt, dMaxDt);
567
569 Form("TofDt/s%03u", uFeeIndexA));
570 } // if( uFeeA < uFeeB )
571 else
572 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB] = NULL;
573 } // for( UInt_t uFeeB = 0; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; ++uFeeB )
574 } // for( UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; ++uFeeA )
575
577 UInt_t uTotalNbFee = fuNrOfFeePerGdpb * fuNrOfGdpbs;
578 // Double_t dGdpbMin = -0.5;
579 // Double_t dGdpbMax = fuNrOfGdpbs;
580 fhPulserTimeDiffMean = new TH2D( "hPulserTimeDiffMean",
581 "Time difference Mean for each FEE pairs; FEE A; FEE B ; Mean [ps]",
582 uTotalNbFee - 1, -0.5, uTotalNbFee - 1.5,
583 uTotalNbFee - 1, 0.5, uTotalNbFee - 0.5 );
584
585 fhPulserTimeDiffRms = new TH2D( "hPulserTimeDiffRms",
586 "Time difference RMS for each FEE pairs; FEE A; FEE B ; RMS [ps]",
587 uTotalNbFee - 1, -0.5, uTotalNbFee - 1.5,
588 uTotalNbFee - 1, 0.5, uTotalNbFee - 0.5 );
589
590 fhPulserTimeDiffRmsZoom = new TH2D( "hPulserTimeDiffRmsZoom",
591 "Time difference RMS for each FEE pairs after zoom on peak; FEE A; FEE B ; RMS [ps]",
592 uTotalNbFee - 1, -0.5, uTotalNbFee - 1.5,
593 uTotalNbFee - 1, 0.5, uTotalNbFee - 0.5 );
594
595
596 fhPulserRmsGdpbToRefEvo = new TH2D( "hPulserRmsGdpbToRefEvo",
597 "Evo. of Time difference RMS for selected FEE of each gDPb to the 1st; Time in run [s] A; gDPB ; RMS [ps]",
599 fuNrOfGdpbs - 1, 0.5, fuNrOfGdpbs - 0.5 );
600
601 fhPulserRmsGbtxToRefEvo = new TH2D( "hPulserTimeDiffRmsZoom",
602 "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]",
604 uTotalNbFee - 1, 0.5, uTotalNbFee - 0.5 );
606 /* clang-format on */
607
612 /*******************************************************************/
613
614 /*******************************************************************/
617 fcSummary = new TCanvas("cSummary", "Pulser Monitoring Summary");
618 fcSummary->Divide(3);
619
620 fcSummary->cd(1);
621 gPad->SetGridx();
622 gPad->SetGridy();
623 fhPulserTimeDiffMean->Draw("colz");
624
625 fcSummary->cd(2);
626 gPad->SetGridx();
627 gPad->SetGridy();
628 fhPulserTimeDiffRms->Draw("colz");
629
630 fcSummary->cd(3);
631 gPad->SetGridx();
632 gPad->SetGridy();
633 fhPulserTimeDiffRmsZoom->Draw("colz");
634
635 AddCanvasToVector(fcSummary, "canvases");
637 /*******************************************************************/
638
639 return kTRUE;
640}
642{
643 for (UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++) {
644 UInt_t uGdpbA = uFeeA / (fuNrOfFeePerGdpb);
645 UInt_t uFeeIdA = uFeeA - (fuNrOfFeePerGdpb * uGdpbA);
646
648 if (kFALSE == fvvbFeeHitFound[uGdpbA][uFeeIdA]) continue;
649
650 for (UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++) {
651 UInt_t uGdpbB = uFeeB / (fuNrOfFeePerGdpb);
652 UInt_t uFeeIdB = uFeeB - (fuNrOfFeePerGdpb * uGdpbB);
653
655 if (kFALSE == fvvbFeeHitFound[uGdpbB][uFeeIdB]) continue;
656
657 Double_t dTimeDiff = 1e3 * (fvvdFeeHits[uGdpbB][uFeeIdB] - fvvdFeeHits[uGdpbA][uFeeIdA]);
658 if (TMath::Abs(dTimeDiff) < kdMaxDtPulserPs) {
659 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Fill(dTimeDiff);
660 } // if( TMath::Abs( dTimeDiff ) < kdMaxDtPulserPs )
661 } // for( UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++)
662
664 fvvbFeeHitFound[uGdpbA][uFeeIdA] = kFALSE;
665 } // for( UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++)
666
670 LOG(info) << Form("Reseting stats histos for update on TS %5llu MS %3u", fulCurrentTsIdx, fuMsIndex);
671 fhPulserTimeDiffMean->Reset();
672 fhPulserTimeDiffRms->Reset();
674
675 for (UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++) {
676 for (UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++) {
677 if (0 == fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetEntries()) continue;
678
680 UInt_t uFeeIndexA = uFeeA;
681 UInt_t uFeeIndexB = uFeeB;
682 fhPulserTimeDiffMean->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetMean());
683 fhPulserTimeDiffRms->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetRMS());
684
686 Int_t iBinWithMax = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetMaximumBin();
687 Double_t dNbCounts = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Integral();
688
690 Double_t dPeakPos = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->GetBinCenter(iBinWithMax);
691 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->SetRangeUser(dPeakPos - kdFitZoomWidthPs,
692 dPeakPos + kdFitZoomWidthPs);
693
695 Double_t dZoomCounts = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Integral();
696
698 if ((dZoomCounts / dNbCounts) < 0.8) {
699 fhPulserTimeDiffRmsZoom->Fill(uFeeIndexA, uFeeIndexB, 0.0);
700 // LOG(warning) << "CbmMcbm2018MonitorAlgoTofPulser::FillHistograms => Zoom too strong, "
701 // << "more than 20% loss for FEE pair " << uFeeA << " and " << uFeeB << " !!! ";
702 } // if( ( dZoomCounts / dNbCounts ) < 0.8 )
703 else
704 fhPulserTimeDiffRmsZoom->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetRMS());
705
707 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->UnZoom();
708 /*
709 LOG(info) << "Stats FEE A " << std::setw(3) << uFeeA
710 << " FEE B " << std::setw(3) << uFeeB
711 << Form( " %5.0f %f", fvvhFeePairPulserTimeDiff[ uFeeA ][ uFeeB ]->GetMean(),
712 fvvhFeePairPulserTimeDiff[ uFeeA ][ uFeeB ]->GetRMS() );
713*/
714 } // for( UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++)
715 } // for( UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++)
716 } // if( 1 == fulCurrentTsIdx % fuUpdateFreqTs && fuNbCoreMsPerTs - 1 == fuMsIndex )
717
718 return kTRUE;
719}
721{
722 LOG(info) << Form("Reseting stats histos for final update on TS %5llu MS %3u", fulCurrentTsIdx, fuMsIndex);
723 fhPulserTimeDiffMean->Reset();
724 fhPulserTimeDiffRms->Reset();
726
727 for (UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++) {
728 for (UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++) {
729 if (nullptr == fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]) continue;
730
731 if (0 == fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetEntries()) continue;
732
734 UInt_t uFeeIndexA = uFeeA;
735 UInt_t uFeeIndexB = uFeeB;
736 fhPulserTimeDiffMean->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetMean());
737 fhPulserTimeDiffRms->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetRMS());
738
740 Int_t iBinWithMax = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetMaximumBin();
741 Double_t dNbCounts = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Integral();
742
744 Double_t dPeakPos = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->GetBinCenter(iBinWithMax);
745 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->SetRangeUser(dPeakPos - kdFitZoomWidthPs,
746 dPeakPos + kdFitZoomWidthPs);
747
749 Double_t dZoomCounts = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Integral();
750
752 if ((dZoomCounts / dNbCounts) < 0.8) {
753 fhPulserTimeDiffRmsZoom->Fill(uFeeIndexA, uFeeIndexB, 0.0);
754 LOG(warning) << "CbmMcbm2018MonitorAlgoTofPulser::FillHistograms => "
755 "Zoom too strong, "
756 << "more than 20% loss for FEE pair " << uFeeA << " and " << uFeeB << " !!! ";
757 continue;
758 } // if( ( dZoomCounts / dNbCounts ) < 0.8 )
759 else
760 fhPulserTimeDiffRmsZoom->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetRMS());
761
762
764 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->UnZoom();
765
766 LOG(info) << "Stats FEE A " << std::setw(3) << uFeeIndexA << " FEE B " << std::setw(3) << uFeeIndexB
767 << Form(" %5.0f %f", fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetMean(),
768 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetRMS());
769
770 } // for( UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++)
771 } // for( UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++)
772
773 return kTRUE;
774}
776{
777 LOG(info) << Form("Reseting stats histos on TS %5llu MS %3u", fulCurrentTsIdx, fuMsIndex);
778 for (UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++) {
779 for (UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++) {
780 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Reset();
781 } // for( UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++)
782 } // for( UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++)
783 fhPulserTimeDiffMean->Reset();
784 fhPulserTimeDiffRms->Reset();
786
787 fdStartTime = -1.0;
788
789 return kTRUE;
790}
791// -------------------------------------------------------------------------
std::string FormatMsHeaderPrintout(const fles::MicrosliceDescriptor &msDescriptor)
int Int_t
bool Bool_t
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.
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