Newer
Older
/**
* CbmDeviceUnpackTofMcbm2018.cxx
*
* @since 2018-04-24
* @author F. Uhlig
*/
#include "CbmDeviceUnpackTofMcbm2018.h"
#include "CbmMQDefs.h"
#include "CbmMcbm2018TofPar.h"
//#include "CbmHistManager.h"
#include "CbmTbDaqBuffer.h"
#include "CbmTofAddress.h"
#include "CbmTofDetectorId_v14a.h" // in cbmdata/tof
#include "CbmTofDigi.h"
#include "StorableTimeslice.hpp"
#include "FairMQLogger.h"
#include "FairParGenericSet.h"
#include "TH1.h"
#include "TH2.h"
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
// include this header to serialize vectors
#include <boost/serialization/vector.hpp>
#include <array>
struct InitTaskError : std::runtime_error {
using std::runtime_error::runtime_error;
};
using namespace std;
//static Int_t iMess=0;
CbmDeviceUnpackTofMcbm2018::CbmDeviceUnpackTofMcbm2018()
: fNumMessages(0)
, fiSelectComponents(0)
, fNumTint(0)
, fEventHeader()
, fiReqMode(0)
, fiReqTint(0)
, fiReqDigiAddr()
, fiPulserMode(0)
, fiPulMulMin(0)
, fiPulTotMin(0)
, fiPulTotMax(1000)
, fuTotalMsNb(0)
, fuOverlapMsNb(0)
, fuCoreMs(0)
, fuNrOfGdpbs(0)
, fuNrOfFeePerGdpb(0)
, fuNrOfGet4PerFee(0)
, fuNrOfChannelsPerGet4(0)
, fuNrOfChannelsPerFee(0)
, fuNrOfGet4(0)
, fuNrOfGet4PerGdpb(0)
, fuNrOfChannelsPerGdpb(0)
, fuGdpbId(0)
, fuGdpbNr(0)
, fuGet4Id(0)
, fuGet4Nr(0)
, fMsgCounter(11, 0) // length of enum MessageTypes initialized with 0
, fGdpbIdIndexMap()
, fvulCurrentEpoch()
, fvbFirstEpochSeen()
, fNofEpochs(0)
, fulCurrentEpochTime(0.)
//, fdMsIndex(0.)
//, fuDiamondDpbIdx(3)
//, fbEpochSuppModeOn( kTRUE )
//, fbGet4M24b( kFALSE )
//, fbGet4v20( kTRUE )
//, fbMergedEpochsOn( kTRUE )
, fUnpackPar(nullptr)
, fdLastDigiTime(0.)
, fdFirstDigiTimeDif(0.)
//, fdEvTime0(0.)
, fhRawTDigEvT0(nullptr)
, fhRawTDigRef0(nullptr)
, fhRawTDigRef(nullptr)
, fhRawTRefDig0(nullptr)
, fhRawTRefDig1(nullptr)
, fhRawDigiLastDigi(nullptr)
, fhRawTotCh()
, fhChCount()
, fvbChanThere()
, fhChanCoinc()
, fhDetChanCoinc(nullptr)
, fvuPadiToGet4()
, fvuGet4ToPadi()
, fvuElinkToGet4()
, fvuGet4ToElink()
, fviRpcType()
, fviModuleId()
, fviNrOfRpc()
, fviRpcSide()
, fviRpcChUId()
, fBuffer(CbmTbDaqBuffer::Instance())
, fUnpackerAlgo(nullptr) {
fUnpackerAlgo = new CbmMcbm2018UnpackerAlgoTof();
CbmDeviceUnpackTofMcbm2018::~CbmDeviceUnpackTofMcbm2018() {
delete fUnpackerAlgo;
void CbmDeviceUnpackTofMcbm2018::InitTask() try {
// Get the information about created channels from the device
// Check if the defined channels from the topology (by name)
// are in the list of channels which are possible/allowed
// for the device
// The idea is to check at initilization if the devices are
// properly connected. For the time beeing this is done with a
// nameing convention. It is not avoided that someone sends other
// data on this channel.
//logger::SetLogLevel("INFO");
int noChannel = fChannels.size();
LOG(info) << "Number of defined channels: " << noChannel;
for (auto const& entry : fChannels) {
LOG(info) << "Channel name: " << entry.first;
if (!IsChannelNameAllowed(entry.first))
throw InitTaskError("Channel name does not match.");
if (entry.first == "syscmd") {
OnData(entry.first, &CbmDeviceUnpackTofMcbm2018::HandleMessage);
continue;
//if(entry.first != "tofdigis") OnData(entry.first, &CbmDeviceUnpackTofMcbm2018::HandleData);
if (entry.first != "tofdigis")
OnData(entry.first, &CbmDeviceUnpackTofMcbm2018::HandleParts);
else {
fChannelsToSend[0].push_back(entry.first);
LOG(info) << "Init to send data to channel " << fChannelsToSend[0][0];
}
InitContainers();
const Int_t iHeaderSize = 4;
fEventHeader.resize(iHeaderSize); // define size of eventheader int[]
for (int i = 0; i < iHeaderSize; i++)
fEventHeader[i] = 0;
fiSelectComponents = fConfig->GetValue<uint64_t>("SelectComponents");
fiReqMode = fConfig->GetValue<uint64_t>("ReqMode");
fiReqTint = fConfig->GetValue<uint64_t>("ReqTint");
fiReqBeam = fConfig->GetValue<uint64_t>("ReqBeam");
fiPulserMode = fConfig->GetValue<int64_t>("PulserMode");
fiPulMulMin = fConfig->GetValue<uint64_t>("PulMulMin");
fiPulTotMin = fConfig->GetValue<uint64_t>("PulTotMin");
fiPulTotMax = fConfig->GetValue<uint64_t>("PulTotMax");
fdToffTof = fConfig->GetValue<double_t>("ToffTof");
Int_t iRefModType = fConfig->GetValue<int64_t>("RefModType");
Int_t iRefModId = fConfig->GetValue<int64_t>("RefModId");
Int_t iRefCtrType = fConfig->GetValue<int64_t>("RefCtrType");
Int_t iRefCtrId = fConfig->GetValue<int64_t>("RefCtrId");
if (iRefModType > -1)
fiAddrRef = CbmTofAddress::GetUniqueAddress(
iRefModId, iRefCtrId, 0, 0, iRefModType, iRefCtrType);
LOG(info) << " Using Reference counter address 0x" << std::hex << fiAddrRef;
// Int_t iMaxAsicInactive = fConfig->GetValue<uint64_t>("MaxAsicInactive");
// fUnpackerAlgo->SetMaxAsicInactive( iMaxAsicInactive );
Int_t iReqDet = 1;
Int_t iNReq = 0;
while (iNReq < iMaxReq) { // FIXME, setup parameter hardwired!
iReqDet = fConfig->GetValue<uint64_t>(Form("ReqDet%d", iNReq));
if (iReqDet == 0) break;
AddReqDigiAddr(iReqDet);
iNReq++;
}
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
if (fiReqMode > 0)
if (iNReq == 0) { // take all defined detectors
for (UInt_t iGbtx = 0; iGbtx < fviNrOfRpc.size(); iGbtx++) {
switch (fviRpcType[iGbtx]) {
case 0: // mTof modules
case 1: // eTof modules
if (iGbtx % 2 == 0)
for (Int_t iRpc = 0; iRpc < fviNrOfRpc[iGbtx]; iRpc++) {
Int_t iAddr = CbmTofAddress::GetUniqueAddress(
fviModuleId[iGbtx], iRpc, 0, 0, fviRpcType[iGbtx]);
AddReqDigiAddr(iAddr);
}
break;
case 9: // HD 2-RPC boxes
for (Int_t iRpc = 0; iRpc < 2; iRpc++) {
Int_t iAddr = CbmTofAddress::GetUniqueAddress(
fviModuleId[iGbtx], iRpc, 0, 0, fviRpcType[iGbtx]);
AddReqDigiAddr(iAddr);
}
break;
case 6: // Buc box
for (Int_t iRpc = 0; iRpc < 2; iRpc++) {
Int_t iAddr = CbmTofAddress::GetUniqueAddress(
fviModuleId[iGbtx], iRpc, 0, 0, fviRpcType[iGbtx]);
AddReqDigiAddr(iAddr);
}
break;
case 7: // CERN box
for (Int_t iRpc = 0; iRpc < 1; iRpc++) {
Int_t iAddr = CbmTofAddress::GetUniqueAddress(
fviModuleId[iGbtx], iRpc, 0, 0, 7);
AddReqDigiAddr(iAddr);
}
break;
case 8: // ceramics
for (Int_t iRpc = 0; iRpc < 8; iRpc++) {
Int_t iAddr = CbmTofAddress::GetUniqueAddress(
fviModuleId[iGbtx], iRpc, 0, 0, fviRpcType[iGbtx]);
AddReqDigiAddr(iAddr);
}
break;
case 5: // add Diamond, single cell RPC
Int_t iAddr =
CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx], 0, 0, 0, 5);
AddReqDigiAddr(iAddr);
break;
}
}
LOG(info) << "ReqMode " << fiReqMode << " in " << fiReqTint << " ns "
<< " with " << fiReqDigiAddr.size() << " detectors out of "
<< fviNrOfRpc.size() << " GBTx, PulserMode " << fiPulserMode
<< " with Mul " << fiPulMulMin << ", TotMin " << fiPulTotMin;
LOG(info) << Form("ReqBeam 0x%08x", (uint) fiReqBeam);
} catch (InitTaskError& e) {
LOG(error) << e.what();
// Wrapper defined in CbmMQDefs.h to support different FairMQ versions
cbm::mq::ChangeState(this, cbm::mq::Transition::ErrorFound);
}
bool CbmDeviceUnpackTofMcbm2018::IsChannelNameAllowed(std::string channelName) {
for (auto const& entry : fAllowedChannels) {
LOG(info) << "Inspect " << entry;
std::size_t pos1 = channelName.find(entry);
const vector<std::string>::const_iterator pos =
std::find(fAllowedChannels.begin(), fAllowedChannels.end(), entry);
const vector<std::string>::size_type idx = pos - fAllowedChannels.begin();
LOG(info) << "Found " << entry << " in " << channelName;
LOG(info) << "Channel name " << channelName
<< " found in list of allowed channel names at position "
<< idx;
return true;
}
}
LOG(info) << "Channel name " << channelName
<< " not found in list of allowed channel names.";
LOG(error) << "Stop device.";
return false;
}
LOG(info) << "Init parameter containers for CbmDeviceUnpackTofMcbm2018.";
// NewSimpleMessage creates a copy of the data and takes care of its destruction (after the transfer takes place).
// Should only be used for small data because of the cost of an additional copy
std::string message {"CbmMcbm2018TofPar,111"};
LOG(info)
<< "Requesting parameter container CbmMcbm2018TofPar, sending message: "
<< message;
FairMQMessagePtr req(NewSimpleMessage("CbmMcbm2018TofPar,111"));
FairMQMessagePtr rep(NewMessage());
if (Send(req, "parameters") > 0) {
if (Receive(rep, "parameters") >= 0) {
if (rep->GetSize() != 0) {
CbmMQTMessage tmsg(rep->GetData(), rep->GetSize());
fUnpackPar =
dynamic_cast<CbmMcbm2018TofPar*>(tmsg.ReadObject(tmsg.GetClass()));
LOG(info) << "Received unpack parameter from parmq server: "
<< fUnpackPar;
fUnpackPar->Print();
} else {
LOG(error) << "Received empty reply. Parameter not available";
}
Bool_t initOK = kTRUE;
initOK &= fUnpackerAlgo->InitContainers();
initOK &= ReInitContainers(); // needed for TInt parameters
// CreateHistograms();
initOK &= fUnpackerAlgo->CreateHistograms();
fvulCurrentEpoch.resize(fuNrOfGdpbs * fuNrOfGet4PerGdpb);
fvbFirstEpochSeen.resize(fuNrOfGdpbs * fuNrOfGet4PerGdpb);
fvbChanThere.resize(fviRpcChUId.size(), kFALSE);
for (UInt_t i = 0; i < fuNrOfGdpbs; ++i) {
for (UInt_t j = 0; j < fuNrOfGet4PerGdpb; ++j) {
fvulCurrentEpoch[GetArrayIndex(i, j)] = 0;
fvbFirstEpochSeen[GetArrayIndex(i, j)] = kFALSE;
} // for( UInt_t j = 0; j < fuNrOfGet4PerGdpb; ++j )
} // for( UInt_t i = 0; i < fuNrOfGdpbs; ++i )
fNumTint = 0;
return initOK;
}
void CbmDeviceUnpackTofMcbm2018::SetParContainers() {
FairRuntimeDb* fRtdb = FairRuntimeDb::instance();
LOG(info) << "Setting parameter containers for " << fParCList->GetEntries()
<< " entries ";
for (Int_t iparC = 0; iparC < fParCList->GetEntries(); ++iparC) {
FairParGenericSet* tempObj = (FairParGenericSet*) (fParCList->At(iparC));
fParCList->Remove(tempObj);
std::string sParamName {tempObj->GetName()};
FairParGenericSet* newObj =
dynamic_cast<FairParGenericSet*>(fRtdb->getContainer(sParamName.data()));
LOG(info) << " - Get " << sParamName.data() << " at " << newObj;
if (nullptr == newObj) {
LOG(error) << "Failed to obtain parameter container " << sParamName
<< ", for parameter index " << iparC;
return;
} // if( nullptr == newObj )
if (iparC == 0) {
newObj = (FairParGenericSet*) fUnpackPar;
LOG(info) << " - Mod " << sParamName.data() << " to " << newObj;
}
fParCList->AddAt(newObj, iparC);
// delete tempObj;
} // for( Int_t iparC = 0; iparC < fParCList->GetEntries(); ++iparC )
void CbmDeviceUnpackTofMcbm2018::AddMsComponentToList(size_t component,
UShort_t usDetectorId) {
fUnpackerAlgo->AddMsComponentToList(component, usDetectorId);
LOG(info) << "ReInit parameter containers for CbmDeviceUnpackMcbm2018TofPar.";
fuNrOfGdpbs = fUnpackPar->GetNrOfGdpbs();
LOG(info) << "Nr. of Tof GDPBs: " << fuNrOfGdpbs;
fuMinNbGdpb = fuNrOfGdpbs;
fuNrOfFeePerGdpb = fUnpackPar->GetNrOfFeesPerGdpb();
LOG(info) << "Nr. of FEES per Tof GDPB: " << fuNrOfFeePerGdpb;
fuNrOfGet4PerFee = fUnpackPar->GetNrOfGet4PerFee();
LOG(info) << "Nr. of GET4 per Tof FEE: " << fuNrOfGet4PerFee;
fuNrOfChannelsPerGet4 = fUnpackPar->GetNrOfChannelsPerGet4();
LOG(info) << "Nr. of channels per GET4: " << fuNrOfChannelsPerGet4;
fuNrOfChannelsPerFee = fuNrOfGet4PerFee * fuNrOfChannelsPerGet4;
LOG(info) << "Nr. of channels per FEE: " << fuNrOfChannelsPerFee;
fuNrOfGet4 = fuNrOfGdpbs * fuNrOfFeePerGdpb * fuNrOfGet4PerFee;
LOG(info) << "Nr. of GET4s: " << fuNrOfGet4;
fuNrOfGet4PerGdpb = fuNrOfFeePerGdpb * fuNrOfGet4PerFee;
LOG(info) << "Nr. of GET4s per GDPB: " << fuNrOfGet4PerGdpb;
/// TODO: move these constants somewhere shared, e.g the parameter file
fvuPadiToGet4.resize(fuNrOfChannelsPerFee);
fvuGet4ToPadi.resize(fuNrOfChannelsPerFee);
/* source: Monitor
UInt_t uGet4topadi[32] = {
4, 3, 2, 1, // provided by Jochen
24, 23, 22, 21,
8, 7, 6, 5,
28, 27, 26, 25,
12, 11, 10, 9,
32, 31, 30, 29,
16, 15, 14, 13,
20, 19, 18, 17 };
*/
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
UInt_t uGet4topadi[32] = {4, 3, 2, 1, // provided by Jochen
8, 7, 6, 5, 12, 11, 10, 9, 16, 15,
14, 13, 20, 19, 18, 17, 24, 23, 22, 21,
28, 27, 26, 25, 32, 31, 30, 29};
UInt_t uPaditoget4[32] = {4, 3, 2, 1, // provided by Jochen
12, 11, 10, 9, 20, 19, 18, 17, 28, 27,
26, 25, 32, 31, 30, 29, 8, 7, 6, 5,
16, 15, 14, 13, 24, 23, 22, 21};
for (UInt_t uChan = 0; uChan < fuNrOfChannelsPerFee; ++uChan) {
fvuPadiToGet4[uChan] = uPaditoget4[uChan] - 1;
fvuGet4ToPadi[uChan] = uGet4topadi[uChan] - 1;
} // for( UInt_t uChan = 0; uChan < fuNrOfChannelsPerFee; ++uChan )
/// TODO: move these constants somewhere shared, e.g the parameter file
fvuElinkToGet4.resize(kuNbGet4PerGbtx);
fvuGet4ToElink.resize(kuNbGet4PerGbtx);
UInt_t kuElinkToGet4[kuNbGet4PerGbtx] = {
27, 2, 7, 3, 31, 26, 30, 1, 33, 37, 32, 13, 9, 14,
10, 15, 17, 21, 16, 35, 34, 38, 25, 24, 0, 6, 20, 23,
18, 22, 28, 4, 29, 5, 19, 36, 39, 8, 12, 11};
UInt_t kuGet4ToElink[kuNbGet4PerGbtx] = {
24, 7, 1, 3, 31, 33, 25, 2, 37, 12, 14, 39, 38, 11,
13, 15, 18, 16, 28, 34, 26, 17, 29, 27, 23, 22, 5, 0,
30, 32, 6, 4, 10, 8, 20, 19, 35, 9, 21, 36};
for (UInt_t uLinkAsic = 0; uLinkAsic < kuNbGet4PerGbtx; ++uLinkAsic) {
fvuElinkToGet4[uLinkAsic] = kuElinkToGet4[uLinkAsic];
fvuGet4ToElink[uLinkAsic] = kuGet4ToElink[uLinkAsic];
} // for( UInt_t uChan = 0; uChan < fuNrOfChannelsPerFee; ++uChan )
UInt_t uNrOfGbtx = fUnpackPar->GetNrOfGbtx();
fviRpcType.resize(uNrOfGbtx);
fviModuleId.resize(uNrOfGbtx);
fviNrOfRpc.resize(uNrOfGbtx);
fviRpcSide.resize(uNrOfGbtx);
for (UInt_t iGbtx = 0; iGbtx < uNrOfGbtx; ++iGbtx) {
fviNrOfRpc[iGbtx] = fUnpackPar->GetNrOfRpc(iGbtx);
fviRpcType[iGbtx] = fUnpackPar->GetRpcType(iGbtx);
fviRpcSide[iGbtx] = fUnpackPar->GetRpcSide(iGbtx);
fviModuleId[iGbtx] = fUnpackPar->GetModuleId(iGbtx);
}
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
UInt_t uNrOfChannels = fuNrOfGet4 * fuNrOfChannelsPerGet4;
LOG(info) << "Nr. of possible Tof channels: " << uNrOfChannels;
// CbmTofDetectorId* fTofId = new CbmTofDetectorId_v14a();
fviRpcChUId.resize(uNrOfChannels);
UInt_t iCh = 0;
for (UInt_t iGbtx = 0; iGbtx < uNrOfGbtx; iGbtx++) {
switch (fviRpcType[iGbtx]) {
case 0: // CBM modules
if (fviRpcSide[iGbtx] < 2) { // mTof modules
const Int_t RpcMap[5] = {4, 2, 0, 3, 1};
for (Int_t iRpc = 0; iRpc < fviNrOfRpc[iGbtx]; iRpc++) {
Int_t iStrMax = 32;
Int_t iChNext = 1;
for (Int_t iStr = 0; iStr < iStrMax; iStr++) {
Int_t iStrMap = iStr;
Int_t iRpcMap = RpcMap[iRpc];
if (fviRpcSide[iGbtx] == 0) iStrMap = 31 - iStr;
if (fviModuleId[iGbtx] > -1)
fviRpcChUId[iCh] =
CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx],
iRpcMap,
iStrMap,
fviRpcSide[iGbtx],
fviRpcType[iGbtx]);
else
fviRpcChUId[iCh] = 0;
// LOG(debug)<<Form("Map Ch %d to Address 0x%08x",iCh,fviRpcChUId[iCh]);
iCh += iChNext;
}
}
}
break;
case 1: // STAR eTOF modules
if (fviRpcSide[iGbtx] < 2) { // mTof modules
const Int_t RpcMap[3] = {0, 1, 2};
for (Int_t iRpc = 0; iRpc < fviNrOfRpc[iGbtx]; iRpc++) {
Int_t iStrMax = 32;
Int_t iChNext = 1;
for (Int_t iStr = 0; iStr < iStrMax; iStr++) {
Int_t iStrMap = iStr;
Int_t iRpcMap = RpcMap[iRpc];
if (fviRpcSide[iGbtx] == 0) iStrMap = 31 - iStr;
if (fviModuleId[iGbtx] > -1)
fviRpcChUId[iCh] =
CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx],
iRpcMap,
iStrMap,
fviRpcSide[iGbtx],
fviRpcType[iGbtx]);
else
fviRpcChUId[iCh] = 0;
// LOG(DEBUG)<<Form("Map Ch %d to Address 0x%08x",iCh,fviRpcChUId[iCh]);
iCh += iChNext;
}
}
}
iCh += 64;
break;
case 5: // Diamond
{
LOG(info) << " Map diamond at GBTX - iCh = " << iCh;
for (UInt_t uFee = 0; uFee < fUnpackPar->GetNrOfFeePerGbtx(); ++uFee) {
for (UInt_t uCh = 0; uCh < fUnpackPar->GetNrOfChannelsPerFee();
++uCh) {
if (uFee < 4 && (0 == uCh % 4 || uCh < 4)) {
// if( 0 == uCh ) {
fviRpcChUId[iCh] = CbmTofAddress::GetUniqueAddress(
fviModuleId[iGbtx],
0,
uFee * fUnpackPar->GetNrOfChannelsPerFee() / 4 + uCh / 4
+ 40 * fviRpcSide[iGbtx],
// 0, uFee + 10 * fviRpcSide[iGbtx],
0,
fviRpcType[iGbtx]);
LOG(info) << Form(
"Map T0 Ch %d to Address 0x%08x", iCh, fviRpcChUId[iCh]);
} else
fviRpcChUId[iCh] = 0;
iCh++;
} // for( UInt_t uCh = 0; uCh < fUnpackPar->GetNrOfChannelsPerFee(); ++uCh )
} // for( UInt_t uFee = 0; uFee < fUnpackPar->GetNrOfFeePerGbtx(); ++uFee )
} break;
case 78: // cern-20-gap + ceramic module
{
LOG(info) << " Map CERN 20 gap at GBTX - iCh = " << iCh;
const Int_t StrMap[32] = {0, 1, 2, 3, 4, 31, 5, 6, 7, 30, 8,
9, 10, 29, 11, 12, 13, 14, 28, 15, 16, 17,
18, 27, 26, 25, 24, 23, 22, 21, 20, 19};
Int_t iModuleId = 0;
Int_t iModuleType = 7;
Int_t iRpcMap = 0;
for (Int_t iFeet = 0; iFeet < 2; iFeet++) {
for (Int_t iStr = 0; iStr < 32; iStr++) {
Int_t iStrMap = 31 - 12 - StrMap[iStr];
Int_t iSideMap = iFeet;
if (iStrMap < 20)
fviRpcChUId[iCh] = CbmTofAddress::GetUniqueAddress(
iModuleId, iRpcMap, iStrMap, iSideMap, iModuleType);
else
fviRpcChUId[iCh] = 0;
iCh++;
}
}
}
// fall through is intended
case 8: // ceramics
{
Int_t iModuleId = 0;
Int_t iModuleType = 8;
for (Int_t iRpc = 0; iRpc < 8; iRpc++) {
fviRpcChUId[iCh] = CbmTofAddress::GetUniqueAddress(
iModuleId, 7 - iRpc, 0, 0, iModuleType);
iCh++;
}
iCh += (24 + 2 * 32);
}
LOG(info) << " Map end ceramics box at GBTX - iCh = " << iCh;
break;
case 9: // Star2 boxes
{
LOG(info) << " Map Star2 box at GBTX - iCh = " << iCh;
const Int_t iRpc[5] = {1, -1, 1, 0, 0};
const Int_t iSide[5] = {1, -1, 0, 1, 0};
for (Int_t iFeet = 0; iFeet < 5; iFeet++) {
for (Int_t iStr = 0; iStr < 32; iStr++) {
Int_t iStrMap = iStr;
Int_t iRpcMap = iRpc[iFeet];
Int_t iSideMap = iSide[iFeet];
if (iSideMap == 0) iStrMap = 31 - iStr;
if (iSideMap > -1)
fviRpcChUId[iCh] =
CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx],
iRpcMap,
iStrMap,
iSideMap,
fviRpcType[iGbtx]);
else
fviRpcChUId[iCh] = 0;
iCh++;
}
}
} break;
case 6: // Buc box
{
LOG(info) << " Map Buc box at GBTX - iCh = " << iCh;
const Int_t iRpc[5] = {0, -1, 0, 1, 1};
const Int_t iSide[5] = {1, -1, 0, 1, 0};
for (Int_t iFeet = 0; iFeet < 5; iFeet++) {
for (Int_t iStr = 0; iStr < 32; iStr++) {
Int_t iStrMap = iStr;
Int_t iRpcMap = iRpc[iFeet];
Int_t iSideMap = iSide[iFeet];
//if(iSideMap == 0)iStrMap=31-iStr;
switch (fviRpcSide[iGbtx]) {
case 0:; break;
case 1: // HD cosmic 2019, Buc2018, v18n
iStrMap = 31 - iStr;
iRpcMap = 1 - iRpcMap;
break;
case 2: // v18m_cosmicHD
// iStrMap=31-iStr;
iSideMap = 1 - iSideMap;
break;
case 3:
iStrMap = 31 - iStr;
iRpcMap = 1 - iRpcMap;
iSideMap = 1 - iSideMap;
break;
case 4: // HD cosmic 2019, Buc2018, v18o
iRpcMap = 1 - iRpcMap;
break;
default:;
}
if (iSideMap > -1)
fviRpcChUId[iCh] =
CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx],
iRpcMap,
iStrMap,
iSideMap,
fviRpcType[iGbtx]);
else
fviRpcChUId[iCh] = 0;
iCh++;
}
}
} break;
case -1:
LOG(info) << " Found unused GBTX link at iCh = " << iCh;
iCh += 160;
break;
default:
LOG(error) << "Invalid Type specifier for Gbtx " << iGbtx << ": "
<< fviRpcType[iGbtx];
}
}
for (UInt_t i = 0; i < uNrOfChannels; i = i + 8) {
if (i % 64 == 0) LOG(info) << " Index " << i;
LOG(info) << Form("0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x",
fviRpcChUId[i],
fviRpcChUId[i + 1],
fviRpcChUId[i + 2],
fviRpcChUId[i + 3],
fviRpcChUId[i + 4],
fviRpcChUId[i + 5],
fviRpcChUId[i + 6],
fviRpcChUId[i + 7]);
} // for( UInt_t i = 0; i < uNrOfChannels; ++i)
return kTRUE;
}
void CbmDeviceUnpackTofMcbm2018::CreateHistograms() {
LOG(info) << "create Histos for " << fuNrOfGdpbs << " gDPBs ";
fhRawTDigEvT0 =
new TH1F(Form("Raw_TDig-EvT0"),
Form("Raw digi time difference to 1st digi ; time [ns]; cts"),
500,
0,
100.);
// fHM->Add( Form("Raw_TDig-EvT0"), fhRawTDigEvT0);
fhRawTDigRef0 =
new TH1F(Form("Raw_TDig-Ref0"),
Form("Raw digi time difference to Ref ; time [ns]; cts"),
6000,
-10000,
50000);
// fHM->Add( Form("Raw_TDig-Ref0"), fhRawTDigRef0);
fhRawTDigRef =
new TH1F(Form("Raw_TDig-Ref"),
Form("Raw digi time difference to Ref ; time [ns]; cts"),
6000,
-1000,
5000);
// fHM->Add( Form("Raw_TDig-Ref"), fhRawTDigRef);
fhRawTRefDig0 =
new TH1F(Form("Raw_TRef-Dig0"),
Form("Raw Ref time difference to last digi ; time [ns]; cts"),
9999,
-50000,
50000);
// fHM->Add( Form("Raw_TRef-Dig0"), fhRawTRefDig0);
fhRawTRefDig1 =
new TH1F(Form("Raw_TRef-Dig1"),
Form("Raw Ref time difference to last digi ; time [ns]; cts"),
9999,
-5000,
5000);
// fHM->Add( Form("Raw_TRef-Dig1"), fhRawTRefDig1);
fhRawDigiLastDigi =
new TH1F(Form("Raw_Digi-LastDigi"),
Form("Raw Digi time difference to last digi ; time [ns]; cts"),
9999,
-5000,
5000);
// 9999, -5000000, 5000000);
// fHM->Add( Form("Raw_Digi-LastDigi"), fhRawDigiLastDigi);
fhRawTotCh.resize(fuNrOfGdpbs);
fhChCount.resize(fuNrOfGdpbs);
fhChanCoinc.resize(fuNrOfGdpbs * fuNrOfFeePerGdpb / 2);
for (UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; uGdpb++) {
fhRawTotCh[uGdpb] =
new TH2F(Form("Raw_Tot_gDPB_%02u", uGdpb),
Form("Raw TOT gDPB %02u; channel; TOT [bin]", uGdpb),
fuNrOfChannelsPerGdpb,
0.,
fuNrOfChannelsPerGdpb,
256,
0.,
256.);
// fHM->Add( Form("Raw_Tot_gDPB_%02u", uGdpb), fhRawTotCh[ uGdpb ]);
fhChCount[uGdpb] =
new TH1I(Form("ChCount_gDPB_%02u", uGdpb),
Form("Channel counts gDPB %02u; channel; Hits", uGdpb),
fuNrOfChannelsPerGdpb,
0.,
fuNrOfChannelsPerGdpb);
// fHM->Add( Form("ChCount_gDPB_%02u", uGdpb), fhChCount[ uGdpb ]);
/*
for( UInt_t uLeftFeb = uGdpb*fuNrOfFebsPerGdpb / 2;
uLeftFeb < (uGdpb + 1 )*fuNrOfFebsPerGdpb / 2;
++uLeftFeb )
{
fhChanCoinc[ uLeftFeb ] = new TH2F( Form("fhChanCoinc_%02u", uLeftFeb),
Form("Channels Coincidence %02; Left; Right", uLeftFeb),
fuNrOfChannelsPerFee, 0., fuNrOfChannelsPerFee,
fuNrOfChannelsPerFee, 0., fuNrOfChannelsPerFee );
} // for( UInt_t uLeftFeb = 0; uLeftFeb < fuNrOfFebsPerGdpb / 2; uLeftFeb ++ )
*/
fhChanCoinc[uGdpb] =
new TH2F(Form("fhChanCoinc_%02u", uGdpb),
Form("Channels Coincidence %02u; Left; Right", uGdpb),
fuNrOfChannelsPerGdpb,
0.,
fuNrOfChannelsPerGdpb,
fuNrOfChannelsPerGdpb,
0.,
fuNrOfChannelsPerGdpb);
} // for( UInt_t uGdpb = 0; uGdpb < fuMinNbGdpb; uGdpb ++)
fhDetChanCoinc = new TH2F("fhDetChanCoinc",
"Det Channels Coincidence; Left; Right",
32,
0.,
32,
32,
0.,
32);
}
// handler is called whenever a message arrives on "data", with a reference to the message and a sub-channel index (here 0)
bool CbmDeviceUnpackTofMcbm2018::HandleData(FairMQMessagePtr& msg,
int /*index*/) {
// Don't do anything with the data
// Maybe add an message counter which counts the incomming messages and add
// an output
LOG(debug) << "Received message number " << fNumMessages << " with size "
<< msg->GetSize();
std::string msgStr(static_cast<char*>(msg->GetData()), msg->GetSize());
std::istringstream iss(msgStr);
boost::archive::binary_iarchive inputArchive(iss);
inputArchive >> component;
DoUnpack(component, 0);
BuildTint(0);
if (fNumMessages % 10000 == 0)
LOG(info) << "Processed " << fNumMessages << " time slices";
return true;
}
bool CbmDeviceUnpackTofMcbm2018::HandleParts(FairMQParts& parts,
int /*index*/) {
// Don't do anything with the data
// Maybe add an message counter which counts the incomming messages and add
// an output
LOG(debug) << "Received message number " << fNumMessages << " with "
<< parts.Size() << " parts";
fles::StorableTimeslice ts {0};
switch (fiSelectComponents) {
case 0: {
std::string msgStr(static_cast<char*>(parts.At(0)->GetData()),
(parts.At(0))->GetSize());
std::istringstream iss(msgStr);
boost::archive::binary_iarchive inputArchive(iss);
if (1 == fNumMessages) {
LOG(info) << "Initialize TS components list to " << ts.num_components();
for (size_t c {0}; c < ts.num_components(); c++) {
auto systemID = static_cast<int>(ts.descriptor(c, 0).sys_id);
LOG(info) << "Found systemID: " << std::hex << systemID << std::dec;
fUnpackerAlgo->AddMsComponentToList(c, systemID); // TOF data
}
}
DoUnpack(ts, 0);
} break;
case 1: {
fles::StorableTimeslice component {0};
uint ncomp = parts.Size();
for (uint i = 0; i < ncomp; i++) {
std::string msgStr(static_cast<char*>(parts.At(i)->GetData()),
(parts.At(i))->GetSize());
std::istringstream iss(msgStr);
boost::archive::binary_iarchive inputArchive(iss);
//fles::StorableTimeslice component{i};
inputArchive >> component;
fUnpackerAlgo->AddMsComponentToList(0, 0x60); // TOF data
LOG(debug) << "HandleParts message " << fNumMessages << " with indx "
<< component.index();
DoUnpack(component, 0);
}
} break;
default:;
}
BuildTint(0);
if (fNumMessages % 10000 == 0)
LOG(info) << "Processed " << fNumMessages << " time slices";
return true;
}
bool CbmDeviceUnpackTofMcbm2018::HandleMessage(FairMQMessagePtr& msg,
int /*index*/) {
const char* cmd = (char*) (msg->GetData());
const char cmda[4] = {*cmd};
LOG(info) << "Handle message " << cmd << ", " << cmd[0];
cbm::mq::LogState(this);
// only one implemented so far "Stop"
cbm::mq::ChangeState(this, cbm::mq::Transition::Ready);
cbm::mq::LogState(this);
cbm::mq::ChangeState(this, cbm::mq::Transition::DeviceReady);
cbm::mq::LogState(this);
cbm::mq::ChangeState(this, cbm::mq::Transition::Idle);
cbm::mq::LogState(this);
cbm::mq::ChangeState(this, cbm::mq::Transition::End);
cbm::mq::LogState(this);
}
return true;
}
Bool_t CbmDeviceUnpackTofMcbm2018::DoUnpack(const fles::Timeslice& ts,
size_t component) {
LOG(debug) << "Timeslice " << ts.index() << " contains "
<< ts.num_microslices(component) << " microslices of component "
<< component;
if (kFALSE == fUnpackerAlgo->ProcessTs(ts)) {
LOG(error) << "Failed processing TS " << ts.index()
<< " in unpacker algorithm class";
return kTRUE;
} // if( kFALSE == fUnpackerAlgo->ProcessTs( ts ) )
/// Copy the digis in the DaqBuffer
std::vector<CbmTofDigi> vDigi = fUnpackerAlgo->GetVector();
/*
// time sort vDigis
sort(vDigi.begin(), vDigi.end(),
[](const CbmTofDigi & a, const CbmTofDigi & b) -> bool
{
return a.GetTime() < b.GetTime();
});
*/
LOG(debug) << "Insert " << vDigi.size()
<< " digis into DAQ buffer with size " << fBuffer->GetSize();
for (auto digi : vDigi) {
// copy Digi for insertion into DAQ buffer
CbmTofDigi* fDigi = new CbmTofDigi(digi);
//if( (fDigi->GetAddress() & 0x000F00F ) != fiAddrRef ) fDigi->SetTime(fDigi->GetTime()+fdToffTof); // shift all Tof Times for v14a geometries
if ((fDigi->GetAddress() & 0x000780F) != fiAddrRef)
fDigi->SetTime(fDigi->GetTime()
+ fdToffTof); // shift all Tof Times for V21a
LOG(debug) << "BufferInsert digi "
<< Form(
"0x%08x at %012.2f", fDigi->GetAddress(), fDigi->GetTime())
<< Form(", first %012.2f, last %012.2f, size %u",
fBuffer->GetTimeFirst(),
fBuffer->GetTimeLast(),
fBuffer->GetSize());
fBuffer->InsertData<CbmTofDigi>(fDigi);
}
vDigi.clear();
fUnpackerAlgo->ClearVector();
void CbmDeviceUnpackTofMcbm2018::BuildTint(int iMode = 0) {
// iMode - sending condition
// 0 (default)- build time interval only if last buffer entry is older the start + TSLength
// 1 (finish), empty buffer without checking
// Steering variables
double TSLENGTH = 1.E6;
LOG(debug) << "BuildTint: Buffer size " << fBuffer->GetSize() << ", DeltaT "
<< (fBuffer->GetTimeLast() - fBuffer->GetTimeFirst()) / 1.E9
<< " s";
CbmTbDaqBuffer::Data data;
CbmTofDigi* digi;
Double_t fTimeBufferLast = fBuffer->GetTimeLast();
switch (iMode) {
case 0:
if (fTimeBufferLast - fBuffer->GetTimeFirst() < TSLENGTH) return;
break;
case 1:; break;
data = fBuffer->GetNextData(fTimeBufferLast);
digi = boost::any_cast<CbmTofDigi*>(data.first);
assert(digi);
Double_t dTEnd = digi->GetTime() + fdMaxDeltaT;
Double_t dTEndMax = digi->GetTime() + 2 * fdMaxDeltaT;
LOG(debug) << Form(
"Next event at %f until %f, max %f ", digi->GetTime(), dTEnd, dTEndMax);
if (dTEnd > fTimeBufferLast) {
LOG(warn) << Form("Remaining buffer < %f with %d entries is not "
"sufficient for digi ending at %f -> skipped ",
fTimeBufferLast,
fBuffer->GetSize(),
dTEnd);
LOG(debug) << "BuildTint0 with digi "
<< Form(
"0x%08x at %012.2f", digi->GetAddress(), digi->GetTime());
Bool_t bDet[fiReqDigiAddr.size()][2];