CbmRoot
Loading...
Searching...
No Matches
CbmDeviceUnpackTofStar2018.cxx
Go to the documentation of this file.
1/* Copyright (C) 2018-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Florian Uhlig [committer] */
4
13
14#include "CbmTofUnpackPar.h"
15//#include "CbmHistManager.h"
16#include "CbmTbDaqBuffer.h"
17#include "CbmTofDigiExp.h"
18
19#include "StorableTimeslice.hpp"
20
21#include "FairMQLogger.h"
22#include "FairMQProgOptions.h" // device->fConfig
23
24#include "TH1.h"
25#include "TH2.h"
26
27#include <boost/archive/binary_iarchive.hpp>
28
29#include <iomanip>
30#include <stdexcept>
31#include <string>
32struct InitTaskError : std::runtime_error {
33 using std::runtime_error::runtime_error;
34};
35
36using namespace std;
37
38static Int_t iMess = 0;
39const Int_t DetMask = 0x0001FFFF;
40
42 : fNumMessages(0)
43 , fuMsAcceptsPercent(100)
44 , fuOverlapMsNb(0)
45 , fuMinNbGdpb(0)
46 , fuCurrNbGdpb(0)
47 , fuNrOfGdpbs(0)
48 , fuNrOfFebsPerGdpb(0)
49 , fuNrOfGet4PerFeb(0)
50 , fuNrOfChannelsPerGet4(0)
51 , fuNrOfChannelsPerFeet(0)
52 , fuNrOfGet4(0)
53 , fuNrOfGet4PerGdpb(0)
54 , fuNrOfChannelsPerGdpb(0)
55 , fMsgCounter(11, 0) // length of enum MessageTypes initialized with 0
56 , fGdpbIdIndexMap()
57 , fuGdpbId(0)
58 , fuGdpbNr(0)
59 , fuGet4Id(0)
60 , fuGet4Nr(0)
61 // , fHM(new CbmHistManager())
62 , fvulCurrentEpoch()
63 , fvbFirstEpochSeen()
64 , fNofEpochs(0)
65 , fulCurrentEpochTime(0.)
66 , fEquipmentId(0)
67 , fdMsIndex(0.)
68 , fdTShiftRef(0.)
69 , fbEpochSuppModeOn(kFALSE)
70 , fbGet4M24b(kFALSE)
71 , fbGet4v20(kFALSE)
72 , fbMergedEpochsOn(kFALSE)
73 , fDigi(nullptr)
74 , fUnpackPar(nullptr)
75 , fdRefTime(0.)
76 , fdLastDigiTime(0.)
77 , fdFirstDigiTimeDif(0.)
78 , fdEvTime0(0.)
79 , fhRawTDigEvBmon(nullptr)
80 , fhRawTDigRef0(nullptr)
81 , fhRawTDigRef(nullptr)
82 , fhRawTRefDig0(nullptr)
83 , fhRawTRefDig1(nullptr)
84 , fhRawDigiLastDigi(nullptr)
85 , fhRawTotCh()
86 , fhChCount()
87 , fvbChanThere()
88 , fhChanCoinc()
89 , fhDetChanCoinc(nullptr)
90 , fvmEpSupprBuffer()
91 , fBuffer(CbmTbDaqBuffer::Instance())
92 , fulGdpbTsMsb(0.)
93 , fulGdpbTsLsb(0.)
94 , fulStarTsMsb(0.)
95 , fulStarTsMid(0.)
96 , fulGdpbTsFullLast(0.)
97 , fulStarTsFullLast(0.)
98 , fuStarTokenLast(0)
99 , fuStarDaqCmdLast(0)
100 , fuStarTrigCmdLast(0)
101{
102}
103
105try {
106 // Get the information about created channels from the device
107 // Check if the defined channels from the topology (by name)
108 // are in the list of channels which are possible/allowed
109 // for the device
110 // The idea is to check at initilization if the devices are
111 // properly connected. For the time beeing this is done with a
112 // nameing convention. It is not avoided that someone sends other
113 // data on this channel.
114 int noChannel = fChannels.size();
115 LOG(info) << "Number of defined input channels: " << noChannel;
116 for (auto const& entry : fChannels) {
117 LOG(info) << "Channel name: " << entry.first;
118 if (!IsChannelNameAllowed(entry.first)) throw InitTaskError("Channel name does not match.");
119 OnData(entry.first, &CbmDeviceUnpackTofStar2018::HandleData);
120 }
122}
123catch (InitTaskError& e) {
124 LOG(error) << e.what();
125 ChangeState(ERROR_FOUND);
126}
127
129{
130
131 for (auto const& entry : fAllowedChannels) {
132 std::size_t pos1 = channelName.find(entry);
133 if (pos1 != std::string::npos) {
134 const vector<std::string>::const_iterator pos =
135 std::find(fAllowedChannels.begin(), fAllowedChannels.end(), entry);
136 const vector<std::string>::size_type idx = pos - fAllowedChannels.begin();
137 LOG(info) << "Found " << entry << " in " << channelName;
138 LOG(info) << "Channel name " << channelName << " found in list of allowed channel names at position " << idx;
139 return true;
140 }
141 }
142 LOG(info) << "Channel name " << channelName << " not found in list of allowed channel names.";
143 LOG(error) << "Stop device.";
144 return false;
145}
146
148{
149 LOG(info) << "Init parameter containers for CbmDeviceUnpackTofStar2018.";
150
151 // NewSimpleMessage creates a copy of the data and takes care of its destruction (after the transfer takes place).
152 // Should only be used for small data because of the cost of an additional copy
153 std::string message {"CbmTofUnpackPar,111"};
154 LOG(info) << "Requesting parameter container CbmTofUnpackPar, sending message: " << message;
155
156 FairMQMessagePtr req(NewSimpleMessage("CbmTofUnpackPar,111"));
157 FairMQMessagePtr rep(NewMessage());
158
159 if (Send(req, "parameters") > 0) {
160 if (Receive(rep, "parameters") >= 0) {
161 if (rep->GetSize() != 0) {
162 CbmMqTMessage tmsg(rep->GetData(), rep->GetSize());
163 fUnpackPar = static_cast<CbmTofUnpackPar*>(tmsg.ReadObject(tmsg.GetClass()));
164 LOG(info) << "Received parameter from the server:";
165 fUnpackPar->print();
166 }
167 else {
168 LOG(error) << "Received empty reply. Parameter not available";
169 }
170 }
171 }
172
173
174 Bool_t initOK = ReInitContainers();
175
177
180 fvbChanThere.resize(fUnpackPar->GetNumberOfChannels(), kFALSE);
181 for (UInt_t i = 0; i < fuNrOfGdpbs; ++i) {
182 for (UInt_t j = 0; j < fuNrOfGet4PerGdpb; ++j) {
184 fvbFirstEpochSeen[GetArrayIndex(i, j)] = kFALSE;
185 } // for( UInt_t j = 0; j < fuNrOfGet4PerGdpb; ++j )
186 } // for( UInt_t i = 0; i < fuNrOfGdpbs; ++i )
187
188 return initOK;
189}
190
192{
193 LOG(info) << "ReInit parameter containers for CbmDeviceUnpackTofStar2018.";
194
195 fuNrOfGdpbs = fUnpackPar->GetNrOfRocs();
196 LOG(info) << "Nr. of Tof GDPBs: " << fuNrOfGdpbs;
198
199 fuNrOfFebsPerGdpb = fUnpackPar->GetNrOfFebsPerGdpb();
200 LOG(info) << "Nr. of FEBS per Tof GDPB: " << fuNrOfFebsPerGdpb;
201
202 fuNrOfGet4PerFeb = fUnpackPar->GetNrOfGet4PerFeb();
203 LOG(info) << "Nr. of GET4 per Tof FEB: " << fuNrOfGet4PerFeb;
204
205 fuNrOfChannelsPerGet4 = fUnpackPar->GetNrOfChannelsPerGet4();
206 LOG(info) << "Nr. of channels per GET4: " << fuNrOfChannelsPerGet4;
207
209 LOG(info) << "Nr. of channels per FEET: " << fuNrOfChannelsPerFeet;
210
212 LOG(info) << "Nr. of GET4s: " << fuNrOfGet4;
213
215 LOG(info) << "Nr. of GET4s per GDPB: " << fuNrOfGet4PerGdpb;
216
218 LOG(info) << "Nr. of channels per GDPB: " << fuNrOfChannelsPerGdpb;
219
220 fGdpbIdIndexMap.clear();
221 for (UInt_t i = 0; i < fuNrOfGdpbs; ++i) {
222 fGdpbIdIndexMap[fUnpackPar->GetRocId(i)] = i;
223 LOG(info) << "GDPB Id of TOF " << i << " : " << std::hex << fUnpackPar->GetRocId(i) << std::dec;
224 } // for( UInt_t i = 0; i < fuNrOfGdpbs; ++i )
225 UInt_t uNrOfChannels = fUnpackPar->GetNumberOfChannels();
226 LOG(info) << "Nr. of mapped Tof channels: " << uNrOfChannels;
227 for (UInt_t i = 0; i < uNrOfChannels; ++i) {
228 if (i % 8 == 0) LOG(info);
229 LOG(info) << Form(" 0x%08x", fUnpackPar->GetChannelToDetUIdMap(i));
230 } // for( UInt_t i = 0; i < uNrOfChannels; ++i)
231 LOG(info);
232
233 LOG(info) << "Plot Channel Rate => " << (fUnpackPar->IsChannelRateEnabled() ? "ON" : "OFF");
234
236
237 return kTRUE;
238}
239
241{
242 LOG(info) << "create Histos for " << fuNrOfGdpbs << " gDPBs ";
243
245 new TH1F(Form("Raw_TDig-EvBmon"), Form("Raw digi time difference to 1st digi ; time [ns]; cts"), 500, 0, 100.);
246 // fHM->Add( Form("Raw_TDig-EvBmon"), fhRawTDigEvBmon);
247
249 new TH1F(Form("Raw_TDig-Ref0"), Form("Raw digi time difference to Ref ; time [ns]; cts"), 6000, -10000, 50000);
250 // fHM->Add( Form("Raw_TDig-Ref0"), fhRawTDigRef0);
251
253 new TH1F(Form("Raw_TDig-Ref"), Form("Raw digi time difference to Ref ; time [ns]; cts"), 6000, -1000, 5000);
254 // fHM->Add( Form("Raw_TDig-Ref"), fhRawTDigRef);
255
256 fhRawTRefDig0 = new TH1F(Form("Raw_TRef-Dig0"), Form("Raw Ref time difference to last digi ; time [ns]; cts"), 9999,
257 -50000, 50000);
258 // fHM->Add( Form("Raw_TRef-Dig0"), fhRawTRefDig0);
259
261 new TH1F(Form("Raw_TRef-Dig1"), Form("Raw Ref time difference to last digi ; time [ns]; cts"), 9999, -5000, 5000);
262 // fHM->Add( Form("Raw_TRef-Dig1"), fhRawTRefDig1);
263
264 fhRawDigiLastDigi = new TH1F(Form("Raw_Digi-LastDigi"),
265 Form("Raw Digi time difference to last digi ; time [ns]; cts"), 9999, -5000, 5000);
266 // 9999, -5000000, 5000000);
267 // fHM->Add( Form("Raw_Digi-LastDigi"), fhRawDigiLastDigi);
268
269 fhRawTotCh.resize(fuNrOfGdpbs);
270 fhChCount.resize(fuNrOfGdpbs);
272 for (UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; uGdpb++) {
273 fhRawTotCh[uGdpb] = new TH2F(Form("Raw_Tot_gDPB_%02u", uGdpb), Form("Raw TOT gDPB %02u; channel; TOT [bin]", uGdpb),
274 fuNrOfChannelsPerGdpb, 0., fuNrOfChannelsPerGdpb, 256, 0., 256.);
275 // fHM->Add( Form("Raw_Tot_gDPB_%02u", uGdpb), fhRawTotCh[ uGdpb ]);
276
277 fhChCount[uGdpb] =
278 new TH1I(Form("ChCount_gDPB_%02u", uGdpb), Form("Channel counts gDPB %02u; channel; Hits", uGdpb),
280 // fHM->Add( Form("ChCount_gDPB_%02u", uGdpb), fhChCount[ uGdpb ]);
281 /*
282 for( UInt_t uLeftFeb = uGdpb*fuNrOfFebsPerGdpb / 2;
283 uLeftFeb < (uGdpb + 1 )*fuNrOfFebsPerGdpb / 2;
284 ++uLeftFeb )
285 {
286 fhChanCoinc[ uLeftFeb ] = new TH2F( Form("fhChanCoinc_%02u", uLeftFeb),
287 Form("Channels Coincidence %02; Left; Right", uLeftFeb),
288 fuNrOfChannelsPerFeet, 0., fuNrOfChannelsPerFeet,
289 fuNrOfChannelsPerFeet, 0., fuNrOfChannelsPerFeet );
290 } // for( UInt_t uLeftFeb = 0; uLeftFeb < fuNrOfFebsPerGdpb / 2; uLeftFeb ++ )
291 */
292 fhChanCoinc[uGdpb] =
293 new TH2F(Form("fhChanCoinc_%02u", uGdpb), Form("Channels Coincidence %02u; Left; Right", uGdpb),
295 } // for( UInt_t uGdpb = 0; uGdpb < fuMinNbGdpb; uGdpb ++)
296 fhDetChanCoinc = new TH2F("fhDetChanCoinc", "Det Channels Coincidence; Left; Right", 32, 0., 32, 32, 0., 32);
297}
298
299
300// handler is called whenever a message arrives on "data", with a reference to the message and a sub-channel index (here 0)
301bool CbmDeviceUnpackTofStar2018::HandleData(FairMQMessagePtr& msg, int /*index*/)
302{
303 // Don't do anything with the data
304 // Maybe add an message counter which counts the incomming messages and add
305 // an output
306 fNumMessages++;
307 LOG(info) << "Received message number " << fNumMessages << " with size " << msg->GetSize();
308
309 std::string msgStr(static_cast<char*>(msg->GetData()), msg->GetSize());
310 std::istringstream iss(msgStr);
311 boost::archive::binary_iarchive inputArchive(iss);
312
313 fles::StorableTimeslice component {0};
314 inputArchive >> component;
315
316 CheckTimeslice(component);
317 DoUnpack(component, 0);
318
319 return true;
320}
321
322Bool_t CbmDeviceUnpackTofStar2018::DoUnpack(const fles::Timeslice& ts, size_t component)
323{
324 LOG(debug) << "Timeslice contains " << ts.num_microslices(component) << " microslices of component " << component;
325
326 // Loop over microslices
327 Int_t iMessageType = -111;
328 size_t numCompMsInTs = ts.num_microslices(component);
329 for (size_t m = 0; m < numCompMsInTs; ++m) {
330 // Jump some microslices if needed
331 // if( fuMsAcceptsPercent < m)
332 // continue;
333
334 // Ignore overlap ms if number defined by user
335 if (numCompMsInTs - fuOverlapMsNb <= m) continue;
336
337 constexpr uint32_t kuBytesPerMessage = 8;
338
339 auto msDescriptor = ts.descriptor(component, m);
340 fEquipmentId = msDescriptor.eq_id;
341 fdMsIndex = static_cast<double>(msDescriptor.idx);
342 const uint8_t* msContent = reinterpret_cast<const uint8_t*>(ts.content(component, m));
343
344 uint32_t size = msDescriptor.size;
345 if (0 < size) LOG(debug) << "Microslice " << m << ": " << fdMsIndex << " has size: " << size;
346
347 // If not integer number of message in input buffer, print warning/error
348 if (0 != (size % kuBytesPerMessage))
349 LOG(error) << "The input microslice buffer does NOT "
350 << "contain only complete nDPB messages!";
351
352 // If not integer number of message in input buffer, print warning/error
353 if (0 != (size % kuBytesPerMessage))
354 LOG(error) << "The input microslice buffer does NOT "
355 << "contain only complete nDPB messages!";
356
357 // Compute the number of complete messages in the input microslice buffer
358 uint32_t uNbMessages = (size - (size % kuBytesPerMessage)) / kuBytesPerMessage;
359
360 // Prepare variables for the loop on contents
361 const uint64_t* pInBuff = reinterpret_cast<const uint64_t*>(msContent);
362 for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx++) {
363 // Fill message
364 uint64_t ulData = static_cast<uint64_t>(pInBuff[uIdx]);
365 ngdpb::Message mess(ulData);
366
367 /*
368 if(fair::Logger::Logging(fair::Severity::debug)
369 {
370 mess.printDataCout();
371 }
372 */
373
374 // Increment counter for different message types
375 iMessageType = mess.getMessageType();
376 fMsgCounter[iMessageType]++;
377
378 fuGdpbId = mess.getRocNumber();
380
381 fuGet4Id = mess.getGdpbGenChipId();
383
384 if (fuNrOfGet4PerGdpb <= fuGet4Id && ngdpb::MSG_STAR_TRI != iMessageType
385 && (get4v1x::kuChipIdMergedEpoch != fuGet4Id || kFALSE == fbMergedEpochsOn)) {
386 LOG(warn) << "Message with Get4 ID too high: " << fuGet4Id << " VS " << fuNrOfGet4PerGdpb
387 << " set in parameters, message ignored";
388 continue;
389 }
390
391 switch (mess.getMessageType()) {
392 case ngdpb::MSG_HIT:
393 case ngdpb::MSG_EPOCH:
394 case ngdpb::MSG_GET4: {
395 if (fbGet4M24b) FillHitInfo(mess);
396 else
397 PrintGenInfo(mess);
398 break;
399 } // case old non tof messages
400 case ngdpb::MSG_EPOCH2: {
401 if (get4v1x::kuChipIdMergedEpoch == fuGet4Id && kTRUE == fbMergedEpochsOn) {
402 for (uint32_t uGet4Index = 0; uGet4Index < fuNrOfGet4PerGdpb; uGet4Index++) {
403 fuGet4Id = uGet4Index;
405 ngdpb::Message tmpMess(mess);
406 tmpMess.setGdpbGenChipId(uGet4Index);
407 // fHistGet4MessType->Fill(uGet4Index, ngdpb::GET4_32B_EPOCH);
408 FillEpochInfo(tmpMess);
409 } // for( uint32_t uGet4Index = 0; uGet4Index < fuNrOfGet4PerGdpb; uGetIndex ++ )
410 } // if this epoch message is a merged one valiud for all chips
411 else {
412 // fHistGet4MessType->Fill( fuGet4Nr, ngdpb::GET4_32B_EPOCH );
413 FillEpochInfo(mess);
414 } // if single chip epoch message
415 break;
416 } // case ngdpb::MSG_EPOCH2:
417 case ngdpb::MSG_GET4_32B: {
418 if (fbEpochSuppModeOn) {
419 fvmEpSupprBuffer[fuGet4Nr].push_back(mess);
420 LOG(debug) << "Add 32B message from Gdpb " << fuGdpbNr << " to EpSupprBuffer of Get4 " << fuGet4Nr
421 << " size " << fvmEpSupprBuffer[fuGet4Nr].size();
422 }
423 else
424 FillHitInfo(mess);
425 break;
426
427 } // case ngdpb::MSG_GET4_32B:
428 case ngdpb::MSG_GET4_SLC: {
429 PrintSlcInfo(mess);
430 break;
431 } // case ngdpb::MSG_GET4_SLC:
432 case ngdpb::MSG_GET4_SYS: {
433 if (100 > iMess++) PrintSysInfo(mess);
434 break;
435 } // case ngdpb::MSG_GET4_SYS:
436 case ngdpb::MSG_STAR_TRI: {
437 FillStarTrigInfo(mess);
438 break;
439 } // case ngdpb::MSG_STAR_TRI:
440 default: {
441 if (100 > iMess++)
442 LOG(error) << "Message (" << iMess << ") type " << std::hex << std::setw(2)
443 << static_cast<uint16_t>(mess.getMessageType()) << " not included in Get4 unpacker.";
444 if (100 == iMess) LOG(error) << "Stop reporting MSG errors... ";
445 } // default:
446 } // switch( mess.getMessageType() )
447
448 } // for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx ++)
449
450 } // for (size_t m = 0; m < numCompMsInTs; ++m)
451
452
453 return kTRUE;
454}
455
457{
458 // --- Get absolute time, GET4 ID and channel number
459 UInt_t uGet4Id = mess.getGdpbGenChipId();
460 UInt_t uChannel = mess.getGdpbHitChanId();
461 UInt_t uTot = mess.getGdpbHit32Tot();
462 // UInt_t uFts = mess.getGdpbHitFineTs();
463
464 ULong_t ulCurEpochGdpbGet4 = fvulCurrentEpoch[fuGet4Nr];
465
466 if (kTRUE == fvbFirstEpochSeen[fuGet4Nr]) {
467 // In Ep. Suppr. Mode, receive following epoch instead of previous
468 if (0 < ulCurEpochGdpbGet4) ulCurEpochGdpbGet4--;
469 else
470 ulCurEpochGdpbGet4 = get4v1x::kuEpochCounterSz; // Catch epoch cycle!
471
472 // ULong_t ulhitTime;
473 Double_t dHitTime;
474 if (fbGet4v20) {
475 // ulhitTime = mess.getMsgG4v2FullTime( ulCurEpochGdpbGet4 );
476 dHitTime = mess.getMsgG4v2FullTimeD(ulCurEpochGdpbGet4);
477
478 // In 32b mode the coarse counter is already computed back to 112 FTS bins
479 // => need to hide its contribution from the Finetime
480 // => FTS = Fullt TS modulo 112
481 // if( !fbGet4M24b )
482 // uFts = mess.getGdpbHitFullTs() % 112;
483 } // if( fbGet4v20 )
484 else {
485 // ulhitTime = mess.getMsgFullTime(ulCurEpochGdpbGet4);
486 dHitTime = mess.getMsgFullTimeD(ulCurEpochGdpbGet4);
487 } // else of if( fbGet4v20 )
488
489 Double_t dHitTot = uTot; // in bins
490
491
492 // UInt_t uFebIdx = (uGet4Id / fuNrOfGet4PerFeb);
493 // UInt_t uFullFebIdx = (fuGdpbNr * fuNrOfFebsPerGdpb) + uFebIdx;
494
495 UInt_t uChanInGdpb = uGet4Id * fuNrOfChannelsPerGet4 + uChannel;
496 Int_t uChanInSyst = fuGdpbNr * fuNrOfChannelsPerGdpb + uChanInGdpb;
497 if (fUnpackPar->GetNumberOfChannels() < uChanInSyst) {
498 LOG(error) << "Invalid mapping index " << uChanInSyst << " VS " << fUnpackPar->GetNumberOfChannels() << ", from "
499 << fuGdpbNr << ", " << uGet4Id << ", " << uChannel;
500 return;
501 } // if( fUnpackPar->GetNumberOfChannels() < uChanUId )
502
503 fvbChanThere[uChanInSyst] = kTRUE;
504
505 UInt_t uChanUId = fUnpackPar->GetChannelToDetUIdMap(uChanInSyst);
506 if (0 == uChanUId) return; // Hit not mapped to digi
507
508 /*
509 if( (uChanUId & DetMask) == 0x00001006 )
510 {
511 UInt_t uDetChan = (uChanUId & 0xFF000000) >> 24;
512 if( (uChanUId & 0x00800000) == 0x00800000 )
513 uDetChan += 32;
514
515 fbDetChanThere[ uDetChan ] = kTRUE;
516 } // if( (uChanUId & DetMask) == 0x00001006 )
517 */
518 // fhRawDigiLastDigi->Fill( dHitTime - fdLastDigiTime );
519
520 if ((uChanUId & DetMask) != 0x00005006) dHitTime += fdTShiftRef;
521 fdLastDigiTime = dHitTime;
522
523 LOG(debug) << Form("Insert 0x%08x digi with time ", uChanUId) << dHitTime << Form(", Tot %4.0f", dHitTot)
524 << " into buffer with " << fBuffer->GetSize() << " data from "
525 << Form("%11.1f to %11.1f ", fBuffer->GetTimeFirst(), fBuffer->GetTimeLast()) << " at epoch "
526 << ulCurEpochGdpbGet4;
527
528 fDigi = new CbmTofDigiExp(uChanUId, dHitTime, dHitTot);
529
530 fBuffer->InsertData<CbmTofDigiExp>(fDigi);
531
532 // Histograms filling
533 fhRawTotCh[fuGdpbNr]->Fill(uChanInGdpb, dHitTot);
534 fhChCount[fuGdpbNr]->Fill(uChanInGdpb);
535
536 } // if( kTRUE == fvbFirstEpochSeen[ fuGet4Nr ] )
537}
538
540{
541 ULong64_t ulEpochNr = mess.getGdpbEpEpochNb();
542
543 // LOG(debug) << "Get4Nr "<<fuGet4Nr<< " in epoch "<<ulEpochNr;
544
545 fvulCurrentEpoch[fuGet4Nr] = ulEpochNr;
546
547 if (kFALSE == fvbFirstEpochSeen[fuGet4Nr]) fvbFirstEpochSeen[fuGet4Nr] = kTRUE;
548
549 fulCurrentEpochTime = mess.getMsgFullTime(ulEpochNr);
550 fNofEpochs++;
551
555 if (0 < ulEpochNr) mess.setEpoch2Number(ulEpochNr - 1);
556 else
557 mess.setEpoch2Number(get4v1x::kuEpochCounterSz);
558
559 Int_t iBufferSize = fvmEpSupprBuffer[fuGet4Nr].size();
560 if (0 < iBufferSize) {
561 LOG(debug) << "Now processing " << iBufferSize << " stored messages for get4 " << fuGet4Nr << " with epoch number "
562 << (fvulCurrentEpoch[fuGet4Nr] - 1);
563
564 for (Int_t iMsgIdx = 0; iMsgIdx < iBufferSize; iMsgIdx++) {
566 } // for( Int_t iMsgIdx = 0; iMsgIdx < iBufferSize; iMsgIdx++ )
567 /*
568 for( UInt_t uLeftFeb = fuGdpbNr * fuNrOfFebsPerGdpb / 2;
569 uLeftFeb < (fuGdpbNr + 1) * fuNrOfFebsPerGdpb / 2;
570 ++uLeftFeb )
571 {
572 for( UInt_t uChanA = 2*uLeftFeb * fuNrOfChannelsPerFeet;
573 uChanA < (2*uLeftFeb + 1) * fuNrOfChannelsPerFeet;
574 ++uChanA )
575 {
576 if( kTRUE == fvbChanThere[ uChanA ] )
577 {
578 for( UInt_t uChanB = (2*uLeftFeb + 1) * fuNrOfChannelsPerFeet;
579 uChanB < (2*uLeftFeb + 2) * fuNrOfChannelsPerFeet;
580 ++uChanB )
581 {
582 if( kTRUE == fvbChanThere[ uChanB ] )
583 {
584 fhChanCoinc[ uLeftFeb ]->Fill( uChanA, uChanB );
585 }
586 }
587 }
588 }
589 } // for( UInt_t uLeftFeb = 0; uLeftFeb < fuNrOfFebsPerGdpb / 2; ++uLeftFeb )
590*/
591 fvmEpSupprBuffer[fuGet4Nr].clear();
592 } // if( 0 < fvmEpSupprBuffer[fGet4Nr] )
593}
594
595void CbmDeviceUnpackTofStar2018::PrintSlcInfo(ngdpb::Message /*mess*/)
596{
598 /*
599 if( fGdpbIdIndexMap.end() != fGdpbIdIndexMap.find( rocId ) )
600 LOG(info) << "GET4 Slow Control message, epoch " << static_cast<Int_t>(fCurrentEpoch[rocId][get4Id])
601 << ", time " << std::setprecision(9) << std::fixed
602 << Double_t(fulCurrentEpochTime) * 1.e-9 << " s "
603 << " for board ID " << std::hex << std::setw(4) << rocId << std::dec
604 << " +++++++ > Chip = " << std::setw(2) << mess.getGdpbGenChipId()
605 << ", Chan = " << std::setw(1) << mess.getGdpbSlcChan()
606 << ", Edge = " << std::setw(1) << mess.getGdpbSlcEdge()
607 << ", Type = " << std::setw(1) << mess.getGdpbSlcType()
608 << ", Data = " << std::hex << std::setw(6) << mess.getGdpbSlcData() << std::dec
609 << ", Type = " << mess.getGdpbSlcCrc();
610*/
611}
612
614{
615 Int_t mType = mess.getMessageType();
616 Int_t rocId = mess.getRocNumber();
617 Int_t get4Id = mess.getGdpbGenChipId();
618 Int_t channel = mess.getGdpbHitChanId();
619 uint64_t uData = mess.getData();
620 if (100 > iMess++)
621 LOG(info) << "Get4 MSG type " << mType << " from rocId " << rocId << ", getId " << get4Id << ", (hit channel) "
622 << channel << Form(" hex data %0lx ", uData);
623}
624
626{
627 LOG(info) << "GET4 System message, epoch " << (fvulCurrentEpoch[fuGet4Nr]) << ", time " << std::setprecision(9)
628 << std::fixed << Double_t(fulCurrentEpochTime) * 1.e-9 << " s "
629 << " for board ID " << std::hex << std::setw(4) << fuGdpbId << std::dec;
630
631 switch (mess.getGdpbSysSubType()) {
632 case ngdpb::SYSMSG_GET4_EVENT: {
633 LOG(info) << " +++++++ > Chip = " << std::setw(2) << mess.getGdpbGenChipId() << ", Chan = " << std::setw(1)
634 << mess.getGdpbSysErrChanId() << ", Edge = " << std::setw(1) << mess.getGdpbSysErrEdge()
635 << ", Empt = " << std::setw(1) << mess.getGdpbSysErrUnused() << ", Data = " << std::hex << std::setw(2)
636 << mess.getGdpbSysErrData() << std::dec << " -- GET4 V1 Error Event";
637 break;
638 } //
639 case ngdpb::SYSMSG_CLOSYSYNC_ERROR: LOG(info) << "Closy synchronization error"; break;
640 case ngdpb::SYSMSG_TS156_SYNC: LOG(info) << "156.25MHz timestamp reset"; break;
641 case ngdpb::SYSMSG_GDPB_UNKWN:
642 LOG(info) << "Unknown GET4 message, data: " << std::hex << std::setw(8) << mess.getGdpbSysUnkwData() << std::dec;
643 break;
644 } // switch( getGdpbSysSubType() )
645}
646
648{
649 Int_t iMsgIndex = mess.getStarTrigMsgIndex();
650
651 //mess.printDataCout();
652
653 switch (iMsgIndex) {
654 case 0: fulGdpbTsMsb = mess.getGdpbTsMsbStarA(); break;
655 case 1:
656 fulGdpbTsLsb = mess.getGdpbTsLsbStarB();
657 fulStarTsMsb = mess.getStarTsMsbStarB();
658 break;
659 case 2: fulStarTsMid = mess.getStarTsMidStarC(); break;
660 case 3: {
661 ULong64_t ulNewGdpbTsFull = (fulGdpbTsMsb << 24) + (fulGdpbTsLsb);
662 ULong64_t ulNewStarTsFull = (fulStarTsMsb << 48) + (fulStarTsMid << 8) + mess.getStarTsLsbStarD();
663 UInt_t uNewToken = mess.getStarTokenStarD();
664 UInt_t uNewDaqCmd = mess.getStarDaqCmdStarD();
665 UInt_t uNewTrigCmd = mess.getStarTrigCmdStarD();
666 if ((uNewToken == fuStarTokenLast) && (ulNewGdpbTsFull == fulGdpbTsFullLast)
667 && (ulNewStarTsFull == fulStarTsFullLast) && (uNewDaqCmd == fuStarDaqCmdLast)
668 && (uNewTrigCmd == fuStarTrigCmdLast)) {
669 LOG(debug) << "Possible error: identical STAR tokens found twice in a "
670 "row => ignore 2nd! "
671 << Form("token = %5u ", fuStarTokenLast) << Form("gDPB ts = %12llu ", fulGdpbTsFullLast)
672 << Form("STAR ts = %12llu ", fulStarTsFullLast) << Form("DAQ cmd = %2u ", fuStarDaqCmdLast)
673 << Form("TRG cmd = %2u ", fuStarTrigCmdLast);
674 return;
675 } // if exactly same message repeated
676 /*
677 if( (uNewToken != fuStarTokenLast + 1) &&
678 0 < fulGdpbTsFullLast && 0 < fulStarTsFullLast &&
679 ( 4095 != fuStarTokenLast || 1 != uNewToken) )
680 LOG(warn) << "Possible error: STAR token did not increase by exactly 1! "
681 << Form("old = %5u vs new = %5u ", fuStarTokenLast, uNewToken)
682 << Form("old = %12llu vs new = %12llu ", fulGdpbTsFullLast, ulNewGdpbTsFull)
683 << Form("old = %12llu vs new = %12llu ", fulStarTsFullLast, ulNewStarTsFull)
684 << Form("old = %2u vs new = %2u ", fuStarDaqCmdLast, uNewDaqCmd)
685 << Form("old = %2u vs new = %2u ", fuStarTrigCmdLast, uNewTrigCmd);
686*/
687 fulGdpbTsFullLast = ulNewGdpbTsFull;
688 fulStarTsFullLast = ulNewStarTsFull;
689 fuStarTokenLast = uNewToken;
690 fuStarDaqCmdLast = uNewDaqCmd;
691 fuStarTrigCmdLast = uNewTrigCmd;
692
693 Double_t dTot = 1.;
694 Double_t dTime = fulGdpbTsFullLast * 6.25;
695 if (0. == fdFirstDigiTimeDif && 0. != fdLastDigiTime) {
697 LOG(info) << "Reference fake digi time shift initialized to " << fdFirstDigiTimeDif
698 << ", default: " << fdTShiftRef;
699 } // if( 0. == fdFirstDigiTimeDif && 0. != fdLastDigiTime )
700
701 // dTime -= fdFirstDigiTimeDif;
702 // dTime += fdTShiftRef;
703
704 LOG(debug) << "Insert fake digi with time " << dTime << ", Tot " << dTot;
705 fhRawTRefDig0->Fill(dTime - fdLastDigiTime);
706 fhRawTRefDig1->Fill(dTime - fdLastDigiTime);
707
708 fDigi = new CbmTofDigiExp(0x00005006, dTime, dTot); // fake start counter signal
709 fBuffer->InsertData<CbmTofDigiExp>(fDigi);
710 break;
711 } // case 3
712 default: LOG(error) << "Unknown Star Trigger messageindex: " << iMsgIndex;
713 } // switch( iMsgIndex )
714}
715
717
718
719void CbmDeviceUnpackTofStar2018::PrintMicroSliceDescriptor(const fles::MicrosliceDescriptor& mdsc)
720{
721 LOG(info) << "Header ID: Ox" << std::hex << static_cast<int>(mdsc.hdr_id) << std::dec;
722 LOG(info) << "Header version: Ox" << std::hex << static_cast<int>(mdsc.hdr_ver) << std::dec;
723 LOG(info) << "Equipement ID: " << mdsc.eq_id;
724 LOG(info) << "Flags: " << mdsc.flags;
725 LOG(info) << "Sys ID: Ox" << std::hex << static_cast<int>(mdsc.sys_id) << std::dec;
726 LOG(info) << "Sys version: Ox" << std::hex << static_cast<int>(mdsc.sys_ver) << std::dec;
727 LOG(info) << "Microslice Idx: " << mdsc.idx;
728 LOG(info) << "Checksum: " << mdsc.crc;
729 LOG(info) << "Size: " << mdsc.size;
730 LOG(info) << "Offset: " << mdsc.offset;
731}
732
733bool CbmDeviceUnpackTofStar2018::CheckTimeslice(const fles::Timeslice& ts)
734{
735 if (0 == ts.num_components()) {
736 LOG(error) << "No Component in TS " << ts.index();
737 return 1;
738 }
739 LOG(info) << "Found " << ts.num_components() << " different components in timeslice";
740
741 for (size_t c = 0; c < ts.num_components(); ++c) {
742 LOG(info) << "Found " << ts.num_microslices(c) << " microslices in component " << c;
743 LOG(info) << "Component " << c << " has a size of " << ts.size_component(c) << " bytes";
744 LOG(info) << "Sys ID: Ox" << std::hex << static_cast<int>(ts.descriptor(0, 0).sys_id) << std::dec;
745
746 /*
747 for (size_t m = 0; m < ts.num_microslices(c); ++m) {
748 PrintMicroSliceDescriptor(ts.descriptor(c,m));
749 }
750*/
751 }
752
753 return true;
754}
static Int_t iMess
const Int_t DetMask
static Int_t iMess
const Int_t DetMask
static constexpr size_t size()
Definition KfSimdPseudo.h:2
std::vector< std::vector< ngdpb::Message > > fvmEpSupprBuffer
void PrintMicroSliceDescriptor(const fles::MicrosliceDescriptor &mdsc)
std::vector< ULong64_t > fvulCurrentEpoch
Bool_t DoUnpack(const fles::Timeslice &ts, size_t component)
bool HandleData(FairMQMessagePtr &, int)
bool IsChannelNameAllowed(std::string channelName)
bool CheckTimeslice(const fles::Timeslice &ts)
std::vector< std::string > fAllowedChannels
std::map< UInt_t, UInt_t > fGdpbIdIndexMap
Int_t GetArrayIndex(Int_t gdpbId, Int_t get4Id)
Singleton buffer class for CBM raw data.
Double_t GetTimeLast() const
Int_t GetSize() const
Double_t GetTimeFirst() const
void InsertData(Digi *digi)
Hash for CbmL1LinkKey.