CbmRoot
Loading...
Searching...
No Matches
CbmStar2019MonitorPulserAlgo.cxx
Go to the documentation of this file.
1/* Copyright (C) 2019 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// ----- CbmStar2019MonitorPulserAlgo -----
8// ----- Created 12.10.2019 by P.-A. Loizeau -----
9// ----- -----
10// -----------------------------------------------------------------------------
11
13
15#include "CbmStar2019TofPar.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 fbEtofFeeIndexing(kTRUE)
44 , fvbMaskedComponents()
45 , fiSectorIndex(-1)
46 , fuUpdateFreqTs(100)
47 , fUnpackPar(nullptr)
48 , fuNrOfGdpbs(0)
49 , fGdpbIdIndexMap()
50 , fuNrOfFeePerGdpb(0)
51 , fuNrOfGet4PerFee(0)
52 , fuNrOfChannelsPerGet4(0)
53 , fuNrOfChannelsPerFee(0)
54 , fuNrOfGet4(0)
55 , fuNrOfGet4PerGdpb(0)
56 , fuNrOfChannelsPerGdpb(0)
57 , fuPulserMinTot(90)
58 , fuPulserMaxTot(110)
59 , fuPulserChannel(3)
60 , fulCurrentTsIdx(0)
61 , fulCurrentMsIdx(0)
62 , fdTsStartTime(-1.0)
63 , fdTsStopTimeCore(-1.0)
64 , fdMsTime(-1.0)
65 , fuMsIndex(0)
66 , fuCurrentEquipmentId(0)
67 , fuCurrDpbId(0)
68 , fuCurrDpbIdx(0)
69 , fuGet4Id(0)
70 , fuGet4Nr(0)
71 , fvulCurrentEpoch()
72 , fvulCurrentEpochCycle()
73 , fvulCurrentEpochFull()
74 , fvmEpSupprBuffer()
75 , fvvbFeeHitFound()
76 , fvvdFeeHits()
77 , dMinDt(0.0)
78 , dMaxDt(0.0)
79 , fdStartTime(-1.0)
80 , fuHistoryHistoSize(1800)
81 , fvvhFeePairPulserTimeDiff()
82 , fhPulserTimeDiffMean(nullptr)
83 , fhPulserTimeDiffRms(nullptr)
84 , fhPulserTimeDiffRmsZoom(nullptr)
85 , fhPulserRmsGdpbToRefEvo(nullptr)
86 , fhPulserRmsGbtxToRefEvo(nullptr)
87{
88}
94
95// -------------------------------------------------------------------------
97{
98 LOG(info) << "Initializing mCBM Bmon 2019 monitor algo";
99
100 return kTRUE;
101}
109
110// -------------------------------------------------------------------------
112{
113 LOG(info) << "Init parameter containers for CbmStar2019MonitorPulserAlgo";
114 Bool_t initOK = ReInitContainers();
115
116 return initOK;
117}
119{
120 LOG(info) << "**********************************************";
121 LOG(info) << "ReInit parameter containers for CbmStar2019MonitorPulserAlgo";
122
123 fUnpackPar = (CbmStar2019TofPar*) fParCList->FindObject("CbmStar2019TofPar");
124 if (nullptr == fUnpackPar) return kFALSE;
125
126 Bool_t initOK = InitParameters();
127
128 return initOK;
129}
131{
132 if (nullptr == fParCList) fParCList = new TList();
133 fUnpackPar = new CbmStar2019TofPar("CbmStar2019TofPar");
134 fParCList->Add(fUnpackPar);
135
136 return fParCList;
137}
139{
140
142 LOG(info) << "Nr. of Tof GDPBs: " << fuNrOfGdpbs;
143
145 LOG(info) << "Nr. of FEES per Tof GDPB: " << fuNrOfFeePerGdpb;
146
148 LOG(info) << "Nr. of GET4 per Tof FEE: " << fuNrOfGet4PerFee;
149
151 LOG(info) << "Nr. of channels per GET4: " << fuNrOfChannelsPerGet4;
152
154 LOG(info) << "Nr. of channels per FEE: " << fuNrOfChannelsPerFee;
155
157 LOG(info) << "Nr. of GET4s: " << fuNrOfGet4;
158
160 LOG(info) << "Nr. of GET4s per GDPB: " << fuNrOfGet4PerGdpb;
161
163 LOG(info) << "Nr. of channels per GDPB: " << fuNrOfChannelsPerGdpb;
164
165 fGdpbIdIndexMap.clear();
166 for (UInt_t i = 0; i < fuNrOfGdpbs; ++i) {
168 LOG(info) << "GDPB Id of TOF " << i << " : " << std::hex << fUnpackPar->GetGdpbId(i) << std::dec;
169 } // for( UInt_t i = 0; i < fuNrOfGdpbs; ++i )
170
173 LOG(info) << "Timeslice parameters: each MS is " << fdMsSizeInNs << " ns";
174
176 if (-1 < fiSectorIndex) {
178 if (fuNrOfGdpbs <= static_cast<UInt_t>(fiSectorIndex))
179 LOG(fatal) << "Selected sector out of bounds relative to parameter file: " << fiSectorIndex << " VS "
180 << fuNrOfGdpbs;
181 else
182 LOG(info) << "Selected sector " << fiSectorIndex + fUnpackPar->GetGdpbToSectorOffset()
183 << " for single sector analysis";
184 fuNrOfGdpbs = 1;
185 fGdpbIdIndexMap.clear();
187 } // if( -1 < fiSectorIndex )
188
189 if (fbEtofFeeIndexing) LOG(info) << "Using eTOF indexing with only 3 FEE per GBTx instead of 5";
190
192 fvulCurrentEpoch.resize(fuNrOfGdpbs, 0);
196 fvvdFeeHits.resize(fuNrOfGdpbs);
197 for (UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; ++uGdpb) {
198 fvvbFeeHitFound[uGdpb].resize(fuNrOfFeePerGdpb, kFALSE);
199 fvvdFeeHits[uGdpb].resize(fuNrOfFeePerGdpb, 0.0);
200 } // for( UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; ++uGdpb )
201
202
203 return kTRUE;
204}
205// -------------------------------------------------------------------------
206
207void CbmStar2019MonitorPulserAlgo::AddMsComponentToList(size_t component, UShort_t usDetectorId)
208{
210 for (UInt_t uCompIdx = 0; uCompIdx < fvMsComponentsList.size(); ++uCompIdx)
211 if (component == fvMsComponentsList[uCompIdx]) return;
212
214 fvMsComponentsList.push_back(component);
215
216 LOG(info) << "CbmStar2019MonitorPulserAlgo::AddMsComponentToList => Component " << component << " with detector ID 0x"
217 << std::hex << usDetectorId << std::dec << " added to list";
218}
219// -------------------------------------------------------------------------
220
221Bool_t CbmStar2019MonitorPulserAlgo::ProcessTs(const fles::Timeslice& ts)
222{
223 fulCurrentTsIdx = ts.index();
224 fdTsStartTime = static_cast<Double_t>(ts.descriptor(0, 0).idx);
225
227 if (0 == fulCurrentTsIdx) return kTRUE;
228
230 if (-1.0 == fdTsCoreSizeInNs) {
231 fuNbCoreMsPerTs = ts.num_core_microslices();
232 fuNbOverMsPerTs = ts.num_microslices(0) - ts.num_core_microslices();
235 LOG(info) << "Timeslice parameters: each TS has " << fuNbCoreMsPerTs << " Core MS and " << fuNbOverMsPerTs
236 << " Overlap MS, for a core duration of " << fdTsCoreSizeInNs << " ns and a full duration of "
237 << fdTsFullSizeInNs << " ns";
238
242 LOG(info) << "In each TS " << fuNbMsLoop << " MS will be looped over";
243 } // if( -1.0 == fdTsCoreSizeInNs )
244
247 // LOG(info) << Form( "TS %5d Start %12f Stop %12f", fulCurrentTsIdx, fdTsStartTime, fdTsStopTimeCore );
248
250 for (fuMsIndex = 0; fuMsIndex < fuNbMsLoop; fuMsIndex++) {
252 for (UInt_t uMsCompIdx = 0; uMsCompIdx < fvMsComponentsList.size(); ++uMsCompIdx) {
253 UInt_t uMsComp = fvMsComponentsList[uMsCompIdx];
254
255 if (kFALSE == ProcessMs(ts, uMsComp, fuMsIndex)) {
256 LOG(error) << "Failed to process ts " << fulCurrentTsIdx << " MS " << fuMsIndex << " for component " << uMsComp;
257 return kFALSE;
258 } // if( kFALSE == ProcessMs( ts, uMsCompIdx, fuMsIndex ) )
259 } // for( UInt_t uMsCompIdx = 0; uMsCompIdx < fvMsComponentsList.size(); ++uMsCompIdx )
260
263 } // for( fuMsIndex = 0; fuMsIndex < uNbMsLoop; fuMsIndex ++ )
264
265 return kTRUE;
266}
267
268Bool_t CbmStar2019MonitorPulserAlgo::ProcessMs(const fles::Timeslice& ts, size_t uMsCompIdx, size_t uMsIdx)
269{
270 auto msDescriptor = ts.descriptor(uMsCompIdx, uMsIdx);
271 fuCurrentEquipmentId = msDescriptor.eq_id;
272 const uint8_t* msContent = reinterpret_cast<const uint8_t*>(ts.content(uMsCompIdx, uMsIdx));
273
274 uint32_t uSize = msDescriptor.size;
275 fulCurrentMsIdx = msDescriptor.idx;
276 fdMsTime = (1e-9) * static_cast<double>(fulCurrentMsIdx);
277 LOG(debug) << "Microslice: " << fulCurrentMsIdx << " from EqId " << std::hex << fuCurrentEquipmentId << std::dec
278 << " has size: " << uSize;
279
280 if (-1.0 == fdStartTime) fdStartTime = fdMsTime;
281
282 if (0 == fvbMaskedComponents.size()) fvbMaskedComponents.resize(ts.num_components(), kFALSE);
283
284 fuCurrDpbId = static_cast<uint32_t>(fuCurrentEquipmentId & 0xFFFF);
285 // fuCurrDpbIdx = fDpbIdIndexMap[ fuCurrDpbId ];
286
288 auto it = fGdpbIdIndexMap.find(fuCurrDpbId);
289 if (it == fGdpbIdIndexMap.end()) {
290 if (kFALSE == fvbMaskedComponents[uMsCompIdx]) {
291 LOG(info) << "---------------------------------------------------------------";
292 LOG(info) << FormatMsHeaderPrintout(msDescriptor);
293 LOG(warning) << "Could not find the gDPB index for AFCK id 0x" << std::hex << fuCurrDpbId << std::dec
294 << " in timeslice " << fulCurrentTsIdx << " in microslice " << uMsIdx << " component " << uMsCompIdx
295 << "\n"
296 << "If valid this index has to be added in the TOF "
297 "parameter file in the DbpIdArray field";
298 fvbMaskedComponents[uMsCompIdx] = kTRUE;
299 } // if( kFALSE == fvbMaskedComponents[ uMsComp ] )
300 else
301 return kTRUE;
302
305
306 return kFALSE;
307 } // if( it == fGdpbIdIndexMap.end() )
308 else
310
311 // If not integer number of message in input buffer, print warning/error
312 if (0 != (uSize % kuBytesPerMessage))
313 LOG(error) << "The input microslice buffer does NOT "
314 << "contain only complete nDPB messages!";
315
316 // Compute the number of complete messages in the input microslice buffer
317 uint32_t uNbMessages = (uSize - (uSize % kuBytesPerMessage)) / kuBytesPerMessage;
318
319 // Prepare variables for the loop on contents
320 Int_t messageType = -111;
321 const uint64_t* pInBuff = reinterpret_cast<const uint64_t*>(msContent);
322 for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx++) {
323 // Fill message
324 uint64_t ulData = static_cast<uint64_t>(pInBuff[uIdx]);
325
327 if (0 == uIdx) {
328 ProcessEpochCycle(ulData);
329 continue;
330 } // if( 0 == uIdx )
331
332 gdpbv100::Message mess(ulData);
334 messageType = mess.getMessageType();
335
338
340 LOG(warning) << "Message with Get4 ID too high: " << fuGet4Id << " VS " << fuNrOfGet4PerGdpb
341 << " set in parameters.";
342
343 switch (messageType) {
344 case gdpbv100::MSG_HIT: {
345 if (mess.getGdpbHitIs24b()) {
347 LOG(fatal) << "This monitor does not support 24b hit messages!!!.";
348 continue;
349 } // if( getGdpbHitIs24b() )
350 else {
351 fvmEpSupprBuffer.push_back(mess);
352 } // else of if( getGdpbHitIs24b() )
353 break;
354 } // case gdpbv100::MSG_HIT:
355 case gdpbv100::MSG_EPOCH: {
357 ProcessEpoch(mess);
358 } // if this epoch message is a merged one valid for all chips
359 else {
361 LOG(fatal) << "This event builder does not support unmerged epoch "
362 "messages!!!.";
363 continue;
364 } // if single chip epoch message
365 break;
366 } // case gdpbv100::MSG_EPOCH:
374 break;
375 } // case not hit or epoch
376 default:
377 LOG(fatal) << "Message type " << std::hex << std::setw(2) << static_cast<uint16_t>(messageType)
378 << " not included in Get4 data format.";
379 } // switch( mess.getMessageType() )
380 } // for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx ++)
381
382 return kTRUE;
383}
384
385// -------------------------------------------------------------------------
387{
388 ULong64_t ulEpochCycleVal = ulCycleData & gdpbv100::kulEpochCycleFieldSz;
389
390 if (!(ulEpochCycleVal == fvulCurrentEpochCycle[fuCurrDpbIdx]
391 || ulEpochCycleVal == fvulCurrentEpochCycle[fuCurrDpbIdx] + 1)
392 && 0 < fulCurrentMsIdx) {
393 LOG(warning) << "CbmStar2019MonitorPulserAlgo::ProcessEpochCycle => "
394 << " Missmatch in epoch cycles detected for Gdpb " << fuCurrDpbIdx
395 << ", probably fake cycles due to epoch index corruption! "
396 << Form(" Current cycle 0x%09llX New cycle 0x%09llX", fvulCurrentEpochCycle[fuCurrDpbIdx],
397 ulEpochCycleVal);
398 } // if epoch cycle did not stay constant or increase by exactly 1, except if first MS of the TS
399 if (ulEpochCycleVal != fvulCurrentEpochCycle[fuCurrDpbIdx]) {
400 LOG(info) << "CbmStar2019EventBuilderEtofAlgo::ProcessEpochCycle => "
401 << " New epoch cycle for Gdpb " << fuCurrDpbIdx
402 << Form(": Current cycle 0x%09llX New cycle 0x%09llX", fvulCurrentEpochCycle[fuCurrDpbIdx],
403 ulEpochCycleVal);
404 } // if( ulEpochCycleVal != fvulCurrentEpochCycle[fuCurrDpbIdx] )
405 fvulCurrentEpochCycle[fuCurrDpbIdx] = ulEpochCycleVal;
406
407 return;
408}
410{
411 ULong64_t ulEpochNr = mess.getGdpbEpEpochNb();
412 /*
413 Bool_t bSyncFlag = ( 1 == mess.getGdpbEpSync() );
414 Bool_t bDataLoss = ( 1 == mess.getGdpbEpDataLoss() );
415 Bool_t bEpochLoss = ( 1 == mess.getGdpbEpEpochLoss() );
416 Bool_t bMissmMatch = ( 1 == mess.getGdpbEpMissmatch() );
417*/
418 fvulCurrentEpoch[fuCurrDpbIdx] = ulEpochNr;
421
424}
425// -------------------------------------------------------------------------
427{
428 Int_t iBufferSize = fvmEpSupprBuffer.size();
429
430 if (0 == iBufferSize) return;
431
432 LOG(debug) << "Now processing stored messages for for gDPB " << fuCurrDpbIdx << " with epoch number "
434
437 std::stable_sort(fvmEpSupprBuffer.begin(), fvmEpSupprBuffer.end());
438
440 ULong64_t ulCurEpochGdpbGet4 = fvulCurrentEpochFull[fuCurrDpbIdx];
441
443 if (0 == ulCurEpochGdpbGet4) return;
444
446 ulCurEpochGdpbGet4--;
447
448 Int_t messageType = -111;
449 for (Int_t iMsgIdx = 0; iMsgIdx < iBufferSize; iMsgIdx++) {
450 messageType = fvmEpSupprBuffer[iMsgIdx].getMessageType();
451
452 fuGet4Id = fUnpackPar->ElinkIdxToGet4Idx(fvmEpSupprBuffer[iMsgIdx].getGdpbGenChipId());
454
456 gdpbv100::FullMessage fullMess(fvmEpSupprBuffer[iMsgIdx], ulCurEpochGdpbGet4);
457
459 switch (messageType) {
460 case gdpbv100::MSG_HIT: {
461 ProcessHit(fullMess);
462 break;
463 } // case gdpbv100::MSG_HIT:
472 break;
473 default:
474 LOG(error) << "Message type " << std::hex << std::setw(2) << static_cast<uint16_t>(messageType)
475 << " not included in Get4 unpacker.";
476 } // switch( mess.getMessageType() )
477 } // for( Int_t iMsgIdx = 0; iMsgIdx < iBufferSize; iMsgIdx++ )
478
479 fvmEpSupprBuffer.clear();
480}
481// -------------------------------------------------------------------------
483{
484 UInt_t uChannel = mess.getGdpbHitChanId();
485 UInt_t uTot = mess.getGdpbHit32Tot();
486
490 // UInt_t uFts = mess.getGdpbHitFullTs() % 112;
491 // UInt_t uCts = mess.getGdpbHitFullTs() / 112;
492
493 // UInt_t uChannelNr = fuGet4Id * fuNrOfChannelsPerGet4 + uChannel;
494 UInt_t uChannelNrInFee = (fuGet4Id % fuNrOfGet4PerFee) * fuNrOfChannelsPerGet4 + uChannel;
495 UInt_t uFeeNr = (fuGet4Id / fuNrOfGet4PerFee);
496 // UInt_t uFeeNrInSys = fuCurrDpbIdx * fuNrOfFeePerGdpb + uFeeNr;
497 // UInt_t uRemappedChannelNr = uFeeNr * fuNrOfChannelsPerFee + fUnpackPar->Get4ChanToPadiChan( uChannelNrInFee );
498 UInt_t uRemappedChanNrInFee = fUnpackPar->Get4ChanToPadiChan(uChannelNrInFee);
499 // UInt_t uGbtxNr = (uFeeNr / fUnpackPar->GetNrOfFeePerGbtx());
500 // UInt_t uFeeInGbtx = (uFeeNr % fUnpackPar->GetNrOfFeePerGbtx());
501 // UInt_t uGbtxNrInSys = fuCurrDpbIdx * fUnpackPar->GetNrOfGbtxPerGdpb() + uGbtxNr;
502
503 // UInt_t uChanInSyst = fuCurrDpbIdx * fuNrOfChannelsPerGdpb + uChannelNr;
504 // UInt_t uRemappedChannelNrInSys = fuCurrDpbIdx * fuNrOfChannelsPerGdpb
505 // + uFeeNr * fuNrOfChannelsPerFee
506 // + fUnpackPar->Get4ChanToPadiChan( uChannelNrInFee );
507
508 // ULong_t ulHitTime = mess.getMsgFullTime( mess.getExtendedEpoch() );
509 Double_t dHitTime = mess.GetFullTimeNs();
510 // Double_t dHitTot = uTot; // in bins
511
512 if (fuPulserChannel == uRemappedChanNrInFee && fuPulserMinTot < uTot && uTot < fuPulserMaxTot) {
513 fvvbFeeHitFound[fuCurrDpbIdx][uFeeNr] = kTRUE;
514 fvvdFeeHits[fuCurrDpbIdx][uFeeNr] = dHitTime;
515 } // if( fuPulserChannel == uRemappedChanNrInFee && fuPulserMinTot < uTot && uTot < fuPulserMaxTot )
516}
517// -------------------------------------------------------------------------
518
520{
521 std::string sFolder = "eTofMoni";
522
523 LOG(info) << "create Histos for eTOF monitoring ";
524 /*
526 // Number of log bins =
527 // 9 for the sub-unit decade
528 // + 9 for each unit of each decade * 10 for the subdecade range
529 // + 1 for the closing bin top edge
530 const Int_t iNbDecadesLog = 4;
531 const Int_t iNbStepsDecade = 9;
532 const Int_t iNbSubStepsInStep = 1;
533 const Int_t iNbBinsLog = iNbStepsDecade
534 + iNbStepsDecade * iNbSubStepsInStep * iNbDecadesLog
535 + 1;
536 Double_t dBinsLog[iNbBinsLog];
537 // First fill sub-unit decade
538 for( Int_t iSubU = 0; iSubU < iNbStepsDecade; iSubU ++ )
539 dBinsLog[ iSubU ] = 0.1 * ( 1 + iSubU );
540 std::cout << std::endl;
541 // Then fill the main decades
542 Double_t dSubstepSize = 1.0 / iNbSubStepsInStep;
543 for( Int_t iDecade = 0; iDecade < iNbDecadesLog; iDecade ++)
544 {
545 Double_t dBase = std::pow( 10, iDecade );
546 Int_t iDecadeIdx = iNbStepsDecade
547 + iDecade * iNbStepsDecade * iNbSubStepsInStep;
548 for( Int_t iStep = 0; iStep < iNbStepsDecade; iStep++ )
549 {
550 Int_t iStepIdx = iDecadeIdx + iStep * iNbSubStepsInStep;
551 for( Int_t iSubStep = 0; iSubStep < iNbSubStepsInStep; iSubStep++ )
552 {
553 dBinsLog[ iStepIdx + iSubStep ] = dBase * (1 + iStep)
554 + dBase * dSubstepSize * iSubStep;
555 } // for( Int_t iSubStep = 0; iSubStep < iNbSubStepsInStep; iSubStep++ )
556 } // for( Int_t iStep = 0; iStep < iNbStepsDecade; iStep++ )
557 } // for( Int_t iDecade = 0; iDecade < iNbDecadesLog; iDecade ++)
558 dBinsLog[ iNbBinsLog - 1 ] = std::pow( 10, iNbDecadesLog );
559*/
560 /*******************************************************************/
561 UInt_t uNbBinsDt = kuNbBinsDt + 1; // To account for extra bin due to shift by 1/2 bin of both ranges
564
565 std::cout << " Bin size " << gdpbv100::kdBinSize << std::endl;
566 std::cout << " Epo bins " << gdpbv100::kuEpochInBins << std::endl;
567 std::cout << " Epo size " << gdpbv100::kdEpochInPs << std::endl;
568 std::cout << " Epo size " << gdpbv100::kdEpochInNs << std::endl;
569 /*******************************************************************/
572 for (UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; ++uFeeA) {
573 UInt_t uGdpbA = uFeeA / (fuNrOfFeePerGdpb);
574 UInt_t uSectorA = uGdpbA + fUnpackPar->GetGdpbToSectorOffset();
577 UInt_t uFeeIndexA = uFeeA;
578 if (fbEtofFeeIndexing) {
579 uFeeIndexA = 3 * (uFeeA / 5) + (uFeeA % 5);
580 } // if( fbEtofFeeIndexing )
581 // UInt_t uFeeIdA = uFeeA - ( fuNrOfFeePerGdpb * uGdpbA );
582 UInt_t uFeeIdA = uFeeIndexA - (3 * 6 * uGdpbA);
583
585 for (UInt_t uFeeB = 0; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; ++uFeeB) {
586
587 if (uFeeA < uFeeB && (!fbEtofFeeIndexing || ((uFeeA % 5) < 3 && (uFeeB % 5) < 3))) {
589 UInt_t uFeeIndexB = uFeeB;
591 if (fbEtofFeeIndexing) { uFeeIndexB = 3 * (uFeeB / 5) + (uFeeB % 5); } // if( fbEtofFeeIndexing )
592
593 UInt_t uGdpbB = uFeeB / (fuNrOfFeePerGdpb);
594 UInt_t uSectorB = uGdpbB + fUnpackPar->GetGdpbToSectorOffset();
596 // UInt_t uFeeIdB = uFeeB - ( fuNrOfFeePerGdpb * uGdpbB );
597 UInt_t uFeeIdB = uFeeIndexB - (3 * 6 * uGdpbB);
598 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB] =
599 new TH1I(Form("hFeePairPulserTimeDiff_s%02u_f%1u_s%02u_f%1u", uSectorA, uFeeIdA, uSectorB, uFeeIdB),
600 Form("Time difference for pulser on sector %02u FEE %1u and "
601 "sector %02u FEE %1u; DeltaT [ps]; Counts",
602 uSectorA, uFeeIdA, uSectorB, uFeeIdB),
603 uNbBinsDt, dMinDt, dMaxDt);
604
605 AddHistoToVector(fvvhFeePairPulserTimeDiff[uFeeA][uFeeB], Form("TofDt/s%03u", uFeeIndexA));
606 } // if( uFeeA < uFeeB )
607 else
608 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB] = NULL;
609 } // for( UInt_t uFeeB = 0; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; ++uFeeB )
610 } // for( UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; ++uFeeA )
611
613 UInt_t uTotalNbFee = fuNrOfFeePerGdpb * fuNrOfGdpbs;
614 // Double_t dSectorMin = -0.5;
615 // Double_t dSectorMax = fuNrOfGdpbs;
616 if (fbEtofFeeIndexing) {
617 uTotalNbFee = fuNrOfFeePerGdpb * fuNrOfGdpbs * 3 / 5;
618 // dSectorMin = -0.5 + fUnpackPar->GetGdpbToSectorOffset();
619 // dSectorMax = fuNrOfGdpbs + dSectorMin;
620 } // if( fbEtofFeeIndexing )
622 new TH2D("hPulserTimeDiffMean", "Time difference Mean for each FEE pairs; FEE A; FEE B ; Mean [ps]",
623 uTotalNbFee - 1, -0.5, uTotalNbFee - 1.5, uTotalNbFee - 1, 0.5, uTotalNbFee - 0.5);
624
626 new TH2D("hPulserTimeDiffRms", "Time difference RMS for each FEE pairs; FEE A; FEE B ; RMS [ps]", uTotalNbFee - 1,
627 -0.5, uTotalNbFee - 1.5, uTotalNbFee - 1, 0.5, uTotalNbFee - 0.5);
628
629 fhPulserTimeDiffRmsZoom = new TH2D("hPulserTimeDiffRmsZoom",
630 "Time difference RMS for each FEE pairs after zoom on peak; FEE "
631 "A; FEE B ; RMS [ps]",
632 uTotalNbFee - 1, -0.5, uTotalNbFee - 1.5, uTotalNbFee - 1, 0.5, uTotalNbFee - 0.5);
633
634 if (fbEtofFeeIndexing) {
636 new TH2D("hPulserRmsGdpbToRefEvo",
637 "Evo. of Time difference RMS for selected FEE of each sector to "
638 "the 1st; Time in run [s] A; Sector ; RMS [ps]",
641
643 new TH2D("hPulserTimeDiffRmsZoom",
644 "Evo. of Time difference RMS for selected FEE pairs of each GBTx to the "
645 "1st in same sector; Time in run [s] A; FEE ; RMS [ps]",
646 fuHistoryHistoSize, 0, fuHistoryHistoSize, uTotalNbFee - 1, 0.5, uTotalNbFee - 0.5);
647 } // if( fbEtofFeeIndexing )
648 else {
650 new TH2D("hPulserRmsGdpbToRefEvo",
651 "Evo. of Time difference RMS for selected FEE of each gDPb to "
652 "the 1st; Time in run [s] A; gDPB ; RMS [ps]",
654
656 new TH2D("hPulserTimeDiffRmsZoom",
657 "Evo. of Time difference RMS for selected FEE pairs of each GBTx to the "
658 "1st in same gDPB; Time in run [s] A; FEE ; RMS [ps]",
659 fuHistoryHistoSize, 0, fuHistoryHistoSize, uTotalNbFee - 1, 0.5, uTotalNbFee - 0.5);
660 } // if( fbEtofFeeIndexing )
661
666 /*******************************************************************/
667
668 /*******************************************************************/
671 fcSummary = new TCanvas("cSummary", "Pulser Monitoring Summary");
672 fcSummary->Divide(3);
673
674 fcSummary->cd(1);
675 gPad->SetGridx();
676 gPad->SetGridy();
677 fhPulserTimeDiffMean->Draw("colz");
678
679 fcSummary->cd(2);
680 gPad->SetGridx();
681 gPad->SetGridy();
682 fhPulserTimeDiffRms->Draw("colz");
683
684 fcSummary->cd(3);
685 gPad->SetGridx();
686 gPad->SetGridy();
687 fhPulserTimeDiffRmsZoom->Draw("colz");
688
689 AddCanvasToVector(fcSummary, "canvases");
691 /*******************************************************************/
692
693 return kTRUE;
694}
696{
700 fhPulserTimeDiffMean->Reset();
701 fhPulserTimeDiffRms->Reset();
703 } // if( 1 == fulCurrentTsIdx % fuUpdateFreqTs && fuNbCoreMsPerTs - 1 == fuMsIndex )
704
705 for (UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++) {
706 UInt_t uGdpbA = uFeeA / (fuNrOfFeePerGdpb);
707 UInt_t uFeeIdA = uFeeA - (fuNrOfFeePerGdpb * uGdpbA);
708
710 if (kFALSE == fvvbFeeHitFound[uGdpbA][uFeeIdA]) continue;
711
712 for (UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++) {
713 UInt_t uGdpbB = uFeeB / (fuNrOfFeePerGdpb);
714 UInt_t uFeeIdB = uFeeB - (fuNrOfFeePerGdpb * uGdpbB);
715
717 if (kFALSE == fvvbFeeHitFound[uGdpbB][uFeeIdB]) continue;
718
719 Double_t dTimeDiff = 1e3 * (fvvdFeeHits[uGdpbB][uFeeIdB] - fvvdFeeHits[uGdpbA][uFeeIdA]);
720 if (TMath::Abs(dTimeDiff) < kdMaxDtPulserPs) {
721 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Fill(dTimeDiff);
722 } // f( TMath::Abs( dTimeDiff ) < kdMaxDtPulserPs )
723
727 UInt_t uFeeIndexA = uFeeA;
728 UInt_t uFeeIndexB = uFeeB;
730 if (fbEtofFeeIndexing) {
731 uFeeIndexA = 3 * (uFeeA / 5) + (uFeeA % 5);
732 uFeeIndexB = 3 * (uFeeB / 5) + (uFeeB % 5);
733 } // if( fbEtofFeeIndexing )
734 fhPulserTimeDiffMean->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetMean());
735 fhPulserTimeDiffRms->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetRMS());
736
738 Int_t iBinWithMax = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetMaximumBin();
739 Double_t dNbCounts = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Integral();
740
742 Double_t dPeakPos = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->GetBinCenter(iBinWithMax);
743 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->SetRangeUser(dPeakPos - kdFitZoomWidthPs,
744 dPeakPos + kdFitZoomWidthPs);
745
747 Double_t dZoomCounts = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Integral();
748
750 if ((dZoomCounts / dNbCounts) < 0.8) {
751 fhPulserTimeDiffRmsZoom->Fill(uFeeIndexA, uFeeIndexB, 0.0);
752 // LOG(warning) << "CbmStar2019MonitorPulserAlgo::FillHistograms => Zoom too strong, "
753 // << "more than 20% loss for FEE pair " << uFeeA << " and " << uFeeB << " !!! ";
754 } // if( ( dZoomCounts / dNbCounts ) < 0.8 )
755 else
756 fhPulserTimeDiffRmsZoom->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetRMS());
757
759 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->UnZoom();
760 /*
761 LOG(info) << "Stats FEE A " << std::setw(3) << uFeeA
762 << " FEE B " << std::setw(3) << uFeeB
763 << Form( " %5.0f %f", fvvhFeePairPulserTimeDiff[ uFeeA ][ uFeeB ]->GetMean(),
764 fvvhFeePairPulserTimeDiff[ uFeeA ][ uFeeB ]->GetRMS() );
765*/
766 } // if( 1 == fulCurrentTsIdx % fuUpdateFreqTs && fuNbCoreMsPerTs - 1 == fuMsIndex )
767 } // for( UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++)
768
770 fvvbFeeHitFound[uGdpbA][uFeeIdA] = kFALSE;
771 } // for( UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++)
772
773 return kTRUE;
774}
776{
777 fhPulserTimeDiffMean->Reset();
778 fhPulserTimeDiffRms->Reset();
780
781 for (UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++) {
782 UInt_t uGdpbA = uFeeA / (fuNrOfFeePerGdpb);
783 UInt_t uFeeIdA = uFeeA - (fuNrOfFeePerGdpb * uGdpbA);
784
785 for (UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++) {
786 // UInt_t uGdpbB = uFeeB / ( fuNrOfFeePerGdpb );
787 // UInt_t uFeeIdB = uFeeB - ( fuNrOfFeePerGdpb * uGdpbB );
788
789 if (nullptr == fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]) continue;
790
792 UInt_t uFeeIndexA = uFeeA;
793 UInt_t uFeeIndexB = uFeeB;
795 if (fbEtofFeeIndexing) {
796 uFeeIndexA = 3 * (uFeeA / 5) + (uFeeA % 5);
797 uFeeIndexB = 3 * (uFeeB / 5) + (uFeeB % 5);
798 } // if( fbEtofFeeIndexing )
799 fhPulserTimeDiffMean->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetMean());
800 fhPulserTimeDiffRms->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetRMS());
801
803 Int_t iBinWithMax = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetMaximumBin();
804 Double_t dNbCounts = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Integral();
805
807 Double_t dPeakPos = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->GetBinCenter(iBinWithMax);
808 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->SetRangeUser(dPeakPos - kdFitZoomWidthPs,
809 dPeakPos + kdFitZoomWidthPs);
810
812 Double_t dZoomCounts = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Integral();
813
815 if ((dZoomCounts / dNbCounts) < 0.8) {
816 fhPulserTimeDiffRmsZoom->Fill(uFeeIndexA, uFeeIndexB, 0.0);
817 LOG(warning) << "CbmStar2019MonitorPulserAlgo::FillHistograms => Zoom too strong, "
818 << "more than 20% loss for FEE pair " << uFeeA << " and " << uFeeB << " !!! ";
819 continue;
820 } // if( ( dZoomCounts / dNbCounts ) < 0.8 )
821 else
822 fhPulserTimeDiffRmsZoom->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetRMS());
823
824
826 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->UnZoom();
827
828 LOG(info) << "Stats FEE A " << std::setw(3) << uFeeIndexA << " FEE B " << std::setw(3) << uFeeIndexB
829 << Form(" %5.0f %f", fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetMean(),
830 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetRMS());
831
832 } // for( UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++)
833
835 fvvbFeeHitFound[uGdpbA][uFeeIdA] = kFALSE;
836 } // for( UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++)
837
838 return kTRUE;
839}
841{
842 for (UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++) {
843 for (UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++) {
844 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Reset();
845 } // for( UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++)
846 } // for( UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++)
847 fhPulserTimeDiffMean->Reset();
848 fhPulserTimeDiffRms->Reset();
850
851 fdStartTime = -1.0;
852
853 return kTRUE;
854}
855// -------------------------------------------------------------------------
std::string FormatMsHeaderPrintout(const fles::MicrosliceDescriptor &msDescriptor)
void AddHistoToVector(TNamed *pointer, std::string sFolder="")
std::vector< size_t > fvMsComponentsList
void AddCanvasToVector(TCanvas *pointer, std::string sFolder="")
std::vector< std::vector< TH1 * > > fvvhFeePairPulserTimeDiff
Size in seconds of the evolution histograms.
UInt_t fuNrOfFeePerGdpb
gDPB ID to index map
Bool_t ProcessTs(const fles::Timeslice &ts)
void ProcessEpoch(gdpbv100::Message mess)
UInt_t fuCurrDpbId
Current equipment ID, tells from which DPB the current MS is originating.
UInt_t fuGet4Nr
running number (0 to fuNrOfGet4PerGdpb) of the Get4 chip of a unique GDPB for current message
const Double_t kdMaxDtPulserPs
[ Sector ][ FEE ]
void ProcessHit(gdpbv100::FullMessage mess)
UInt_t fuCurrDpbIdx
Temp holder until Current equipment ID is properly filled in MS.
std::vector< ULong64_t > fvulCurrentEpoch
Data format control: Current time references for each GDPB: merged epoch marker, epoch cycle,...
std::vector< ULong64_t > fvulCurrentEpochFull
Epoch cycle from the Ms Start message and Epoch counter flip.
std::vector< std::vector< Double_t > > fvvdFeeHits
[ Sector ][ FEE ]
Double_t fdStartTime
Starting time and time evolution book-keeping.
std::vector< ULong64_t > fvulCurrentEpochCycle
Current epoch index, per DPB.
UInt_t fuNrOfGet4PerGdpb
Total number of Get4 chips in the system.
std::vector< gdpbv100::Message > fvmEpSupprBuffer
Epoch + Epoch Cycle.
void AddMsComponentToList(size_t component, UShort_t usDetectorId)
UInt_t fuNrOfChannelsPerFee
Number of channels in each GET4.
Double_t fdMsTime
End Time in ns of current TS Core from the index of the first MS first component.
std::vector< std::vector< Bool_t > > fvvbFeeHitFound
Storing the time of the last hit for each MS in each of the FEE.
UInt_t fuNrOfChannelsPerGet4
Number of GET4s per FEE.
Double_t fdTsStopTimeCore
Time in ns of current TS from the index of the first MS first component.
UInt_t fuGet4Id
Index of the DPB from which the MS currently unpacked is coming.
UInt_t fuNrOfGet4
Number of channels in each FEE.
UInt_t fuNrOfGet4PerFee
Number of FEBs per GDPB.
CbmStar2019TofPar * fUnpackPar
Settings from parameter file.
UInt_t fuNrOfChannelsPerGdpb
Number of GET4s per GDPB.
std::map< UInt_t, UInt_t > fGdpbIdIndexMap
Total number of GDPBs in the system.
Bool_t ProcessMs(const fles::Timeslice &ts, size_t uMsCompIdx, size_t uMsIdx)
UInt_t fuMsIndex
Start Time in ns of current MS from its index field in header.
UInt_t fuPulserMinTot
Number of channels per GDPB.
static constexpr UInt_t GetNrOfFeePerGdpb()
Int_t GetGdpbId(Int_t i)
Int_t ElinkIdxToGet4Idx(UInt_t uElink)
static constexpr UInt_t GetGdpbToSectorOffset()
Int_t Get4ChanToPadiChan(UInt_t uChannelInFee)
static constexpr UInt_t GetNrOfChannelsPerGet4()
static constexpr UInt_t GetNrOfGet4PerFee()
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