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#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// -------------------------------------------------------------------------
92
93// -------------------------------------------------------------------------
95{
96 LOG(info) << "Initializing mCBM Bmon 2019 monitor algo";
97
98 return kTRUE;
99}
107
108// -------------------------------------------------------------------------
110{
111 LOG(info) << "Init parameter containers for CbmStar2019MonitorPulserAlgo";
112 Bool_t initOK = ReInitContainers();
113
114 return initOK;
115}
117{
118 LOG(info) << "**********************************************";
119 LOG(info) << "ReInit parameter containers for CbmStar2019MonitorPulserAlgo";
120
121 fUnpackPar = (CbmStar2019TofPar*) fParCList->FindObject("CbmStar2019TofPar");
122 if (nullptr == fUnpackPar) return kFALSE;
123
124 Bool_t initOK = InitParameters();
125
126 return initOK;
127}
129{
130 if (nullptr == fParCList) fParCList = new TList();
131 fUnpackPar = new CbmStar2019TofPar("CbmStar2019TofPar");
132 fParCList->Add(fUnpackPar);
133
134 return fParCList;
135}
137{
138
139 fuNrOfGdpbs = fUnpackPar->GetNrOfGdpbs();
140 LOG(info) << "Nr. of Tof GDPBs: " << fuNrOfGdpbs;
141
142 fuNrOfFeePerGdpb = fUnpackPar->GetNrOfFeePerGdpb();
143 LOG(info) << "Nr. of FEES per Tof GDPB: " << fuNrOfFeePerGdpb;
144
145 fuNrOfGet4PerFee = fUnpackPar->GetNrOfGet4PerFee();
146 LOG(info) << "Nr. of GET4 per Tof FEE: " << fuNrOfGet4PerFee;
147
148 fuNrOfChannelsPerGet4 = fUnpackPar->GetNrOfChannelsPerGet4();
149 LOG(info) << "Nr. of channels per GET4: " << fuNrOfChannelsPerGet4;
150
152 LOG(info) << "Nr. of channels per FEE: " << fuNrOfChannelsPerFee;
153
155 LOG(info) << "Nr. of GET4s: " << fuNrOfGet4;
156
158 LOG(info) << "Nr. of GET4s per GDPB: " << fuNrOfGet4PerGdpb;
159
161 LOG(info) << "Nr. of channels per GDPB: " << fuNrOfChannelsPerGdpb;
162
163 fGdpbIdIndexMap.clear();
164 for (UInt_t i = 0; i < fuNrOfGdpbs; ++i) {
165 fGdpbIdIndexMap[fUnpackPar->GetGdpbId(i)] = i;
166 LOG(info) << "GDPB Id of TOF " << i << " : " << std::hex << fUnpackPar->GetGdpbId(i) << std::dec;
167 } // for( UInt_t i = 0; i < fuNrOfGdpbs; ++i )
168
170 fdMsSizeInNs = fUnpackPar->GetSizeMsInNs();
171 LOG(info) << "Timeslice parameters: each MS is " << fdMsSizeInNs << " ns";
172
174 if (-1 < fiSectorIndex) {
175 fiSectorIndex -= fUnpackPar->GetGdpbToSectorOffset();
176 if (fuNrOfGdpbs <= static_cast<UInt_t>(fiSectorIndex))
177 LOG(fatal) << "Selected sector out of bounds relative to parameter file: " << fiSectorIndex << " VS "
178 << fuNrOfGdpbs;
179 else
180 LOG(info) << "Selected sector " << fiSectorIndex + fUnpackPar->GetGdpbToSectorOffset()
181 << " for single sector analysis";
182 fuNrOfGdpbs = 1;
183 fGdpbIdIndexMap.clear();
185 } // if( -1 < fiSectorIndex )
186
187 if (fbEtofFeeIndexing) LOG(info) << "Using eTOF indexing with only 3 FEE per GBTx instead of 5";
188
190 fvulCurrentEpoch.resize(fuNrOfGdpbs, 0);
194 fvvdFeeHits.resize(fuNrOfGdpbs);
195 for (UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; ++uGdpb) {
196 fvvbFeeHitFound[uGdpb].resize(fuNrOfFeePerGdpb, kFALSE);
197 fvvdFeeHits[uGdpb].resize(fuNrOfFeePerGdpb, 0.0);
198 } // for( UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; ++uGdpb )
199
200
201 return kTRUE;
202}
203// -------------------------------------------------------------------------
204
205void CbmStar2019MonitorPulserAlgo::AddMsComponentToList(size_t component, UShort_t usDetectorId)
206{
208 for (UInt_t uCompIdx = 0; uCompIdx < fvMsComponentsList.size(); ++uCompIdx)
209 if (component == fvMsComponentsList[uCompIdx]) return;
210
212 fvMsComponentsList.push_back(component);
213
214 LOG(info) << "CbmStar2019MonitorPulserAlgo::AddMsComponentToList => Component " << component << " with detector ID 0x"
215 << std::hex << usDetectorId << std::dec << " added to list";
216}
217// -------------------------------------------------------------------------
218
220{
221 fulCurrentTsIdx = ts.index();
222 fdTsStartTime = static_cast<Double_t>(ts.descriptor(0, 0).idx);
223
225 if (0 == fulCurrentTsIdx) return kTRUE;
226
228 if (-1.0 == fdTsCoreSizeInNs) {
229 fuNbCoreMsPerTs = ts.num_core_microslices();
230 fuNbOverMsPerTs = ts.num_microslices(0) - ts.num_core_microslices();
233 LOG(info) << "Timeslice parameters: each TS has " << fuNbCoreMsPerTs << " Core MS and " << fuNbOverMsPerTs
234 << " Overlap MS, for a core duration of " << fdTsCoreSizeInNs << " ns and a full duration of "
235 << fdTsFullSizeInNs << " ns";
236
240 LOG(info) << "In each TS " << fuNbMsLoop << " MS will be looped over";
241 } // if( -1.0 == fdTsCoreSizeInNs )
242
245 // LOG(info) << Form( "TS %5d Start %12f Stop %12f", fulCurrentTsIdx, fdTsStartTime, fdTsStopTimeCore );
246
248 for (fuMsIndex = 0; fuMsIndex < fuNbMsLoop; fuMsIndex++) {
250 for (UInt_t uMsCompIdx = 0; uMsCompIdx < fvMsComponentsList.size(); ++uMsCompIdx) {
251 UInt_t uMsComp = fvMsComponentsList[uMsCompIdx];
252
253 if (kFALSE == ProcessMs(ts, uMsComp, fuMsIndex)) {
254 LOG(error) << "Failed to process ts " << fulCurrentTsIdx << " MS " << fuMsIndex << " for component " << uMsComp;
255 return kFALSE;
256 } // if( kFALSE == ProcessMs( ts, uMsCompIdx, fuMsIndex ) )
257 } // for( UInt_t uMsCompIdx = 0; uMsCompIdx < fvMsComponentsList.size(); ++uMsCompIdx )
258
261 } // for( fuMsIndex = 0; fuMsIndex < uNbMsLoop; fuMsIndex ++ )
262
263 return kTRUE;
264}
265
266Bool_t CbmStar2019MonitorPulserAlgo::ProcessMs(const fles::Timeslice& ts, size_t uMsCompIdx, size_t uMsIdx)
267{
268 auto msDescriptor = ts.descriptor(uMsCompIdx, uMsIdx);
269 fuCurrentEquipmentId = msDescriptor.eq_id;
270 const uint8_t* msContent = reinterpret_cast<const uint8_t*>(ts.content(uMsCompIdx, uMsIdx));
271
272 uint32_t uSize = msDescriptor.size;
273 fulCurrentMsIdx = msDescriptor.idx;
274 fdMsTime = (1e-9) * static_cast<double>(fulCurrentMsIdx);
275 LOG(debug) << "Microslice: " << fulCurrentMsIdx << " from EqId " << std::hex << fuCurrentEquipmentId << std::dec
276 << " has size: " << uSize;
277
278 if (-1.0 == fdStartTime) fdStartTime = fdMsTime;
279
280 if (0 == fvbMaskedComponents.size()) fvbMaskedComponents.resize(ts.num_components(), kFALSE);
281
282 fuCurrDpbId = static_cast<uint32_t>(fuCurrentEquipmentId & 0xFFFF);
283 // fuCurrDpbIdx = fDpbIdIndexMap[ fuCurrDpbId ];
284
286 auto it = fGdpbIdIndexMap.find(fuCurrDpbId);
287 if (it == fGdpbIdIndexMap.end()) {
288 if (kFALSE == fvbMaskedComponents[uMsCompIdx]) {
289 LOG(info) << "---------------------------------------------------------------";
290 LOG(info) << FormatMsHeaderPrintout(msDescriptor);
291 LOG(warning) << "Could not find the gDPB index for AFCK id 0x" << std::hex << fuCurrDpbId << std::dec
292 << " in timeslice " << fulCurrentTsIdx << " in microslice " << uMsIdx << " component " << uMsCompIdx
293 << "\n"
294 << "If valid this index has to be added in the TOF "
295 "parameter file in the DbpIdArray field";
296 fvbMaskedComponents[uMsCompIdx] = kTRUE;
297 } // if( kFALSE == fvbMaskedComponents[ uMsComp ] )
298 else
299 return kTRUE;
300
303
304 return kFALSE;
305 } // if( it == fGdpbIdIndexMap.end() )
306 else
308
309 // If not integer number of message in input buffer, print warning/error
310 if (0 != (uSize % kuBytesPerMessage))
311 LOG(error) << "The input microslice buffer does NOT "
312 << "contain only complete nDPB messages!";
313
314 // Compute the number of complete messages in the input microslice buffer
315 uint32_t uNbMessages = (uSize - (uSize % kuBytesPerMessage)) / kuBytesPerMessage;
316
317 // Prepare variables for the loop on contents
318 Int_t messageType = -111;
319 const uint64_t* pInBuff = reinterpret_cast<const uint64_t*>(msContent);
320 for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx++) {
321 // Fill message
322 uint64_t ulData = static_cast<uint64_t>(pInBuff[uIdx]);
323
325 if (0 == uIdx) {
326 ProcessEpochCycle(ulData);
327 continue;
328 } // if( 0 == uIdx )
329
330 gdpbv100::Message mess(ulData);
332 messageType = mess.getMessageType();
333
334 fuGet4Id = fUnpackPar->ElinkIdxToGet4Idx(mess.getGdpbGenChipId());
336
338 LOG(warning) << "Message with Get4 ID too high: " << fuGet4Id << " VS " << fuNrOfGet4PerGdpb
339 << " set in parameters.";
340
341 switch (messageType) {
342 case gdpbv100::MSG_HIT: {
343 if (mess.getGdpbHitIs24b()) {
345 LOG(fatal) << "This monitor does not support 24b hit messages!!!.";
346 continue;
347 } // if( getGdpbHitIs24b() )
348 else {
349 fvmEpSupprBuffer.push_back(mess);
350 } // else of if( getGdpbHitIs24b() )
351 break;
352 } // case gdpbv100::MSG_HIT:
353 case gdpbv100::MSG_EPOCH: {
355 ProcessEpoch(mess);
356 } // if this epoch message is a merged one valid for all chips
357 else {
359 LOG(fatal) << "This event builder does not support unmerged epoch "
360 "messages!!!.";
361 continue;
362 } // if single chip epoch message
363 break;
364 } // case gdpbv100::MSG_EPOCH:
372 break;
373 } // case not hit or epoch
374 default:
375 LOG(fatal) << "Message type " << std::hex << std::setw(2) << static_cast<uint16_t>(messageType)
376 << " not included in Get4 data format.";
377 } // switch( mess.getMessageType() )
378 } // for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx ++)
379
380 return kTRUE;
381}
382
383// -------------------------------------------------------------------------
385{
386 ULong64_t ulEpochCycleVal = ulCycleData & gdpbv100::kulEpochCycleFieldSz;
387
388 if (!(ulEpochCycleVal == fvulCurrentEpochCycle[fuCurrDpbIdx]
389 || ulEpochCycleVal == fvulCurrentEpochCycle[fuCurrDpbIdx] + 1)
390 && 0 < fulCurrentMsIdx) {
391 LOG(warning) << "CbmStar2019MonitorPulserAlgo::ProcessEpochCycle => "
392 << " Missmatch in epoch cycles detected for Gdpb " << fuCurrDpbIdx
393 << ", probably fake cycles due to epoch index corruption! "
394 << Form(" Current cycle 0x%09llX New cycle 0x%09llX", fvulCurrentEpochCycle[fuCurrDpbIdx],
395 ulEpochCycleVal);
396 } // if epoch cycle did not stay constant or increase by exactly 1, except if first MS of the TS
397 if (ulEpochCycleVal != fvulCurrentEpochCycle[fuCurrDpbIdx]) {
398 LOG(info) << "CbmStar2019EventBuilderEtofAlgo::ProcessEpochCycle => "
399 << " New epoch cycle for Gdpb " << fuCurrDpbIdx
400 << Form(": Current cycle 0x%09llX New cycle 0x%09llX", fvulCurrentEpochCycle[fuCurrDpbIdx],
401 ulEpochCycleVal);
402 } // if( ulEpochCycleVal != fvulCurrentEpochCycle[fuCurrDpbIdx] )
403 fvulCurrentEpochCycle[fuCurrDpbIdx] = ulEpochCycleVal;
404
405 return;
406}
408{
409 ULong64_t ulEpochNr = mess.getGdpbEpEpochNb();
410 /*
411 Bool_t bSyncFlag = ( 1 == mess.getGdpbEpSync() );
412 Bool_t bDataLoss = ( 1 == mess.getGdpbEpDataLoss() );
413 Bool_t bEpochLoss = ( 1 == mess.getGdpbEpEpochLoss() );
414 Bool_t bMissmMatch = ( 1 == mess.getGdpbEpMissmatch() );
415*/
416 fvulCurrentEpoch[fuCurrDpbIdx] = ulEpochNr;
419
422}
423// -------------------------------------------------------------------------
425{
426 Int_t iBufferSize = fvmEpSupprBuffer.size();
427
428 if (0 == iBufferSize) return;
429
430 LOG(debug) << "Now processing stored messages for for gDPB " << fuCurrDpbIdx << " with epoch number "
432
435 std::stable_sort(fvmEpSupprBuffer.begin(), fvmEpSupprBuffer.end());
436
438 ULong64_t ulCurEpochGdpbGet4 = fvulCurrentEpochFull[fuCurrDpbIdx];
439
441 if (0 == ulCurEpochGdpbGet4) return;
442
444 ulCurEpochGdpbGet4--;
445
446 Int_t messageType = -111;
447 for (Int_t iMsgIdx = 0; iMsgIdx < iBufferSize; iMsgIdx++) {
448 messageType = fvmEpSupprBuffer[iMsgIdx].getMessageType();
449
450 fuGet4Id = fUnpackPar->ElinkIdxToGet4Idx(fvmEpSupprBuffer[iMsgIdx].getGdpbGenChipId());
452
454 gdpbv100::FullMessage fullMess(fvmEpSupprBuffer[iMsgIdx], ulCurEpochGdpbGet4);
455
457 switch (messageType) {
458 case gdpbv100::MSG_HIT: {
459 ProcessHit(fullMess);
460 break;
461 } // case gdpbv100::MSG_HIT:
470 break;
471 default:
472 LOG(error) << "Message type " << std::hex << std::setw(2) << static_cast<uint16_t>(messageType)
473 << " not included in Get4 unpacker.";
474 } // switch( mess.getMessageType() )
475 } // for( Int_t iMsgIdx = 0; iMsgIdx < iBufferSize; iMsgIdx++ )
476
477 fvmEpSupprBuffer.clear();
478}
479// -------------------------------------------------------------------------
481{
482 UInt_t uChannel = mess.getGdpbHitChanId();
483 UInt_t uTot = mess.getGdpbHit32Tot();
484
488 // UInt_t uFts = mess.getGdpbHitFullTs() % 112;
489 // UInt_t uCts = mess.getGdpbHitFullTs() / 112;
490
491 // UInt_t uChannelNr = fuGet4Id * fuNrOfChannelsPerGet4 + uChannel;
492 UInt_t uChannelNrInFee = (fuGet4Id % fuNrOfGet4PerFee) * fuNrOfChannelsPerGet4 + uChannel;
493 UInt_t uFeeNr = (fuGet4Id / fuNrOfGet4PerFee);
494 // UInt_t uFeeNrInSys = fuCurrDpbIdx * fuNrOfFeePerGdpb + uFeeNr;
495 // UInt_t uRemappedChannelNr = uFeeNr * fuNrOfChannelsPerFee + fUnpackPar->Get4ChanToPadiChan( uChannelNrInFee );
496 UInt_t uRemappedChanNrInFee = fUnpackPar->Get4ChanToPadiChan(uChannelNrInFee);
497 // UInt_t uGbtxNr = (uFeeNr / fUnpackPar->GetNrOfFeePerGbtx());
498 // UInt_t uFeeInGbtx = (uFeeNr % fUnpackPar->GetNrOfFeePerGbtx());
499 // UInt_t uGbtxNrInSys = fuCurrDpbIdx * fUnpackPar->GetNrOfGbtxPerGdpb() + uGbtxNr;
500
501 // UInt_t uChanInSyst = fuCurrDpbIdx * fuNrOfChannelsPerGdpb + uChannelNr;
502 // UInt_t uRemappedChannelNrInSys = fuCurrDpbIdx * fuNrOfChannelsPerGdpb
503 // + uFeeNr * fuNrOfChannelsPerFee
504 // + fUnpackPar->Get4ChanToPadiChan( uChannelNrInFee );
505
506 // ULong_t ulHitTime = mess.getMsgFullTime( mess.getExtendedEpoch() );
507 Double_t dHitTime = mess.GetFullTimeNs();
508 // Double_t dHitTot = uTot; // in bins
509
510 if (fuPulserChannel == uRemappedChanNrInFee && fuPulserMinTot < uTot && uTot < fuPulserMaxTot) {
511 fvvbFeeHitFound[fuCurrDpbIdx][uFeeNr] = kTRUE;
512 fvvdFeeHits[fuCurrDpbIdx][uFeeNr] = dHitTime;
513 } // if( fuPulserChannel == uRemappedChanNrInFee && fuPulserMinTot < uTot && uTot < fuPulserMaxTot )
514}
515// -------------------------------------------------------------------------
516
518{
519 std::string sFolder = "eTofMoni";
520
521 LOG(info) << "create Histos for eTOF monitoring ";
522 /*
524 // Number of log bins =
525 // 9 for the sub-unit decade
526 // + 9 for each unit of each decade * 10 for the subdecade range
527 // + 1 for the closing bin top edge
528 const Int_t iNbDecadesLog = 4;
529 const Int_t iNbStepsDecade = 9;
530 const Int_t iNbSubStepsInStep = 1;
531 const Int_t iNbBinsLog = iNbStepsDecade
532 + iNbStepsDecade * iNbSubStepsInStep * iNbDecadesLog
533 + 1;
534 Double_t dBinsLog[iNbBinsLog];
535 // First fill sub-unit decade
536 for( Int_t iSubU = 0; iSubU < iNbStepsDecade; iSubU ++ )
537 dBinsLog[ iSubU ] = 0.1 * ( 1 + iSubU );
538 std::cout << std::endl;
539 // Then fill the main decades
540 Double_t dSubstepSize = 1.0 / iNbSubStepsInStep;
541 for( Int_t iDecade = 0; iDecade < iNbDecadesLog; iDecade ++)
542 {
543 Double_t dBase = std::pow( 10, iDecade );
544 Int_t iDecadeIdx = iNbStepsDecade
545 + iDecade * iNbStepsDecade * iNbSubStepsInStep;
546 for( Int_t iStep = 0; iStep < iNbStepsDecade; iStep++ )
547 {
548 Int_t iStepIdx = iDecadeIdx + iStep * iNbSubStepsInStep;
549 for( Int_t iSubStep = 0; iSubStep < iNbSubStepsInStep; iSubStep++ )
550 {
551 dBinsLog[ iStepIdx + iSubStep ] = dBase * (1 + iStep)
552 + dBase * dSubstepSize * iSubStep;
553 } // for( Int_t iSubStep = 0; iSubStep < iNbSubStepsInStep; iSubStep++ )
554 } // for( Int_t iStep = 0; iStep < iNbStepsDecade; iStep++ )
555 } // for( Int_t iDecade = 0; iDecade < iNbDecadesLog; iDecade ++)
556 dBinsLog[ iNbBinsLog - 1 ] = std::pow( 10, iNbDecadesLog );
557*/
558 /*******************************************************************/
559 UInt_t uNbBinsDt = kuNbBinsDt + 1; // To account for extra bin due to shift by 1/2 bin of both ranges
562
563 std::cout << " Bin size " << gdpbv100::kdBinSize << std::endl;
564 std::cout << " Epo bins " << gdpbv100::kuEpochInBins << std::endl;
565 std::cout << " Epo size " << gdpbv100::kdEpochInPs << std::endl;
566 std::cout << " Epo size " << gdpbv100::kdEpochInNs << std::endl;
567 /*******************************************************************/
570 for (UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; ++uFeeA) {
571 UInt_t uGdpbA = uFeeA / (fuNrOfFeePerGdpb);
572 UInt_t uSectorA = uGdpbA + fUnpackPar->GetGdpbToSectorOffset();
573 if (-1 != fiSectorIndex) uSectorA = fiSectorIndex + fUnpackPar->GetGdpbToSectorOffset();
575 UInt_t uFeeIndexA = uFeeA;
576 if (fbEtofFeeIndexing) {
577 uFeeIndexA = 3 * (uFeeA / 5) + (uFeeA % 5);
578 } // if( fbEtofFeeIndexing )
579 // UInt_t uFeeIdA = uFeeA - ( fuNrOfFeePerGdpb * uGdpbA );
580 UInt_t uFeeIdA = uFeeIndexA - (3 * 6 * uGdpbA);
581
583 for (UInt_t uFeeB = 0; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; ++uFeeB) {
584
585 if (uFeeA < uFeeB && (!fbEtofFeeIndexing || ((uFeeA % 5) < 3 && (uFeeB % 5) < 3))) {
587 UInt_t uFeeIndexB = uFeeB;
589 if (fbEtofFeeIndexing) { uFeeIndexB = 3 * (uFeeB / 5) + (uFeeB % 5); } // if( fbEtofFeeIndexing )
590
591 UInt_t uGdpbB = uFeeB / (fuNrOfFeePerGdpb);
592 UInt_t uSectorB = uGdpbB + fUnpackPar->GetGdpbToSectorOffset();
593 if (-1 != fiSectorIndex) uSectorB = fiSectorIndex + fUnpackPar->GetGdpbToSectorOffset();
594 // UInt_t uFeeIdB = uFeeB - ( fuNrOfFeePerGdpb * uGdpbB );
595 UInt_t uFeeIdB = uFeeIndexB - (3 * 6 * uGdpbB);
596 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB] =
597 new TH1I(Form("hFeePairPulserTimeDiff_s%02u_f%1u_s%02u_f%1u", uSectorA, uFeeIdA, uSectorB, uFeeIdB),
598 Form("Time difference for pulser on sector %02u FEE %1u and "
599 "sector %02u FEE %1u; DeltaT [ps]; Counts",
600 uSectorA, uFeeIdA, uSectorB, uFeeIdB),
601 uNbBinsDt, dMinDt, dMaxDt);
602
603 AddHistoToVector(fvvhFeePairPulserTimeDiff[uFeeA][uFeeB], Form("TofDt/s%03u", uFeeIndexA));
604 } // if( uFeeA < uFeeB )
605 else
606 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB] = NULL;
607 } // for( UInt_t uFeeB = 0; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; ++uFeeB )
608 } // for( UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; ++uFeeA )
609
611 UInt_t uTotalNbFee = fuNrOfFeePerGdpb * fuNrOfGdpbs;
612 // Double_t dSectorMin = -0.5;
613 // Double_t dSectorMax = fuNrOfGdpbs;
614 if (fbEtofFeeIndexing) {
615 uTotalNbFee = fuNrOfFeePerGdpb * fuNrOfGdpbs * 3 / 5;
616 // dSectorMin = -0.5 + fUnpackPar->GetGdpbToSectorOffset();
617 // dSectorMax = fuNrOfGdpbs + dSectorMin;
618 } // if( fbEtofFeeIndexing )
620 new TH2D("hPulserTimeDiffMean", "Time difference Mean for each FEE pairs; FEE A; FEE B ; Mean [ps]",
621 uTotalNbFee - 1, -0.5, uTotalNbFee - 1.5, uTotalNbFee - 1, 0.5, uTotalNbFee - 0.5);
622
624 new TH2D("hPulserTimeDiffRms", "Time difference RMS for each FEE pairs; FEE A; FEE B ; RMS [ps]", uTotalNbFee - 1,
625 -0.5, uTotalNbFee - 1.5, uTotalNbFee - 1, 0.5, uTotalNbFee - 0.5);
626
627 fhPulserTimeDiffRmsZoom = new TH2D("hPulserTimeDiffRmsZoom",
628 "Time difference RMS for each FEE pairs after zoom on peak; FEE "
629 "A; FEE B ; RMS [ps]",
630 uTotalNbFee - 1, -0.5, uTotalNbFee - 1.5, uTotalNbFee - 1, 0.5, uTotalNbFee - 0.5);
631
632 if (fbEtofFeeIndexing) {
634 new TH2D("hPulserRmsGdpbToRefEvo",
635 "Evo. of Time difference RMS for selected FEE of each sector to "
636 "the 1st; Time in run [s] A; Sector ; RMS [ps]",
637 fuHistoryHistoSize, 0, fuHistoryHistoSize, fuNrOfGdpbs + fUnpackPar->GetGdpbToSectorOffset() - 1, 0.5,
638 fuNrOfGdpbs + fUnpackPar->GetGdpbToSectorOffset() - 0.5);
639
641 new TH2D("hPulserTimeDiffRmsZoom",
642 "Evo. of Time difference RMS for selected FEE pairs of each GBTx to the "
643 "1st in same sector; Time in run [s] A; FEE ; RMS [ps]",
644 fuHistoryHistoSize, 0, fuHistoryHistoSize, uTotalNbFee - 1, 0.5, uTotalNbFee - 0.5);
645 } // if( fbEtofFeeIndexing )
646 else {
648 new TH2D("hPulserRmsGdpbToRefEvo",
649 "Evo. of Time difference RMS for selected FEE of each gDPb to "
650 "the 1st; Time in run [s] A; gDPB ; RMS [ps]",
652
654 new TH2D("hPulserTimeDiffRmsZoom",
655 "Evo. of Time difference RMS for selected FEE pairs of each GBTx to the "
656 "1st in same gDPB; Time in run [s] A; FEE ; RMS [ps]",
657 fuHistoryHistoSize, 0, fuHistoryHistoSize, uTotalNbFee - 1, 0.5, uTotalNbFee - 0.5);
658 } // if( fbEtofFeeIndexing )
659
664 /*******************************************************************/
665
666 /*******************************************************************/
669 fcSummary = new TCanvas("cSummary", "Pulser Monitoring Summary");
670 fcSummary->Divide(3);
671
672 fcSummary->cd(1);
673 gPad->SetGridx();
674 gPad->SetGridy();
675 fhPulserTimeDiffMean->Draw("colz");
676
677 fcSummary->cd(2);
678 gPad->SetGridx();
679 gPad->SetGridy();
680 fhPulserTimeDiffRms->Draw("colz");
681
682 fcSummary->cd(3);
683 gPad->SetGridx();
684 gPad->SetGridy();
685 fhPulserTimeDiffRmsZoom->Draw("colz");
686
687 AddCanvasToVector(fcSummary, "canvases");
689 /*******************************************************************/
690
691 return kTRUE;
692}
694{
698 fhPulserTimeDiffMean->Reset();
699 fhPulserTimeDiffRms->Reset();
701 } // if( 1 == fulCurrentTsIdx % fuUpdateFreqTs && fuNbCoreMsPerTs - 1 == fuMsIndex )
702
703 for (UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++) {
704 UInt_t uGdpbA = uFeeA / (fuNrOfFeePerGdpb);
705 UInt_t uFeeIdA = uFeeA - (fuNrOfFeePerGdpb * uGdpbA);
706
708 if (kFALSE == fvvbFeeHitFound[uGdpbA][uFeeIdA]) continue;
709
710 for (UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++) {
711 UInt_t uGdpbB = uFeeB / (fuNrOfFeePerGdpb);
712 UInt_t uFeeIdB = uFeeB - (fuNrOfFeePerGdpb * uGdpbB);
713
715 if (kFALSE == fvvbFeeHitFound[uGdpbB][uFeeIdB]) continue;
716
717 Double_t dTimeDiff = 1e3 * (fvvdFeeHits[uGdpbB][uFeeIdB] - fvvdFeeHits[uGdpbA][uFeeIdA]);
718 if (TMath::Abs(dTimeDiff) < kdMaxDtPulserPs) {
719 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Fill(dTimeDiff);
720 } // f( TMath::Abs( dTimeDiff ) < kdMaxDtPulserPs )
721
725 UInt_t uFeeIndexA = uFeeA;
726 UInt_t uFeeIndexB = uFeeB;
728 if (fbEtofFeeIndexing) {
729 uFeeIndexA = 3 * (uFeeA / 5) + (uFeeA % 5);
730 uFeeIndexB = 3 * (uFeeB / 5) + (uFeeB % 5);
731 } // if( fbEtofFeeIndexing )
732 fhPulserTimeDiffMean->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetMean());
733 fhPulserTimeDiffRms->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetRMS());
734
736 Int_t iBinWithMax = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetMaximumBin();
737 Double_t dNbCounts = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Integral();
738
740 Double_t dPeakPos = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->GetBinCenter(iBinWithMax);
741 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->SetRangeUser(dPeakPos - kdFitZoomWidthPs,
742 dPeakPos + kdFitZoomWidthPs);
743
745 Double_t dZoomCounts = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Integral();
746
748 if ((dZoomCounts / dNbCounts) < 0.8) {
749 fhPulserTimeDiffRmsZoom->Fill(uFeeIndexA, uFeeIndexB, 0.0);
750 // LOG(warning) << "CbmStar2019MonitorPulserAlgo::FillHistograms => Zoom too strong, "
751 // << "more than 20% loss for FEE pair " << uFeeA << " and " << uFeeB << " !!! ";
752 } // if( ( dZoomCounts / dNbCounts ) < 0.8 )
753 else
754 fhPulserTimeDiffRmsZoom->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetRMS());
755
757 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->UnZoom();
758 /*
759 LOG(info) << "Stats FEE A " << std::setw(3) << uFeeA
760 << " FEE B " << std::setw(3) << uFeeB
761 << Form( " %5.0f %f", fvvhFeePairPulserTimeDiff[ uFeeA ][ uFeeB ]->GetMean(),
762 fvvhFeePairPulserTimeDiff[ uFeeA ][ uFeeB ]->GetRMS() );
763*/
764 } // if( 1 == fulCurrentTsIdx % fuUpdateFreqTs && fuNbCoreMsPerTs - 1 == fuMsIndex )
765 } // for( UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++)
766
768 fvvbFeeHitFound[uGdpbA][uFeeIdA] = kFALSE;
769 } // for( UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++)
770
771 return kTRUE;
772}
774{
775 fhPulserTimeDiffMean->Reset();
776 fhPulserTimeDiffRms->Reset();
778
779 for (UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++) {
780 UInt_t uGdpbA = uFeeA / (fuNrOfFeePerGdpb);
781 UInt_t uFeeIdA = uFeeA - (fuNrOfFeePerGdpb * uGdpbA);
782
783 for (UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++) {
784 // UInt_t uGdpbB = uFeeB / ( fuNrOfFeePerGdpb );
785 // UInt_t uFeeIdB = uFeeB - ( fuNrOfFeePerGdpb * uGdpbB );
786
787 if (nullptr == fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]) continue;
788
790 UInt_t uFeeIndexA = uFeeA;
791 UInt_t uFeeIndexB = uFeeB;
793 if (fbEtofFeeIndexing) {
794 uFeeIndexA = 3 * (uFeeA / 5) + (uFeeA % 5);
795 uFeeIndexB = 3 * (uFeeB / 5) + (uFeeB % 5);
796 } // if( fbEtofFeeIndexing )
797 fhPulserTimeDiffMean->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetMean());
798 fhPulserTimeDiffRms->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetRMS());
799
801 Int_t iBinWithMax = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetMaximumBin();
802 Double_t dNbCounts = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Integral();
803
805 Double_t dPeakPos = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->GetBinCenter(iBinWithMax);
806 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->SetRangeUser(dPeakPos - kdFitZoomWidthPs,
807 dPeakPos + kdFitZoomWidthPs);
808
810 Double_t dZoomCounts = fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Integral();
811
813 if ((dZoomCounts / dNbCounts) < 0.8) {
814 fhPulserTimeDiffRmsZoom->Fill(uFeeIndexA, uFeeIndexB, 0.0);
815 LOG(warning) << "CbmStar2019MonitorPulserAlgo::FillHistograms => Zoom too strong, "
816 << "more than 20% loss for FEE pair " << uFeeA << " and " << uFeeB << " !!! ";
817 continue;
818 } // if( ( dZoomCounts / dNbCounts ) < 0.8 )
819 else
820 fhPulserTimeDiffRmsZoom->Fill(uFeeIndexA, uFeeIndexB, fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetRMS());
821
822
824 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetXaxis()->UnZoom();
825
826 LOG(info) << "Stats FEE A " << std::setw(3) << uFeeIndexA << " FEE B " << std::setw(3) << uFeeIndexB
827 << Form(" %5.0f %f", fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetMean(),
828 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->GetRMS());
829
830 } // for( UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++)
831
833 fvvbFeeHitFound[uGdpbA][uFeeIdA] = kFALSE;
834 } // for( UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++)
835
836 return kTRUE;
837}
839{
840 for (UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++) {
841 for (UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++) {
842 fvvhFeePairPulserTimeDiff[uFeeA][uFeeB]->Reset();
843 } // for( UInt_t uFeeB = uFeeA + 1; uFeeB < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeB++)
844 } // for( UInt_t uFeeA = 0; uFeeA < fuNrOfFeePerGdpb * fuNrOfGdpbs; uFeeA++)
845 fhPulserTimeDiffMean->Reset();
846 fhPulserTimeDiffRms->Reset();
848
849 fdStartTime = -1.0;
850
851 return kTRUE;
852}
853// -------------------------------------------------------------------------
std::string FormatMsHeaderPrintout(const fles::MicrosliceDescriptor &msDescriptor)
int Int_t
bool Bool_t
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.
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