CbmRoot
Loading...
Searching...
No Matches
CbmDeviceUnpackTofMcbm2018.cxx
Go to the documentation of this file.
1/* Copyright (C) 2018-2020 PI-UHd, GSI
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Florian Uhlig, Norbert Herrmann [committer] */
4
13
14#include "CbmDefs.h"
15#include "CbmMQDefs.h"
16#include "CbmMcbm2018TofPar.h"
18//#include "CbmHistManager.h"
19#include "CbmTbDaqBuffer.h"
20#include "CbmTofAddress.h"
21#include "CbmTofDetectorId_v21a.h" // in cbmdata/tof
22#include "CbmTofDigi.h"
23
24#include "StorableTimeslice.hpp"
25
26#include "FairMQLogger.h"
27#include "FairMQProgOptions.h" // device->fConfig
28#include "FairParGenericSet.h"
29#include "FairRuntimeDb.h"
30
31#include "TH1.h"
32#include "TH2.h"
33
34#include <boost/archive/binary_iarchive.hpp>
35#include <boost/archive/binary_oarchive.hpp>
36
37// include this header to serialize vectors
38#include <boost/serialization/vector.hpp>
39
40#include <array>
41#include <iomanip>
42#include <stdexcept>
43#include <string>
44struct InitTaskError : std::runtime_error {
45 using std::runtime_error::runtime_error;
46};
47
48using namespace std;
49
50//static Int_t iMess=0;
51//const Int_t DetMask = 0x001FFFFF;
52
54 : fNumMessages(0)
56 , fNumTint(0)
57 , fEventHeader()
58 , fiReqMode(0)
59 , fiReqTint(0)
60 , fiReqBeam(-1)
61 , fiReqDigiAddr()
62 , fiPulserMode(0)
63 , fiPulMulMin(0)
64 , fiPulTotMin(0)
65 , fiPulTotMax(1000)
66 , fuTotalMsNb(0)
67 , fuOverlapMsNb(0)
68 , fuCoreMs(0)
69 , fdMsSizeInNs(0)
70 , fdTsCoreSizeInNs(0)
71 , fuMinNbGdpb(0)
72 , fuNrOfGdpbs(0)
73 , fuNrOfFeePerGdpb(0)
74 , fuNrOfGet4PerFee(0)
75 , fuNrOfChannelsPerGet4(0)
76 , fuNrOfChannelsPerFee(0)
77 , fuNrOfGet4(0)
78 , fuNrOfGet4PerGdpb(0)
79 , fuNrOfChannelsPerGdpb(0)
80 , fuGdpbId(0)
81 , fuGdpbNr(0)
82 , fuGet4Id(0)
83 , fuGet4Nr(0)
84 , fMsgCounter(11, 0) // length of enum MessageTypes initialized with 0
85 , fGdpbIdIndexMap()
86 , fvulCurrentEpoch()
87 , fvbFirstEpochSeen()
88 , fNofEpochs(0)
89 , fulCurrentEpochTime(0.)
90 //, fdMsIndex(0.)
91 , fdToffTof(0.)
92 , fiAddrRef(0)
93 //, fuDiamondDpbIdx(3)
94 //, fbEpochSuppModeOn( kTRUE )
95 //, fbGet4M24b( kFALSE )
96 //, fbGet4v20( kTRUE )
97 //, fbMergedEpochsOn( kTRUE )
98 , fUnpackPar(nullptr)
99 , fdLastDigiTime(0.)
100 , fdFirstDigiTimeDif(0.)
101 //, fdEvTime0(0.)
102 , fhRawTDigEvBmon(nullptr)
103 , fhRawTDigRef0(nullptr)
104 , fhRawTDigRef(nullptr)
105 , fhRawTRefDig0(nullptr)
106 , fhRawTRefDig1(nullptr)
107 , fhRawDigiLastDigi(nullptr)
108 , fhRawTotCh()
109 , fhChCount()
110 , fvbChanThere()
111 , fhChanCoinc()
112 , fhDetChanCoinc(nullptr)
113 , fvuPadiToGet4()
114 , fvuGet4ToPadi()
115 , fvuElinkToGet4()
116 , fvuGet4ToElink()
117 , fviRpcType()
118 , fviModuleId()
119 , fviNrOfRpc()
120 , fviRpcSide()
121 , fviRpcChUId()
122 , fBuffer(CbmTbDaqBuffer::Instance())
123 , fUnpackerAlgo(nullptr)
124{
126}
127
129
131try {
132 // Get the information about created channels from the device
133 // Check if the defined channels from the topology (by name)
134 // are in the list of channels which are possible/allowed
135 // for the device
136 // The idea is to check at initilization if the devices are
137 // properly connected. For the time beeing this is done with a
138 // nameing convention. It is not avoided that someone sends other
139 // data on this channel.
140 //logger::SetLogLevel("INFO");
141
142 int noChannel = fChannels.size();
143 LOG(info) << "Number of defined channels: " << noChannel;
144 for (auto const& entry : fChannels) {
145 LOG(info) << "Channel name: " << entry.first;
146 if (!IsChannelNameAllowed(entry.first)) throw InitTaskError("Channel name does not match.");
147 if (entry.first == "syscmd") {
148 OnData(entry.first, &CbmDeviceUnpackTofMcbm2018::HandleMessage);
149 continue;
150 }
151 //if(entry.first != "tofdigis") OnData(entry.first, &CbmDeviceUnpackTofMcbm2018::HandleData);
152 if (entry.first != "tofdigis") OnData(entry.first, &CbmDeviceUnpackTofMcbm2018::HandleParts);
153 else {
154 fChannelsToSend[0].push_back(entry.first);
155 LOG(info) << "Init to send data to channel " << fChannelsToSend[0][0];
156 }
157 }
159 const Int_t iHeaderSize = 4;
160 fEventHeader.resize(iHeaderSize); // define size of eventheader int[]
161 for (int i = 0; i < iHeaderSize; i++)
162 fEventHeader[i] = 0;
163 LOG(info) << "Read config";
164 fiSelectComponents = fConfig->GetValue<uint64_t>("SelectComponents");
165 fiReqMode = fConfig->GetValue<uint64_t>("ReqMode");
166 fiReqTint = fConfig->GetValue<uint64_t>("ReqTint");
167 fiReqBeam = fConfig->GetValue<uint64_t>("ReqBeam");
168 fiPulserMode = fConfig->GetValue<int64_t>("PulserMode");
169 fiPulMulMin = fConfig->GetValue<uint64_t>("PulMulMin");
170 fiPulTotMin = fConfig->GetValue<uint64_t>("PulTotMin");
171 fiPulTotMax = fConfig->GetValue<uint64_t>("PulTotMax");
172 fdToffTof = fConfig->GetValue<double_t>("ToffTof");
173 Int_t iRefModType = fConfig->GetValue<int64_t>("RefModType");
174 Int_t iRefModId = fConfig->GetValue<int64_t>("RefModId");
175 Int_t iRefCtrType = fConfig->GetValue<int64_t>("RefCtrType");
176 Int_t iRefCtrId = fConfig->GetValue<int64_t>("RefCtrId");
177 if (iRefModType > -1)
178 fiAddrRef = CbmTofAddress::GetUniqueAddress(iRefModId, iRefCtrId, 0, 0, iRefModType, iRefCtrType);
179 LOG(info) << " Using Reference counter address 0x" << std::hex << fiAddrRef;
180
181 // Int_t iMaxAsicInactive = fConfig->GetValue<uint64_t>("MaxAsicInactive");
182 // fUnpackerAlgo->SetMaxAsicInactive( iMaxAsicInactive );
183 Int_t iReqDet = 1;
184 Int_t iNReq = 0;
185 const Int_t iMaxReq = 50;
186
187 while (iNReq < iMaxReq) { // FIXME, setup parameter hardwired!
188 iReqDet = fConfig->GetValue<uint64_t>(Form("ReqDet%d", iNReq));
189 if (iReqDet == 0) break;
190 AddReqDigiAddr(iReqDet);
191 iNReq++;
192 }
193 LOG(info) << "Setup request";
194 if (fiReqMode > 0)
195 if (iNReq == 0) { // take all defined detectors
196 for (UInt_t iGbtx = 0; iGbtx < fviNrOfRpc.size(); iGbtx++) {
197 switch (fviRpcType[iGbtx]) {
198 case 0: // mTof modules
199 case 1: // eTof modules
200 if (iGbtx % 2 == 0)
201 for (Int_t iRpc = 0; iRpc < fviNrOfRpc[iGbtx]; iRpc++) {
202 Int_t iAddr = CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx], iRpc, 0, 0, fviRpcType[iGbtx]);
203 AddReqDigiAddr(iAddr);
204 }
205 break;
206
207 case 4:
208 case 9: // HD 2-RPC boxes
209 for (Int_t iRpc = 0; iRpc < 2; iRpc++) {
210 Int_t iAddr = CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx], iRpc, 0, 0, fviRpcType[iGbtx]);
211 AddReqDigiAddr(iAddr);
212 }
213 break;
214 case 6: // Buc box
215 for (Int_t iRpc = 0; iRpc < 2; iRpc++) {
216 Int_t iAddr = CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx], iRpc, 0, 0, fviRpcType[iGbtx]);
217 AddReqDigiAddr(iAddr);
218 }
219 break;
220
221 case 7: // CERN box
222 for (Int_t iRpc = 0; iRpc < 1; iRpc++) {
223 Int_t iAddr = CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx], iRpc, 0, 0, 7);
224 AddReqDigiAddr(iAddr);
225 }
226 break;
227 case 8: // ceramics
228 for (Int_t iRpc = 0; iRpc < 8; iRpc++) {
229 Int_t iAddr = CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx], iRpc, 0, 0, fviRpcType[iGbtx]);
230 AddReqDigiAddr(iAddr);
231 }
232 break;
233 case 5: // add Diamond, single cell RPC
234 Int_t iAddr = CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx], 0, 0, 0, 5);
235 AddReqDigiAddr(iAddr);
236 break;
237 }
238 }
239 }
240
241 LOG(info) << "ReqMode " << fiReqMode << " in " << fiReqTint << " ns "
242 << " with " << fiReqDigiAddr.size() << " detectors out of " << fviNrOfRpc.size() << " GBTx, PulserMode "
243 << fiPulserMode << " with Mul " << fiPulMulMin << ", TotMin " << fiPulTotMin;
244 LOG(info) << Form("ReqBeam 0x%08x", (uint) fiReqBeam);
245}
246catch (InitTaskError& e) {
247 LOG(error) << e.what();
248 // Wrapper defined in CbmMQDefs.h to support different FairMQ versions
250}
251
253{
254 for (auto const& entry : fAllowedChannels) {
255 LOG(info) << "Inspect " << entry;
256 std::size_t pos1 = channelName.find(entry);
257 if (pos1 != std::string::npos) {
258 const vector<std::string>::const_iterator pos =
259 std::find(fAllowedChannels.begin(), fAllowedChannels.end(), entry);
260 const vector<std::string>::size_type idx = pos - fAllowedChannels.begin();
261 LOG(info) << "Found " << entry << " in " << channelName;
262 LOG(info) << "Channel name " << channelName << " found in list of allowed channel names at position " << idx;
263 return true;
264 }
265 }
266 LOG(info) << "Channel name " << channelName << " not found in list of allowed channel names.";
267 LOG(error) << "Stop device.";
268 return false;
269}
270
272{
273 LOG(info) << "Init parameter containers for CbmDeviceUnpackTofMcbm2018.";
274 // FairRuntimeDb* fRtdb = FairRuntimeDb::instance();
275
276 // NewSimpleMessage creates a copy of the data and takes care of its destruction (after the transfer takes place).
277 // Should only be used for small data because of the cost of an additional copy
278 std::string message {"CbmMcbm2018TofPar,111"};
279 LOG(info) << "Requesting parameter container CbmMcbm2018TofPar, sending message: " << message;
280
281 FairMQMessagePtr req(NewSimpleMessage("CbmMcbm2018TofPar,111"));
282 FairMQMessagePtr rep(NewMessage());
283
284 if (Send(req, "parameters") > 0) {
285 if (Receive(rep, "parameters") >= 0) {
286 if (rep->GetSize() != 0) {
287 CbmMqTMessage tmsg(rep->GetData(), rep->GetSize());
288 fUnpackPar = dynamic_cast<CbmMcbm2018TofPar*>(tmsg.ReadObject(tmsg.GetClass()));
289 LOG(info) << "Received unpack parameter from parmq server: " << fUnpackPar;
290 fUnpackPar->Print();
291 }
292 else {
293 LOG(error) << "Received empty reply. Parameter not available";
294 }
295 }
296 }
297
298
300
301 Bool_t initOK = kTRUE;
302 initOK &= fUnpackerAlgo->InitContainers();
303 initOK &= ReInitContainers(); // needed for TInt parameters
304
305 // CreateHistograms();
306 initOK &= fUnpackerAlgo->CreateHistograms();
307
310 fvbChanThere.resize(fviRpcChUId.size(), kFALSE);
311 for (UInt_t i = 0; i < fuNrOfGdpbs; ++i) {
312 for (UInt_t j = 0; j < fuNrOfGet4PerGdpb; ++j) {
314 fvbFirstEpochSeen[GetArrayIndex(i, j)] = kFALSE;
315 } // for( UInt_t j = 0; j < fuNrOfGet4PerGdpb; ++j )
316 } // for( UInt_t i = 0; i < fuNrOfGdpbs; ++i )
317
318 fNumTint = 0;
319 return initOK;
320}
321
323{
324 FairRuntimeDb* fRtdb = FairRuntimeDb::instance();
325
326 TList* fParCList = fUnpackerAlgo->GetParList();
327
328 LOG(info) << "Setting parameter containers for " << fParCList->GetEntries() << " entries ";
329
330 for (Int_t iparC = 0; iparC < fParCList->GetEntries(); ++iparC) {
331 FairParGenericSet* tempObj = (FairParGenericSet*) (fParCList->At(iparC));
332 fParCList->Remove(tempObj);
333
334 std::string sParamName {tempObj->GetName()};
335
336 FairParGenericSet* newObj = dynamic_cast<FairParGenericSet*>(fRtdb->getContainer(sParamName.data()));
337 LOG(info) << " - Get " << sParamName.data() << " at " << newObj;
338 if (nullptr == newObj) {
339
340 LOG(error) << "Failed to obtain parameter container " << sParamName << ", for parameter index " << iparC;
341 return;
342 } // if( nullptr == newObj )
343 if (iparC == 0) {
344 newObj = (FairParGenericSet*) fUnpackPar;
345 LOG(info) << " - Mod " << sParamName.data() << " to " << newObj;
346 }
347 fParCList->AddAt(newObj, iparC);
348 // delete tempObj;
349 } // for( Int_t iparC = 0; iparC < fParCList->GetEntries(); ++iparC )
350}
351
352void CbmDeviceUnpackTofMcbm2018::AddMsComponentToList(size_t component, UShort_t usDetectorId)
353{
354 fUnpackerAlgo->AddMsComponentToList(component, usDetectorId);
355}
356
358{
359 LOG(info) << "ReInit parameter containers for CbmDeviceUnpackMcbm2018TofPar.";
360
362 LOG(info) << "Nr. of Tof GDPBs: " << fuNrOfGdpbs;
364
366 LOG(info) << "Nr. of FEES per Tof GDPB: " << fuNrOfFeePerGdpb;
367
369 LOG(info) << "Nr. of GET4 per Tof FEE: " << fuNrOfGet4PerFee;
370
372 LOG(info) << "Nr. of channels per GET4: " << fuNrOfChannelsPerGet4;
373
375 LOG(info) << "Nr. of channels per FEE: " << fuNrOfChannelsPerFee;
376
378 LOG(info) << "Nr. of GET4s: " << fuNrOfGet4;
379
381 LOG(info) << "Nr. of GET4s per GDPB: " << fuNrOfGet4PerGdpb;
382
386 /* source: Monitor
387 UInt_t uGet4topadi[32] = {
388 4, 3, 2, 1, // provided by Jochen
389 24, 23, 22, 21,
390 8, 7, 6, 5,
391 28, 27, 26, 25,
392 12, 11, 10, 9,
393 32, 31, 30, 29,
394 16, 15, 14, 13,
395 20, 19, 18, 17 };
396 */
397
398 UInt_t uGet4topadi[32] = {4, 3, 2, 1, // provided by Jochen
399 8, 7, 6, 5, 12, 11, 10, 9, 16, 15, 14, 13, 20, 19,
400 18, 17, 24, 23, 22, 21, 28, 27, 26, 25, 32, 31, 30, 29};
401
402 UInt_t uPaditoget4[32] = {4, 3, 2, 1, // provided by Jochen
403 12, 11, 10, 9, 20, 19, 18, 17, 28, 27, 26, 25, 32, 31,
404 30, 29, 8, 7, 6, 5, 16, 15, 14, 13, 24, 23, 22, 21};
405
406 for (UInt_t uChan = 0; uChan < fuNrOfChannelsPerFee; ++uChan) {
407 fvuPadiToGet4[uChan] = uPaditoget4[uChan] - 1;
408 fvuGet4ToPadi[uChan] = uGet4topadi[uChan] - 1;
409 } // for( UInt_t uChan = 0; uChan < fuNrOfChannelsPerFee; ++uChan )
410
414 UInt_t kuElinkToGet4[kuNbGet4PerGbtx] = {27, 2, 7, 3, 31, 26, 30, 1, 33, 37, 32, 13, 9, 14,
415 10, 15, 17, 21, 16, 35, 34, 38, 25, 24, 0, 6, 20, 23,
416 18, 22, 28, 4, 29, 5, 19, 36, 39, 8, 12, 11};
417 UInt_t kuGet4ToElink[kuNbGet4PerGbtx] = {24, 7, 1, 3, 31, 33, 25, 2, 37, 12, 14, 39, 38, 11,
418 13, 15, 18, 16, 28, 34, 26, 17, 29, 27, 23, 22, 5, 0,
419 30, 32, 6, 4, 10, 8, 20, 19, 35, 9, 21, 36};
420 for (UInt_t uLinkAsic = 0; uLinkAsic < kuNbGet4PerGbtx; ++uLinkAsic) {
421 fvuElinkToGet4[uLinkAsic] = kuElinkToGet4[uLinkAsic];
422 fvuGet4ToElink[uLinkAsic] = kuGet4ToElink[uLinkAsic];
423 } // for( UInt_t uChan = 0; uChan < fuNrOfChannelsPerFee; ++uChan )
424
425 UInt_t uNrOfGbtx = fUnpackPar->GetNrOfGbtx();
426 fviRpcType.resize(uNrOfGbtx);
427 fviModuleId.resize(uNrOfGbtx);
428 fviNrOfRpc.resize(uNrOfGbtx);
429 fviRpcSide.resize(uNrOfGbtx);
430
431 for (UInt_t iGbtx = 0; iGbtx < uNrOfGbtx; ++iGbtx) {
432 fviNrOfRpc[iGbtx] = fUnpackPar->GetNrOfRpc(iGbtx);
433 fviRpcType[iGbtx] = fUnpackPar->GetRpcType(iGbtx);
434 fviRpcSide[iGbtx] = fUnpackPar->GetRpcSide(iGbtx);
435 fviModuleId[iGbtx] = fUnpackPar->GetModuleId(iGbtx);
436 }
437
438 UInt_t uNrOfChannels = fuNrOfGet4 * fuNrOfChannelsPerGet4;
439 LOG(info) << "Nr. of possible Tof channels: " << uNrOfChannels;
440
441 // CbmTofDetectorId* fTofId = new CbmTofDetectorId_v14a();
442 fviRpcChUId.resize(uNrOfChannels);
443 UInt_t iCh = 0;
444 for (UInt_t iGbtx = 0; iGbtx < uNrOfGbtx; iGbtx++) {
445 Int_t iModuleIdMap = fviModuleId[iGbtx];
446 switch (fviRpcType[iGbtx]) {
447
448 case 0: // CBM modules
449 if (fviRpcSide[iGbtx] < 2) { // mTof modules
450 const Int_t RpcMap[5] = {4, 2, 0, 3, 1};
451 for (Int_t iRpc = 0; iRpc < fviNrOfRpc[iGbtx]; iRpc++) {
452 Int_t iStrMax = 32;
453 Int_t iChNext = 1;
454
455 for (Int_t iStr = 0; iStr < iStrMax; iStr++) {
456 Int_t iStrMap = iStr;
457 Int_t iRpcMap = RpcMap[iRpc];
458
459 if (fviRpcSide[iGbtx] == 0) iStrMap = 31 - iStr;
460 if (fviModuleId[iGbtx] > -1)
461 fviRpcChUId[iCh] = CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx], iRpcMap, iStrMap,
462 fviRpcSide[iGbtx], fviRpcType[iGbtx]);
463 else
464 fviRpcChUId[iCh] = 0;
465 // LOG(debug)<<Form("Map Ch %d to Address 0x%08x",iCh,fviRpcChUId[iCh]);
466
467 iCh += iChNext;
468 }
469 }
470 }
471 break;
472
473
474 case 1: // STAR eTOF modules
475 if (fviRpcSide[iGbtx] < 2) { // mTof modules
476 const Int_t RpcMap[3] = {0, 1, 2};
477 for (Int_t iRpc = 0; iRpc < fviNrOfRpc[iGbtx]; iRpc++) {
478 Int_t iStrMax = 32;
479 Int_t iChNext = 1;
480
481 for (Int_t iStr = 0; iStr < iStrMax; iStr++) {
482 Int_t iStrMap = iStr;
483 Int_t iRpcMap = RpcMap[iRpc];
484
485 if (fviRpcSide[iGbtx] == 0) iStrMap = 31 - iStr;
486 if (fviModuleId[iGbtx] > -1)
487 fviRpcChUId[iCh] = CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx], iRpcMap, iStrMap,
488 fviRpcSide[iGbtx], fviRpcType[iGbtx]);
489 else
490 fviRpcChUId[iCh] = 0;
491 // LOG(debug)<<Form("Map Ch %d to Address 0x%08x",iCh,fviRpcChUId[iCh]);
492 iCh += iChNext;
493 }
494 }
495 }
496 iCh += 64;
497 break;
498
499 case 5: // Diamond
500 {
501 LOG(info) << " Map diamond at GBTX - iCh = " << iCh;
502 for (UInt_t uFee = 0; uFee < fUnpackPar->GetNrOfFeePerGbtx(); ++uFee) {
503 for (UInt_t uCh = 0; uCh < fUnpackPar->GetNrOfChannelsPerFee(); ++uCh) {
504 if (uFee < 4 && (0 == uCh % 4 || uCh < 4)) {
505 // if( 0 == uCh ) {
507 fviModuleId[iGbtx], 0,
508 uFee * fUnpackPar->GetNrOfChannelsPerFee() / 4 + uCh / 4 + 40 * fviRpcSide[iGbtx],
509 // 0, uFee + 10 * fviRpcSide[iGbtx],
510 0, fviRpcType[iGbtx]);
511 LOG(info) << Form("Map Bmon Ch %d to Address 0x%08x", iCh, fviRpcChUId[iCh]);
512 }
513 else
514 fviRpcChUId[iCh] = 0;
515
516 iCh++;
517 } // for( UInt_t uCh = 0; uCh < fUnpackPar->GetNrOfChannelsPerFee(); ++uCh )
518 } // for( UInt_t uFee = 0; uFee < fUnpackPar->GetNrOfFeePerGbtx(); ++uFee )
519 } break;
520
521 case 78: // cern-20-gap + ceramic module
522 {
523 LOG(info) << " Map CERN 20 gap at GBTX - iCh = " << iCh;
524 // clang-format off
525 const Int_t StrMap[32] = {0, 1, 2, 3, 4, 31, 5, 6, 7, 30, 8,
526 9, 10, 29, 11, 12, 13, 14, 28, 15, 16, 17,
527 18, 27, 26, 25, 24, 23, 22, 21, 20, 19};
528 // clang-format on
529 Int_t iModuleId = 0;
530 Int_t iModuleType = 7;
531 Int_t iRpcMap = 0;
532 for (Int_t iFeet = 0; iFeet < 2; iFeet++) {
533 for (Int_t iStr = 0; iStr < 32; iStr++) {
534 Int_t iStrMap = 31 - 12 - StrMap[iStr];
535 Int_t iSideMap = iFeet;
536
537 if (iStrMap < 20)
538 fviRpcChUId[iCh] = CbmTofAddress::GetUniqueAddress(iModuleId, iRpcMap, iStrMap, iSideMap, iModuleType);
539 else
540 fviRpcChUId[iCh] = 0;
541 iCh++;
542 }
543 }
544 }
545 [[fallthrough]]; // fall through is intended
546 case 8: // ceramics
547 {
548 Int_t iModuleId = 0;
549 Int_t iModuleType = 8;
550 for (Int_t iRpc = 0; iRpc < 8; iRpc++) {
551 fviRpcChUId[iCh] = CbmTofAddress::GetUniqueAddress(iModuleId, 7 - iRpc, 0, 0, iModuleType);
552 iCh++;
553 }
554 iCh += (24 + 2 * 32);
555 }
556 LOG(info) << " Map end ceramics box at GBTX - iCh = " << iCh;
557
558 break;
559
560 case 4:
561 case 9: // Star2 boxes
562 {
563 LOG(info) << " Map Star2 box at GBTX - iCh = " << iCh;
564 const Int_t iRpc[5] = {1, -1, 1, 0, 0};
565 const Int_t iSide[5] = {1, -1, 0, 1, 0};
566 for (Int_t iFeet = 0; iFeet < 5; iFeet++) {
567 for (Int_t iStr = 0; iStr < 32; iStr++) {
568 Int_t iStrMap = iStr;
569 Int_t iRpcMap = iRpc[iFeet];
570 Int_t iSideMap = iSide[iFeet];
571 if (iSideMap == 0) iStrMap = 31 - iStr;
572 switch (fviRpcSide[iGbtx]) {
573 case 0:; break;
574 case 1:; break;
575 case 2:
576 switch (iFeet) {
577 case 1:
578 iRpcMap = iRpc[4];
579 iSideMap = iSide[4];
580 break;
581 case 4:
582 iRpcMap = iRpc[1];
583 iSideMap = iSide[1];
584 break;
585 default:;
586 }
587 break;
588 }
589 if (iSideMap > -1)
590 fviRpcChUId[iCh] =
591 CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx], iRpcMap, iStrMap, iSideMap, fviRpcType[iGbtx]);
592 else
593 fviRpcChUId[iCh] = 0;
594
595 iCh++;
596 }
597 }
598 } break;
599
600 case 6: // Buc box
601 {
602 LOG(info) << " DevMap Buc box at GBTX - iCh = " << iCh;
603 const Int_t iRpc[5] = {0, -1, 0, 1, 1};
604 const Int_t iSide[5] = {1, -1, 0, 1, 0};
605 for (Int_t iFeet = 0; iFeet < 5; iFeet++) {
606 for (Int_t iStr = 0; iStr < 32; iStr++) {
607 Int_t iStrMap = iStr;
608 Int_t iRpcMap = iRpc[iFeet];
609 Int_t iSideMap = iSide[iFeet];
610 //if(iSideMap == 0)iStrMap=31-iStr;
611 switch (fviRpcSide[iGbtx]) {
612 case 0:; break;
613 case 1: // HD cosmic 2019, Buc2018, v18n
614 iStrMap = 31 - iStr;
615 iRpcMap = 1 - iRpcMap;
616 break;
617 case 2: // v18m_cosmicHD
618 // iStrMap=31-iStr;
619 iSideMap = 1 - iSideMap;
620 break;
621 case 3:
622 iStrMap = 31 - iStr;
623 iRpcMap = 1 - iRpcMap;
624 iSideMap = 1 - iSideMap;
625 break;
626 case 4: // HD cosmic 2019, Buc2018, v18o
627 iRpcMap = 1 - iRpcMap;
628 break;
629 case 5: // HD cosmic 2020, Buc2018, v20a
630 iStrMap = 31 - iStr;
631 break;
632 case 6: //BUC special
633 {
634 switch (fviModuleId[iGbtx]) {
635 case 0: iRpcMap = 0; break;
636 case 1: iRpcMap = 1; break;
637 }
638 if (iFeet > 2) iModuleIdMap = 1;
639 } break;
640 case 7: {
641 // clang-format off
642 const Int_t iChMap[160]={
643 127, 126, 125, 124, 12, 13, 14, 15, 7, 6, 5, 4, 28, 29, 30, 31, 123, 122, 121, 120, 8, 9, 10, 11, 107, 106, 105, 104, 108, 109, 110, 111,
644 39, 38, 37, 36, 52, 53, 54, 55, 63, 62, 61, 60, 128, 129, 130, 131, 43, 42, 41, 40, 148, 149, 150, 151, 59, 58, 57, 56, 132, 133, 134, 135,
645 139, 138, 137, 136, 140, 141, 142, 143, 99, 98, 97, 96, 64, 65, 66, 67, 103, 102, 101, 100, 84, 85, 86, 87, 155, 154, 153, 152, 68, 69, 70, 71,
646 159, 158, 157, 156, 144, 145, 146, 147, 47, 46, 45, 44, 76, 77, 78, 79, 51, 50, 49, 48, 20, 21, 22, 23, 35, 34, 33, 32, 116, 117, 118, 119,
647 75, 74, 73, 72, 92, 93, 94, 95, 19, 18, 17, 16, 80, 81, 82, 83, 115, 114, 113, 112, 24, 25, 26, 27, 91, 90, 89, 88, 0, 1, 2, 3
648 };
649 // clang-format on
650 Int_t iInd = iFeet * 32 + iStr;
651 Int_t i = 0;
652 for (; i < 160; i++)
653 if (iInd == iChMap[i]) break;
654 iStrMap = i % 32;
655 Int_t iFeetInd = (i - iStrMap) / 32;
656 switch (iFeet) {
657 case 0:
658 iRpcMap = 0;
659 iSideMap = 1;
660 break;
661 case 1:
662 iRpcMap = 1;
663 iSideMap = 1;
664 break;
665 case 2:
666 iRpcMap = 1;
667 iSideMap = 0;
668 break;
669 case 3:
670 iRpcMap = 0;
671 iSideMap = 0;
672 break;
673 case 4: iSideMap = -1; break;
674 }
675 iModuleIdMap = fviModuleId[iGbtx];
676 LOG(info) << "Buc of GBTX " << iGbtx
677 << Form(", Feet %1d, Str %2d, i %3d, FeetInd %1d, Rpc %1d, Side %1d, Str %2d ", iFeet, iStr,
678 i, iFeetInd, iRpcMap, iSideMap, iStrMap);
679 } break;
680 default:;
681 }
682 if (iSideMap > -1)
683 fviRpcChUId[iCh] =
684 CbmTofAddress::GetUniqueAddress(iModuleIdMap, iRpcMap, iStrMap, iSideMap, fviRpcType[iGbtx]);
685 else
686 fviRpcChUId[iCh] = 0;
687
688 iCh++;
689 }
690 }
691 } break;
692
693 case -1:
694 LOG(info) << " Found unused GBTX link at iCh = " << iCh;
695 iCh += 160;
696 break;
697
698 default: LOG(error) << "Invalid Type specifier for Gbtx " << iGbtx << ": " << fviRpcType[iGbtx];
699 }
700 }
701
702 for (UInt_t i = 0; i < uNrOfChannels; i = i + 8) {
703 if (i % 64 == 0) LOG(info) << " Index " << i;
704 LOG(info) << Form("0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x", fviRpcChUId[i], fviRpcChUId[i + 1],
705 fviRpcChUId[i + 2], fviRpcChUId[i + 3], fviRpcChUId[i + 4], fviRpcChUId[i + 5],
706 fviRpcChUId[i + 6], fviRpcChUId[i + 7]);
707 } // for( UInt_t i = 0; i < uNrOfChannels; ++i)
708
709 return kTRUE;
710}
711
713{
714 LOG(info) << "create Histos for " << fuNrOfGdpbs << " gDPBs ";
715
717 new TH1F(Form("Raw_TDig-EvBmon"), Form("Raw digi time difference to 1st digi ; time [ns]; cts"), 500, 0, 100.);
718 // fHM->Add( Form("Raw_TDig-EvBmon"), fhRawTDigEvBmon);
719
721 new TH1F(Form("Raw_TDig-Ref0"), Form("Raw digi time difference to Ref ; time [ns]; cts"), 6000, -10000, 50000);
722 // fHM->Add( Form("Raw_TDig-Ref0"), fhRawTDigRef0);
723
725 new TH1F(Form("Raw_TDig-Ref"), Form("Raw digi time difference to Ref ; time [ns]; cts"), 6000, -1000, 5000);
726 // fHM->Add( Form("Raw_TDig-Ref"), fhRawTDigRef);
727
728 fhRawTRefDig0 = new TH1F(Form("Raw_TRef-Dig0"), Form("Raw Ref time difference to last digi ; time [ns]; cts"), 9999,
729 -50000, 50000);
730 // fHM->Add( Form("Raw_TRef-Dig0"), fhRawTRefDig0);
731
733 new TH1F(Form("Raw_TRef-Dig1"), Form("Raw Ref time difference to last digi ; time [ns]; cts"), 9999, -5000, 5000);
734 // fHM->Add( Form("Raw_TRef-Dig1"), fhRawTRefDig1);
735
736 fhRawDigiLastDigi = new TH1F(Form("Raw_Digi-LastDigi"),
737 Form("Raw Digi time difference to last digi ; time [ns]; cts"), 9999, -5000, 5000);
738 // 9999, -5000000, 5000000);
739 // fHM->Add( Form("Raw_Digi-LastDigi"), fhRawDigiLastDigi);
740
741 fhRawTotCh.resize(fuNrOfGdpbs);
742 fhChCount.resize(fuNrOfGdpbs);
744 for (UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; uGdpb++) {
745 fhRawTotCh[uGdpb] = new TH2F(Form("Raw_Tot_gDPB_%02u", uGdpb), Form("Raw TOT gDPB %02u; channel; TOT [bin]", uGdpb),
746 fuNrOfChannelsPerGdpb, 0., fuNrOfChannelsPerGdpb, 256, 0., 256.);
747 // fHM->Add( Form("Raw_Tot_gDPB_%02u", uGdpb), fhRawTotCh[ uGdpb ]);
748
749 fhChCount[uGdpb] =
750 new TH1I(Form("ChCount_gDPB_%02u", uGdpb), Form("Channel counts gDPB %02u; channel; Hits", uGdpb),
752 // fHM->Add( Form("ChCount_gDPB_%02u", uGdpb), fhChCount[ uGdpb ]);
753 /*
754 for( UInt_t uLeftFeb = uGdpb*fuNrOfFebsPerGdpb / 2;
755 uLeftFeb < (uGdpb + 1 )*fuNrOfFebsPerGdpb / 2;
756 ++uLeftFeb )
757 {
758 fhChanCoinc[ uLeftFeb ] = new TH2F( Form("fhChanCoinc_%02u", uLeftFeb),
759 Form("Channels Coincidence %02; Left; Right", uLeftFeb),
760 fuNrOfChannelsPerFee, 0., fuNrOfChannelsPerFee,
761 fuNrOfChannelsPerFee, 0., fuNrOfChannelsPerFee );
762 } // for( UInt_t uLeftFeb = 0; uLeftFeb < fuNrOfFebsPerGdpb / 2; uLeftFeb ++ )
763 */
764 fhChanCoinc[uGdpb] =
765 new TH2F(Form("fhChanCoinc_%02u", uGdpb), Form("Channels Coincidence %02u; Left; Right", uGdpb),
767 } // for( UInt_t uGdpb = 0; uGdpb < fuMinNbGdpb; uGdpb ++)
768 fhDetChanCoinc = new TH2F("fhDetChanCoinc", "Det Channels Coincidence; Left; Right", 32, 0., 32, 32, 0., 32);
769}
770
771// handler is called whenever a message arrives on "data", with a reference to the message and a sub-channel index (here 0)
772bool CbmDeviceUnpackTofMcbm2018::HandleData(FairMQMessagePtr& msg, int /*index*/)
773{
774 // Don't do anything with the data
775 // Maybe add an message counter which counts the incomming messages and add
776 // an output
777 fNumMessages++;
778 LOG(debug) << "Received message number " << fNumMessages << " with size " << msg->GetSize();
779
780 std::string msgStr(static_cast<char*>(msg->GetData()), msg->GetSize());
781 std::istringstream iss(msgStr);
782 boost::archive::binary_iarchive inputArchive(iss);
783
784 fles::StorableTimeslice component {0};
785 inputArchive >> component;
786
787 // CheckTimeslice(component);
788
789 DoUnpack(component, 0);
790
791 BuildTint(0);
792
793 if (fNumMessages % 10000 == 0) LOG(info) << "Processed " << fNumMessages << " time slices";
794
795 return true;
796}
797
798bool CbmDeviceUnpackTofMcbm2018::HandleParts(FairMQParts& parts, int /*index*/)
799{
800 // Don't do anything with the data
801 // Maybe add an message counter which counts the incomming messages and add
802 // an output
803 fNumMessages++;
804 LOG(debug) << "Received message number " << fNumMessages << " with " << parts.Size() << " parts";
805
806 fles::StorableTimeslice ts {0};
807
808 switch (fiSelectComponents) {
809 case 0: {
810 std::string msgStr(static_cast<char*>(parts.At(0)->GetData()), (parts.At(0))->GetSize());
811 std::istringstream iss(msgStr);
812 boost::archive::binary_iarchive inputArchive(iss);
813 inputArchive >> ts;
814 //CheckTimeslice(ts);
815 if (1 == fNumMessages) {
816 LOG(info) << "Initialize TS components list to " << ts.num_components();
817 for (size_t c {0}; c < ts.num_components(); c++) {
818 auto systemID = static_cast<int>(ts.descriptor(c, 0).sys_id);
819 LOG(info) << "Found systemID: " << std::hex << systemID << std::dec;
820 fUnpackerAlgo->AddMsComponentToList(c, systemID); // TOF data
821 }
822 }
823 DoUnpack(ts, 0);
824 } break;
825 case 1: {
826 fles::StorableTimeslice component {0};
827
828 uint ncomp = parts.Size();
829 for (uint i = 0; i < ncomp; i++) {
830 std::string msgStr(static_cast<char*>(parts.At(i)->GetData()), (parts.At(i))->GetSize());
831 std::istringstream iss(msgStr);
832 boost::archive::binary_iarchive inputArchive(iss);
833 //fles::StorableTimeslice component{i};
834 inputArchive >> component;
835
836 // CheckTimeslice(component);
837 fUnpackerAlgo->AddMsComponentToList(0, 0x60); // TOF data
838 LOG(debug) << "HandleParts message " << fNumMessages << " with indx " << component.index();
839 DoUnpack(component, 0);
840 }
841 } break;
842 default:;
843 }
844
845 BuildTint(0);
846
847 if (fNumMessages % 10000 == 0) LOG(info) << "Processed " << fNumMessages << " time slices";
848
849 return true;
850}
851
852bool CbmDeviceUnpackTofMcbm2018::HandleMessage(FairMQMessagePtr& msg, int /*index*/)
853{
854 const char* cmd = (char*) (msg->GetData());
855 const char cmda[4] = {*cmd};
856 LOG(info) << "Handle message " << cmd << ", " << cmd[0];
857 cbm::mq::LogState(this);
858
859 // only one implemented so far "Stop"
860
861 if (strcmp(cmda, "STOP")) {
862 LOG(info) << "STOP";
865 cbm::mq::LogState(this);
867 cbm::mq::LogState(this);
869 cbm::mq::LogState(this);
871 cbm::mq::LogState(this);
872 }
873 return true;
874}
875
876Bool_t CbmDeviceUnpackTofMcbm2018::DoUnpack(const fles::Timeslice& ts, size_t component)
877{
878 LOG(debug) << "Timeslice " << ts.index() << " contains " << ts.num_microslices(component)
879 << " microslices of component " << component;
880
881 if (kFALSE == fUnpackerAlgo->ProcessTs(ts)) {
882 LOG(error) << "Failed processing TS " << ts.index() << " in unpacker algorithm class";
883 return kTRUE;
884 } // if( kFALSE == fUnpackerAlgo->ProcessTs( ts ) )
885
887 std::vector<CbmTofDigi> vDigi = fUnpackerAlgo->GetVector();
888
889 /*
890 // time sort vDigis
891 sort(vDigi.begin(), vDigi.end(),
892 [](const CbmTofDigi & a, const CbmTofDigi & b) -> bool
893 {
894 return a.GetTime() < b.GetTime();
895 });
896 */
897
898 LOG(debug) << "Insert " << vDigi.size() << " digis into DAQ buffer with size " << fBuffer->GetSize();
899
900 for (auto digi : vDigi) {
901 // copy Digi for insertion into DAQ buffer
902 CbmTofDigi* fDigi = new CbmTofDigi(digi);
903
904 //if( (fDigi->GetAddress() & 0x000F00F ) != fiAddrRef ) fDigi->SetTime(fDigi->GetTime()+fdToffTof); // shift all Tof Times for v14a geometries
905 if ((fDigi->GetAddress() & 0x000780F) != fiAddrRef)
906 fDigi->SetTime(fDigi->GetTime() + fdToffTof); // shift all Tof Times for V21a
907
908 LOG(debug) << "BufferInsert digi " << Form("0x%08x at %012.2f", fDigi->GetAddress(), fDigi->GetTime())
909 << Form(", first %012.2f, last %012.2f, size %u", fBuffer->GetTimeFirst(), fBuffer->GetTimeLast(),
910 fBuffer->GetSize());
911
913 }
914 vDigi.clear();
916
917 return kTRUE;
918}
919
921{
922 // iMode - sending condition
923 // 0 (default)- build time interval only if last buffer entry is older the start + TSLength
924 // 1 (finish), empty buffer without checking
925 // Steering variables
926 double TSLENGTH = 1.E6;
927 double fdMaxDeltaT = (double) fiReqTint; // in ns
928
929 LOG(debug) << "BuildTint: Buffer size " << fBuffer->GetSize() << ", DeltaT "
930 << (fBuffer->GetTimeLast() - fBuffer->GetTimeFirst()) / 1.E9 << " s";
932 CbmTofDigi* digi;
933
934 while (fBuffer->GetSize() > 0) {
935 Double_t fTimeBufferLast = fBuffer->GetTimeLast();
936
937 switch (iMode) {
938 case 0:
939 if (fTimeBufferLast - fBuffer->GetTimeFirst() < TSLENGTH) return;
940 break;
941 case 1:; break;
942 }
943
944 data = fBuffer->GetNextData(fTimeBufferLast);
945 digi = boost::any_cast<CbmTofDigi*>(data.first);
946 assert(digi);
947
948 Double_t dTEnd = digi->GetTime() + fdMaxDeltaT;
949 Double_t dTEndMax = digi->GetTime() + 2 * fdMaxDeltaT;
950 LOG(debug) << Form("Next event at %f until %f, max %f ", digi->GetTime(), dTEnd, dTEndMax);
951
952 if (dTEnd > fTimeBufferLast) {
953 LOG(warn) << Form("Remaining buffer < %f with %d entries is not "
954 "sufficient for digi ending at %f -> skipped ",
955 fTimeBufferLast, fBuffer->GetSize(), dTEnd);
956 return;
957 }
958
959 LOG(debug) << "BuildTint0 with digi " << Form("0x%08x at %012.2f", digi->GetAddress(), digi->GetTime());
960
961 Bool_t bDet[fiReqDigiAddr.size()][2];
962 for (UInt_t i = 0; i < fiReqDigiAddr.size(); i++)
963 for (Int_t j = 0; j < 2; j++)
964 bDet[i][j] = kFALSE; //initialize
965 Bool_t bPul[fiReqDigiAddr.size()][2];
966 for (UInt_t i = 0; i < fiReqDigiAddr.size(); i++)
967 for (Int_t j = 0; j < 2; j++)
968 bPul[i][j] = kFALSE; //initialize
969 Bool_t bBeam = kFALSE;
970
971 std::vector<CbmTofDigi*> vdigi;
972 UInt_t nDigi = 0;
973 //const Int_t AddrMask=0x003FFFFF;
974 const Int_t AddrMask = 0x001FFFFF;
975 Bool_t bOut = kFALSE;
976 Int_t iBucMul = 0;
977
978 while (data.second != ECbmModuleId::kNotExist) { // build digi array
979 digi = boost::any_cast<CbmTofDigi*>(data.first);
980 LOG(debug) << "GetNextData " << digi << ", " << data.second << ", " << Form("%f %f", digi->GetTime(), dTEnd)
981 << ", Mul " << nDigi;
982 assert(digi);
983
984 if (nDigi == vdigi.size()) vdigi.resize(nDigi + 100);
985 vdigi[nDigi++] = digi;
986
987 Int_t iAddr = digi->GetAddress() & AddrMask;
988 if (iAddr == 0x00003006 || iAddr == 0x0000b006) {
989 iBucMul++;
990 LOG(debug) << Form("Event %10d: BucMul %2d, addr 0x%08x, side %d, strip %2d, rpc %d", fEventHeader[0], iBucMul,
991 digi->GetAddress(), (Int_t) digi->GetSide(), (Int_t) digi->GetChannel(),
992 (Int_t) digi->GetRpc());
993 }
994 for (UInt_t i = 0; i < fiReqDigiAddr.size(); i++)
995 if ((digi->GetAddress() & AddrMask) == fiReqDigiAddr[i]) {
996 Int_t j = ((CbmTofDigi*) digi)->GetSide();
997 bDet[i][j] = kTRUE;
998 if (fiReqDigiAddr[i] == (Int_t) fiReqBeam) {
999 bBeam = kTRUE;
1000 LOG(debug) << "Found ReqBeam at index " << nDigi - 1 << ", req " << i;
1001 }
1002 if ((UInt_t) fiReqDigiAddr[i] == fiAddrRef) bDet[i][1] = kTRUE; // diamond with pad readout
1003 // if ( (fiReqDigiAddr[i] & 0x0000F00F ) == 0x00008006) bDet[i][1]=kTRUE; // ceramic with pad readout
1004 Int_t str = ((CbmTofDigi*) digi)->GetChannel();
1005
1006 switch (j) { // treat both strip ends separately
1007 case 0:
1008 switch (fiPulserMode) {
1009 case 0:
1010 case 1:
1011 if (str == 31)
1012 if (digi->GetTot() > fiPulTotMin && digi->GetTot() < fiPulTotMax) bPul[i][0] = kTRUE;
1013 if (str == 0) bPul[i][1] = kFALSE;
1014 if ((UInt_t) fiReqDigiAddr[i] == fiAddrRef) { //special mapping for MAr2019 diamond (Bmon)
1015 if (str == 0) bPul[i][0] = kTRUE;
1016 if (str == 40) bPul[i][1] = kTRUE;
1017 }
1018 break;
1019 case 2:
1020 if (str == 0)
1021 if (digi->GetTot() > fiPulTotMin && digi->GetTot() < fiPulTotMax) {
1022 bPul[i][0] = kTRUE;
1023 if ((fiReqDigiAddr[i] & 0x000FF00F) == 0x00078006) {
1024 bPul[i][1] = kTRUE; // ceramic with pad readout
1025 bDet[i][1] = kFALSE; // remove Hit flag
1026 }
1027 if (str == 31) bPul[i][1] = kFALSE;
1028 }
1029 default:;
1030 }
1031 break;
1032
1033 case 1:
1034 switch (fiPulserMode) {
1035 case 0:
1036 case 1:
1037 if (str == 31) bPul[i][0] = kFALSE;
1038 if (str == 0)
1039 if (digi->GetTot() > fiPulTotMin && digi->GetTot() < fiPulTotMax) bPul[i][1] = kTRUE;
1040 break;
1041 case 2:
1042 if (str == 0) bPul[i][0] = kFALSE;
1043 if (str == 31)
1044 if (digi->GetTot() > fiPulTotMin && digi->GetTot() < fiPulTotMax) bPul[i][1] = kTRUE;
1045 break;
1046 default:;
1047 }
1048 break;
1049 default:;
1050 }
1051 }
1052 //if(bOut) LOG(info)<<Form("Found 0x%08x, Req 0x%08x ", digi->GetAddress(), fiReqDigiAddr);
1053 if (dTEnd - digi->GetTime() < fdMaxDeltaT * 0.5) {
1054 if (digi->GetTime() + fdMaxDeltaT * 0.5 < dTEndMax) dTEnd = digi->GetTime() + fdMaxDeltaT * 0.5;
1055 else
1056 dTEnd = dTEndMax;
1057 };
1058 data = fBuffer->GetNextData(dTEnd);
1059
1060 } // end while
1061
1062 LOG(debug) << nDigi << " digis associated to dTEnd = " << dTEnd << ":";
1063 //for(UInt_t iDigi=0; iDigi<nDigi; iDigi++) LOG(debug)<<Form(" 0x%08x",vdigi[iDigi]->GetAddress());
1064 for (UInt_t iDigi = 0; iDigi < nDigi; iDigi++)
1065 LOG(debug) << vdigi[iDigi]->ToString();
1066
1067 UInt_t iDetMul = 0;
1068 if (fiReqDigiAddr.size() == 0) bOut = kTRUE; // output everything
1069 else {
1070 if (fiReqMode == 0) { // check for presence of requested detectors
1071 for (UInt_t i = 0; i < fiReqDigiAddr.size(); i++)
1072 if (bDet[i][0] == kFALSE || bDet[i][1] == kFALSE) break;
1073 else if (i == fiReqDigiAddr.size() - 1) {
1074 bOut = kTRUE;
1075 iDetMul = i;
1076 }
1077 }
1078 else { // check for presence of any known detector
1079 for (UInt_t i = 0; i < fiReqDigiAddr.size(); i++)
1080 if (bDet[i][0] == kTRUE && bDet[i][1] == kTRUE) { iDetMul++; }
1081 if (iDetMul >= fiReqMode) { bOut = kTRUE; }
1082 }
1083 }
1084
1085 if (bOut && fiReqDigiAddr.size() > 1) {
1086 LOG(debug) << "Found Req coinc in event with " << nDigi << " digis in " << iDetMul
1087 << " detectors, dTEnd = " << dTEnd;
1088 }
1089
1090 // determine Pulser status
1091 UInt_t iPulMul = 0; // Count Potential Pulser Signals
1092 for (UInt_t i = 0; i < fiReqDigiAddr.size(); i++) {
1093 if (bPul[i][0] == kTRUE && bPul[i][1] == kTRUE) iPulMul++;
1094 }
1095
1096 if (fiPulserMode > 0 && iPulMul > fiPulMulMin) {
1097 LOG(debug) << "@Event " << fEventHeader[0] << ": iPulMul = " << iPulMul;
1098 bOut = kTRUE;
1099 }
1100 LOG(debug) << "Process Ev " << fEventHeader[0] << " with iDetMul = " << iDetMul << ", iPulMul = " << iPulMul;
1101
1102 fEventHeader[0]++;
1103
1104 if ((Int_t) fiReqBeam > -1) {
1105 if (bBeam) { LOG(debug) << "Beam counter is present "; }
1106 else {
1107 LOG(debug) << "Beam counter is not present";
1108 bOut = kFALSE; // request beam counter for event
1109 }
1110 }
1111
1112 if (bOut) {
1113 fEventHeader[1] = iDetMul;
1115 fEventHeader[3] = iPulMul;
1116 vdigi.resize(nDigi);
1117 const Int_t NDigiMax = 10000;
1118 if (nDigi > NDigiMax) {
1119 LOG(warn) << "Oversized event, truncated! ";
1120 for (UInt_t iDigi = NDigiMax; iDigi < nDigi; iDigi++)
1121 delete vdigi[iDigi];
1122 nDigi = 1; //NDigiMax;
1123 vdigi.resize(nDigi);
1124 }
1125 SendDigis(vdigi, 0);
1126
1127 for (UInt_t iDigi = 0; iDigi < nDigi; iDigi++)
1128 delete vdigi[iDigi];
1129 }
1130 else {
1131 LOG(debug) << " BuildTint cleanup of " << nDigi << " digis";
1132 for (UInt_t iDigi = 0; iDigi < nDigi; iDigi++) {
1133 // vdigi[iDigi]->Delete();
1134 }
1135 LOG(debug) << " Digis deleted ";
1136 //vdigi.clear();
1137 //delete &vdigi; // crashes, since local variable, will be done at return (?)
1138 }
1139 }
1140}
1141
1142bool CbmDeviceUnpackTofMcbm2018::SendDigis(std::vector<CbmTofDigi*> vdigi, int idx)
1143{
1144 LOG(debug) << "Send Digis for event " << fNumTint << " with size " << vdigi.size() << Form(" at %p ", &vdigi);
1145 LOG(debug) << "EventHeader: " << fEventHeader[0] << " " << fEventHeader[1] << " " << fEventHeader[2] << " "
1146 << fEventHeader[3];
1147
1148 // Int_t NDigi=vdigi.size();
1149
1150 std::stringstream ossE;
1151 boost::archive::binary_oarchive oaE(ossE);
1152 oaE << fEventHeader;
1153 std::string* strMsgE = new std::string(ossE.str());
1154
1155 std::stringstream oss;
1156 boost::archive::binary_oarchive oa(oss);
1157 oa << vdigi;
1158 std::string* strMsg = new std::string(oss.str());
1159
1160 FairMQParts parts;
1161 parts.AddPart(NewMessage(
1162 const_cast<char*>(strMsgE->c_str()), // data
1163 strMsgE->length(), // size
1164 [](void*, void* object) { delete static_cast<std::string*>(object); },
1165 strMsgE)); // object that manages the data
1166
1167 parts.AddPart(NewMessage(
1168 const_cast<char*>(strMsg->c_str()), // data
1169 strMsg->length(), // size
1170 [](void*, void* object) { delete static_cast<std::string*>(object); },
1171 strMsg)); // object that manages the data
1172
1173
1174 /*
1175 std::vector<CbmTofDigi>vTofDigi;
1176 vTofDigi.resize(vdigi.size());
1177 for (Int_t i=0; i<vdigi.size(); i++) {
1178 CbmTofDigi *pdigi = (CbmTofDigi *) vdigi[i];
1179 CbmTofDigi digi = *pdigi;
1180 vTofDigi[i] = digi;
1181 LOG(debug) << vTofDigi[i].ToString()<<" bits "<<Form("0x%08x",vTofDigi[i].TestBits(0xFFFF));
1182 }
1183 FairMQMessagePtr msg(NewMessage(static_cast<std::vector<CbmTofDigi>*> (&vTofDigi), // data
1184 NDigi*sizeof(CbmTofDigi), // size
1185 [](void* , void* object){ delete static_cast<CbmTofDigi*>(object); }
1186 )); // object that manages the data
1187
1188 // transfer of TofDigi array, ... works
1189 CbmTofDigi aTofDigi[NDigi];
1190 // const Int_t iNDigiOut=100;
1191 // NDigi=TMath::Min(NDigi,iNDigiOut);
1192 // std::array<CbmTofDigi,iNDigiOut> aTofDigi;
1193 for (Int_t i=0; i<NDigi; i++) {
1194 aTofDigi[i] = *vdigi[i];
1195 LOG(debug) << aTofDigi[i].ToString()<<" bits "<<Form("0x%08x",aTofDigi[i].TestBits(0xFFFF));
1196 }
1197 FairMQMessagePtr msg(NewMessage(static_cast<CbmTofDigi*> (&aTofDigi[0]), // data
1198 NDigi*sizeof(CbmTofDigi), // size
1199 [](void* , void* object){ delete static_cast<CbmTofDigi*>(object); }
1200 )); // object that manages the data
1201
1202
1203 LOG(info) << "Send aTofDigi sizes "<<NDigi<<", "<<sizeof(CbmTofDigi)<<", msg size "<<msg->GetSize();
1204
1205 // serialize the timeslice and create the message
1206
1207 std::stringstream oss;
1208 boost::archive::binary_oarchive oa(oss);
1209 oa << vdigi;
1210 std::string* strMsg = new std::string(oss.str());
1211
1212 LOG(debug) << "send strMsg with length " << strMsg->length()<<" "<<strMsg;
1213 FairMQMessagePtr msg(NewMessage(const_cast<char*>(strMsg->c_str()), // data
1214 strMsg->length(), // size
1215 [](void* , void* object){ delete static_cast<std::string*>(object); },
1216 strMsg)); // object that manages the data
1217 */
1218 /*
1219 FairMQMessagePtr msg(NewMessage(static_cast<CbmTofDigi*> (vTofDigi.data()), // data
1220 vTofDigi.size()*sizeof(CbmTofDigi), // size
1221 [](void* , void* object){ delete static_cast<CbmTofDigi*>(object); }
1222 )); // object that manages the data
1223 */
1224
1225 /* --------------------------------------- compiles but crashes .... ---------------------------------------------------
1226 const Int_t WSize=8;
1227 FairMQMessagePtr msg(NewMessage(static_cast<std::vector<CbmTofDigi>*> (&vTofDigi), // data
1228 vTofDigi.size()*sizeof(CbmTofDigi)*WSize, // size, FIXME, numerical value in code!
1229 [](void* , void* object){ delete static_cast<std::vector<CbmTofDigi>*>(object); }
1230 )); // object that manages the data
1231
1232 LOG(info) << "Send TofDigi sizes "<<vTofDigi.size()<<", "<<sizeof(CbmTofDigi)<<", msg size "<<msg->GetSize();
1233 int *pData = static_cast <int *>(vTofDigi.data());
1234
1235 int *pData = static_cast <int *>(msg->GetData());
1236 const Int_t NBytes=4;
1237 for (int iData=0; iData<msg->GetSize()/NBytes; iData++) {
1238 LOG(info) << Form(" ind %d, poi %p, data: 0x%08x",iData,pData,*pData++);
1239 }
1240 */
1241 /*
1242 auto msg = NewMessageFor("my_channel", 0,
1243 static_cast<void*>(vTofDigi.data()),
1244 vTofDigi.size() * sizeof(CbmTofDigi),
1245 FairMQNoCleanup, nullptr);
1246 */
1247
1248 // TODO: Implement sending same data to more than one channel
1249 // Need to create new message (copy message??)
1250 /*
1251 if (fChannelsToSend[idx]>1) {
1252 LOG(info) << "Need to copy FairMessage ?";
1253 }
1254 */
1255 // in case of error or transfer interruption,
1256 // return false to go to IDLE state
1257 // successfull transfer will return number of bytes
1258 // transfered (can be 0 if sending an empty message).
1259
1260 LOG(debug) << "Send data to channel " << idx << " " << fChannelsToSend[idx][0];
1261
1262
1263 // if (Send(msg, fChannelsToSend[idx][0]) < 0) {
1264 if (Send(parts, fChannelsToSend[idx][0]) < 0) {
1265 LOG(error) << "Problem sending data " << fChannelsToSend[idx][0];
1266 return false;
1267 }
1268 /*
1269 LOG(info) << "Sent message # "<< fNumTint << " at " << msg->GetData()
1270 << ", size " << msg->GetSize()<<" for "<<vTofDigi.size()<<" Digis at "
1271 << vTofDigi.data() << ", "<<&vTofDigi;
1272 */
1273 fNumTint++;
1274 //if(fNumTint==100) FairMQStateMachine::ChangeState(PAUSE); //sleep(10000); // Stop for debugging ...
1275 /*
1276 LOG(info) << "Send message " << fNumTint << " with a size of "
1277 << msg->GetSize();
1278 */
1279 return true;
1280}
1281
1283{
1284 UInt_t iNReq = fiReqDigiAddr.size();
1285 for (UInt_t i = 0; i < iNReq; i++)
1286 if (fiReqDigiAddr[i] == iAddr) return; // det already present, avoid double counting
1287 fiReqDigiAddr.resize(iNReq + 1); // hopefully the old entries are preserved ...
1288 fiReqDigiAddr[iNReq] = iAddr;
1289 LOG(info) << Form("Request Digi Address 0x%08x at index %d", iAddr, iNReq);
1290}
1291
1293
@ kNotExist
If not found.
static uint fiSelectComponents
bool IsChannelNameAllowed(std::string channelName)
Bool_t DoUnpack(const fles::Timeslice &ts, size_t component)
std::vector< UInt_t > fvuElinkToGet4
5 FEE with 8 GET4 each
std::vector< ULong64_t > fvulCurrentEpoch
std::vector< std::string > fAllowedChannels
void AddMsComponentToList(size_t component, UShort_t usDetectorId)
Temp until we change from CbmMcbmUnpack to something else.
void SetTimeOffsetNs(Double_t dOffsetIn=0.0)
void SetIgnoreOverlapMs(Bool_t bFlagIn=kTRUE)
Algo settings setters.
Int_t GetArrayIndex(Int_t gdpbId, Int_t get4Id)
virtual bool SendDigis(std::vector< CbmTofDigi * >, int)
std::vector< std::vector< std::string > > fChannelsToSend
bool HandleMessage(FairMQMessagePtr &, int)
bool HandleData(FairMQMessagePtr &, int)
CbmMcbm2018UnpackerAlgoTof * fUnpackerAlgo
Processing algo.
Int_t GetModuleId(Int_t i)
static constexpr UInt_t GetNrOfFeePerGbtx()
Int_t GetRpcSide(Int_t i)
Int_t GetNrOfGdpbs()
FIXME: replace with method returning the correspondign constants! see Star2019 parameter.
Int_t GetNrOfRpc(Int_t i)
Int_t GetRpcType(Int_t i)
static constexpr UInt_t GetNrOfChannelsPerFee()
Bool_t ProcessTs(const fles::Timeslice &ts)
void SetTimeOffsetNs(Double_t dOffsetIn=0.0)
void AddMsComponentToList(size_t component, UShort_t usDetectorId)
std::vector< T > & GetVector()
void SetIgnoreOverlapMs(Bool_t bFlagIn=kTRUE)
Control flags.
void ClearVector()
For unpacker algos.
Singleton buffer class for CBM raw data.
Double_t GetTimeLast() const
Data GetNextData(Double_t time)
Int_t GetSize() const
std::pair< boost::any, ECbmModuleId > Data
Double_t GetTimeFirst() const
void InsertData(Digi *digi)
static uint32_t GetUniqueAddress(uint32_t Sm, uint32_t Rpc, uint32_t Channel, uint32_t Side=0, uint32_t SmType=0, uint32_t RpcType=0)
Data class for expanded digital TOF information.
Definition CbmTofDigi.h:47
double GetSide() const
Channel Side.
Definition CbmTofDigi.h:160
double GetChannel() const
Channel .
Definition CbmTofDigi.h:156
int32_t GetAddress() const
Inherited from CbmDigi.
Definition CbmTofDigi.h:112
double GetTime() const
Inherited from CbmDigi.
Definition CbmTofDigi.h:131
double GetRpc() const
Detector aka Module aka RPC .
Definition CbmTofDigi.h:152
double GetTot() const
Alias for GetCharge.
Definition CbmTofDigi.h:140
void SetTime(double time)
Definition CbmTofDigi.h:165
void ChangeState(FairMQDevice *device, cbm::mq::Transition transition)
Definition CbmMQDefs.h:26
void LogState(FairMQDevice *device)
Definition CbmMQDefs.h:47
Hash for CbmL1LinkKey.