Skip to content
Snippets Groups Projects
CbmDeviceUnpackTofMcbm2018.cxx 49 KiB
Newer Older
/* Copyright (C) 2018-2020 PI-UHd, GSI
   SPDX-License-Identifier: GPL-3.0-only
Administrator's avatar
Administrator committed
   Authors: Florian Uhlig, Norbert Herrmann [committer] */
/**
 * CbmDeviceUnpackTofMcbm2018.cxx
 *
 * @since 2018-04-24
 * @author F. Uhlig
 */

#include "CbmDeviceUnpackTofMcbm2018.h"
Norbert Herrmann's avatar
Norbert Herrmann committed

#include "CbmDefs.h"
#include "CbmMQDefs.h"
#include "CbmMcbm2018TofPar.h"
Administrator's avatar
Administrator committed
#include "CbmMcbm2018UnpackerAlgoTof.h"
//#include "CbmHistManager.h"
#include "CbmTbDaqBuffer.h"
#include "CbmTofAddress.h"
#include "CbmTofDetectorId_v21a.h"  // in cbmdata/tof
Administrator's avatar
Administrator committed
#include "CbmTofDigi.h"

#include "StorableTimeslice.hpp"

#include "FairMQLogger.h"
Administrator's avatar
Administrator committed
#include "FairMQProgOptions.h"  // device->fConfig
#include "FairParGenericSet.h"
Administrator's avatar
Administrator committed
#include "FairRuntimeDb.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>
Administrator's avatar
Administrator committed
#include <iomanip>
#include <stdexcept>
Norbert Herrmann's avatar
Norbert Herrmann committed
#include <string>
Administrator's avatar
Administrator committed
struct InitTaskError : std::runtime_error {
  using std::runtime_error::runtime_error;
};

using namespace std;

//static Int_t iMess=0;
Administrator's avatar
Administrator committed
//const Int_t DetMask = 0x001FFFFF;

CbmDeviceUnpackTofMcbm2018::CbmDeviceUnpackTofMcbm2018()
  : fNumMessages(0)
  , fiSelectComponents(0)
  , fNumTint(0)
  , fEventHeader()
  , fiReqMode(0)
  , fiReqTint(0)
  , fiReqBeam(-1)
  , fiReqDigiAddr()
  , fiPulserMode(0)
  , fiPulMulMin(0)
  , fiPulTotMin(0)
  , fiPulTotMax(1000)
  , fuTotalMsNb(0)
  , fuOverlapMsNb(0)
  , fuCoreMs(0)
Administrator's avatar
Administrator committed
  , fdMsSizeInNs(0)
  , fdTsCoreSizeInNs(0)
Administrator's avatar
Administrator committed
  , fuMinNbGdpb(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)
Administrator's avatar
Administrator committed
  , fMsgCounter(11, 0)  // length of enum MessageTypes initialized with 0
  , fGdpbIdIndexMap()
  , fvulCurrentEpoch()
  , fvbFirstEpochSeen()
  , fNofEpochs(0)
  , fulCurrentEpochTime(0.)
  //, fdMsIndex(0.)
  , fdToffTof(0.)
  , fiAddrRef(0)
  //, fuDiamondDpbIdx(3)
  //, fbEpochSuppModeOn( kTRUE )
  //, fbGet4M24b( kFALSE )
  //, fbGet4v20( kTRUE )
  //, fbMergedEpochsOn( kTRUE )
  , fUnpackPar(nullptr)
  , fdLastDigiTime(0.)
  , fdFirstDigiTimeDif(0.)
  //, fdEvTime0(0.)
  , fhRawTDigEvBmon(nullptr)
Administrator's avatar
Administrator committed
  , 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())
Norbert Herrmann's avatar
Norbert Herrmann committed
  , fUnpackerAlgo(nullptr)
{
Administrator's avatar
Administrator committed
  fUnpackerAlgo = new CbmMcbm2018UnpackerAlgoTof();
Norbert Herrmann's avatar
Norbert Herrmann committed
CbmDeviceUnpackTofMcbm2018::~CbmDeviceUnpackTofMcbm2018() { delete fUnpackerAlgo; }
Norbert Herrmann's avatar
Norbert Herrmann committed
void CbmDeviceUnpackTofMcbm2018::InitTask()
try {
Administrator's avatar
Administrator committed
  // 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;
Norbert Herrmann's avatar
Norbert Herrmann committed
    if (!IsChannelNameAllowed(entry.first)) throw InitTaskError("Channel name does not match.");
Administrator's avatar
Administrator committed
    if (entry.first == "syscmd") {
      OnData(entry.first, &CbmDeviceUnpackTofMcbm2018::HandleMessage);
      continue;
Administrator's avatar
Administrator committed
    //if(entry.first != "tofdigis") OnData(entry.first, &CbmDeviceUnpackTofMcbm2018::HandleData);
Norbert Herrmann's avatar
Norbert Herrmann committed
    if (entry.first != "tofdigis") OnData(entry.first, &CbmDeviceUnpackTofMcbm2018::HandleParts);
Administrator's avatar
Administrator committed
    else {
      fChannelsToSend[0].push_back(entry.first);
      LOG(info) << "Init to send data to channel " << fChannelsToSend[0][0];
Administrator's avatar
Administrator committed
  }
  InitContainers();
  const Int_t iHeaderSize = 4;
  fEventHeader.resize(iHeaderSize);  // define size of eventheader int[]
  for (int i = 0; i < iHeaderSize; i++)
    fEventHeader[i] = 0;
  LOG(info) << "Read config";
Administrator's avatar
Administrator committed
  fiSelectComponents = fConfig->GetValue<uint64_t>("SelectComponents");
  fiReqMode          = fConfig->GetValue<uint64_t>("ReqMode");
  fiReqTint          = fConfig->GetValue<uint64_t>("ReqTint");
  fiReqBeam          = fConfig->GetValue<uint64_t>("ReqBeam");
Administrator's avatar
Administrator committed
  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)
Norbert Herrmann's avatar
Norbert Herrmann committed
    fiAddrRef = CbmTofAddress::GetUniqueAddress(iRefModId, iRefCtrId, 0, 0, iRefModType, iRefCtrType);
  LOG(info) << " Using Reference counter address 0x" << std::hex << fiAddrRef;

Administrator's avatar
Administrator committed
  //    Int_t iMaxAsicInactive = fConfig->GetValue<uint64_t>("MaxAsicInactive");
  //    fUnpackerAlgo->SetMaxAsicInactive( iMaxAsicInactive );
  Int_t iReqDet       = 1;
  Int_t iNReq         = 0;
  const Int_t iMaxReq = 50;
Administrator's avatar
Administrator committed

  while (iNReq < iMaxReq) {  // FIXME, setup parameter hardwired!
    iReqDet = fConfig->GetValue<uint64_t>(Form("ReqDet%d", iNReq));
    if (iReqDet == 0) break;
    AddReqDigiAddr(iReqDet);
    iNReq++;
  }
  LOG(info) << "Setup request";
Administrator's avatar
Administrator committed
  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++) {
Norbert Herrmann's avatar
Norbert Herrmann committed
                Int_t iAddr = CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx], iRpc, 0, 0, fviRpcType[iGbtx]);
Administrator's avatar
Administrator committed
                AddReqDigiAddr(iAddr);
              }
            break;

Administrator's avatar
Administrator committed
          case 9:  // HD 2-RPC boxes
            for (Int_t iRpc = 0; iRpc < 2; iRpc++) {
Norbert Herrmann's avatar
Norbert Herrmann committed
              Int_t iAddr = CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx], iRpc, 0, 0, fviRpcType[iGbtx]);
Administrator's avatar
Administrator committed
              AddReqDigiAddr(iAddr);
            }
            break;
          case 6:  // Buc box
            for (Int_t iRpc = 0; iRpc < 2; iRpc++) {
Norbert Herrmann's avatar
Norbert Herrmann committed
              Int_t iAddr = CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx], iRpc, 0, 0, fviRpcType[iGbtx]);
Administrator's avatar
Administrator committed
              AddReqDigiAddr(iAddr);
            }
            break;
Administrator's avatar
Administrator committed
          case 7:  // CERN box
            for (Int_t iRpc = 0; iRpc < 1; iRpc++) {
Norbert Herrmann's avatar
Norbert Herrmann committed
              Int_t iAddr = CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx], iRpc, 0, 0, 7);
Administrator's avatar
Administrator committed
              AddReqDigiAddr(iAddr);
            }
            break;
          case 8:  // ceramics
            for (Int_t iRpc = 0; iRpc < 8; iRpc++) {
Norbert Herrmann's avatar
Norbert Herrmann committed
              Int_t iAddr = CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx], iRpc, 0, 0, fviRpcType[iGbtx]);
Administrator's avatar
Administrator committed
              AddReqDigiAddr(iAddr);
            }
            break;
          case 5:  // add Diamond, single cell RPC
Norbert Herrmann's avatar
Norbert Herrmann committed
            Int_t iAddr = CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx], 0, 0, 0, 5);
Administrator's avatar
Administrator committed
            AddReqDigiAddr(iAddr);
            break;
        }
      }
Administrator's avatar
Administrator committed
  LOG(info) << "ReqMode " << fiReqMode << " in " << fiReqTint << " ns "
Norbert Herrmann's avatar
Norbert Herrmann committed
            << " with " << fiReqDigiAddr.size() << " detectors out of " << fviNrOfRpc.size() << " GBTx, PulserMode "
            << fiPulserMode << " with Mul " << fiPulMulMin << ", TotMin " << fiPulTotMin;
  LOG(info) << Form("ReqBeam 0x%08x", (uint) fiReqBeam);
Norbert Herrmann's avatar
Norbert Herrmann committed
}
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);
}

Norbert Herrmann's avatar
Norbert Herrmann committed
bool CbmDeviceUnpackTofMcbm2018::IsChannelNameAllowed(std::string channelName)
{
Administrator's avatar
Administrator committed
  for (auto const& entry : fAllowedChannels) {
    LOG(info) << "Inspect " << entry;
    std::size_t pos1 = channelName.find(entry);
Administrator's avatar
Administrator committed
    if (pos1 != std::string::npos) {
      const vector<std::string>::const_iterator pos =
Administrator's avatar
Administrator committed
        std::find(fAllowedChannels.begin(), fAllowedChannels.end(), entry);
      const vector<std::string>::size_type idx = pos - fAllowedChannels.begin();
      LOG(info) << "Found " << entry << " in " << channelName;
Norbert Herrmann's avatar
Norbert Herrmann committed
      LOG(info) << "Channel name " << channelName << " found in list of allowed channel names at position " << idx;
Norbert Herrmann's avatar
Norbert Herrmann committed
  LOG(info) << "Channel name " << channelName << " not found in list of allowed channel names.";
  LOG(error) << "Stop device.";
  return false;
}

Norbert Herrmann's avatar
Norbert Herrmann committed
Bool_t CbmDeviceUnpackTofMcbm2018::InitContainers()
{
  LOG(info) << "Init parameter containers for CbmDeviceUnpackTofMcbm2018.";
Administrator's avatar
Administrator committed
  //  FairRuntimeDb* fRtdb = FairRuntimeDb::instance();

  // 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
Administrator's avatar
Administrator committed
  std::string message {"CbmMcbm2018TofPar,111"};
Norbert Herrmann's avatar
Norbert Herrmann committed
  LOG(info) << "Requesting parameter container CbmMcbm2018TofPar, sending message: " << message;

  FairMQMessagePtr req(NewSimpleMessage("CbmMcbm2018TofPar,111"));
  FairMQMessagePtr rep(NewMessage());

Administrator's avatar
Administrator committed
  if (Send(req, "parameters") > 0) {
    if (Receive(rep, "parameters") >= 0) {
      if (rep->GetSize() != 0) {
        CbmMqTMessage tmsg(rep->GetData(), rep->GetSize());
Norbert Herrmann's avatar
Norbert Herrmann committed
        fUnpackPar = dynamic_cast<CbmMcbm2018TofPar*>(tmsg.ReadObject(tmsg.GetClass()));
        LOG(info) << "Received unpack parameter from parmq server: " << fUnpackPar;
Administrator's avatar
Administrator committed
        fUnpackPar->Print();
Norbert Herrmann's avatar
Norbert Herrmann committed
      }
      else {
Administrator's avatar
Administrator committed
        LOG(error) << "Received empty reply. Parameter not available";
      }
Administrator's avatar
Administrator committed
  }
Administrator's avatar
Administrator committed
  SetParContainers();
Administrator's avatar
Administrator committed
  Bool_t initOK = kTRUE;
  initOK &= fUnpackerAlgo->InitContainers();
  initOK &= ReInitContainers();  // needed for TInt parameters
Administrator's avatar
Administrator committed
  //  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 )
Norbert Herrmann's avatar
Norbert Herrmann committed
void CbmDeviceUnpackTofMcbm2018::SetParContainers()
{
Administrator's avatar
Administrator committed
  FairRuntimeDb* fRtdb = FairRuntimeDb::instance();
Administrator's avatar
Administrator committed
  TList* fParCList = fUnpackerAlgo->GetParList();
Norbert Herrmann's avatar
Norbert Herrmann committed
  LOG(info) << "Setting parameter containers for " << fParCList->GetEntries() << " entries ";
Administrator's avatar
Administrator committed
  for (Int_t iparC = 0; iparC < fParCList->GetEntries(); ++iparC) {
    FairParGenericSet* tempObj = (FairParGenericSet*) (fParCList->At(iparC));
    fParCList->Remove(tempObj);
Administrator's avatar
Administrator committed
    std::string sParamName {tempObj->GetName()};

Norbert Herrmann's avatar
Norbert Herrmann committed
    FairParGenericSet* newObj = dynamic_cast<FairParGenericSet*>(fRtdb->getContainer(sParamName.data()));
Administrator's avatar
Administrator committed
    LOG(info) << " - Get " << sParamName.data() << " at " << newObj;
    if (nullptr == newObj) {

Norbert Herrmann's avatar
Norbert Herrmann committed
      LOG(error) << "Failed to obtain parameter container " << sParamName << ", for parameter index " << iparC;
Administrator's avatar
Administrator committed
      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 )
Norbert Herrmann's avatar
Norbert Herrmann committed
void CbmDeviceUnpackTofMcbm2018::AddMsComponentToList(size_t component, UShort_t usDetectorId)
{
Administrator's avatar
Administrator committed
  fUnpackerAlgo->AddMsComponentToList(component, usDetectorId);
Norbert Herrmann's avatar
Norbert Herrmann committed
Bool_t CbmDeviceUnpackTofMcbm2018::ReInitContainers()
{
  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;

Administrator's avatar
Administrator committed
  /// 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 };
   */

Administrator's avatar
Administrator committed
  UInt_t uGet4topadi[32] = {4,  3,  2,  1,  // provided by Jochen
Norbert Herrmann's avatar
Norbert Herrmann committed
                            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};
Administrator's avatar
Administrator committed

  UInt_t uPaditoget4[32] = {4,  3,  2,  1,  // provided by Jochen
Norbert Herrmann's avatar
Norbert Herrmann committed
                            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};
Administrator's avatar
Administrator committed

  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);
Norbert Herrmann's avatar
Norbert Herrmann committed
  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};
Administrator's avatar
Administrator committed
  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);
  }
Administrator's avatar
Administrator committed
  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++) {
Administrator's avatar
Administrator committed
    Int_t iModuleIdMap = fviModuleId[iGbtx];
Administrator's avatar
Administrator committed
    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)
Norbert Herrmann's avatar
Norbert Herrmann committed
                fviRpcChUId[iCh] = CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx], iRpcMap, iStrMap,
                                                                   fviRpcSide[iGbtx], fviRpcType[iGbtx]);
Administrator's avatar
Administrator committed
              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)
Norbert Herrmann's avatar
Norbert Herrmann committed
                fviRpcChUId[iCh] = CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx], iRpcMap, iStrMap,
                                                                   fviRpcSide[iGbtx], fviRpcType[iGbtx]);
Administrator's avatar
Administrator committed
              else
                fviRpcChUId[iCh] = 0;
              //	 LOG(debug)<<Form("Map Ch %d to Address 0x%08x",iCh,fviRpcChUId[iCh]);
Administrator's avatar
Administrator committed
              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) {
Norbert Herrmann's avatar
Norbert Herrmann committed
          for (UInt_t uCh = 0; uCh < fUnpackPar->GetNrOfChannelsPerFee(); ++uCh) {
Administrator's avatar
Administrator committed
            if (uFee < 4 && (0 == uCh % 4 || uCh < 4)) {
              //  if(  0 == uCh )  {
              fviRpcChUId[iCh] = CbmTofAddress::GetUniqueAddress(
Norbert Herrmann's avatar
Norbert Herrmann committed
                fviModuleId[iGbtx], 0,
                uFee * fUnpackPar->GetNrOfChannelsPerFee() / 4 + uCh / 4 + 40 * fviRpcSide[iGbtx],
Administrator's avatar
Administrator committed
                //                           0, uFee + 10 * fviRpcSide[iGbtx],
Norbert Herrmann's avatar
Norbert Herrmann committed
                0, fviRpcType[iGbtx]);
              LOG(info) << Form("Map Bmon Ch %d to Address 0x%08x", iCh, fviRpcChUId[iCh]);
Norbert Herrmann's avatar
Norbert Herrmann committed
            }
            else
Administrator's avatar
Administrator committed
              fviRpcChUId[iCh] = 0;

            iCh++;
          }  // for( UInt_t uCh = 0; uCh < fUnpackPar->GetNrOfChannelsPerFee(); ++uCh )
Norbert Herrmann's avatar
Norbert Herrmann committed
        }    // for( UInt_t uFee = 0; uFee < fUnpackPar->GetNrOfFeePerGbtx(); ++uFee )
Administrator's avatar
Administrator committed
      } break;

      case 78:  // cern-20-gap + ceramic module
      {
        LOG(info) << " Map CERN 20 gap  at GBTX  -  iCh = " << iCh;
Norbert Herrmann's avatar
Norbert Herrmann committed
        // clang-format off
Administrator's avatar
Administrator committed
        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};
Norbert Herrmann's avatar
Norbert Herrmann committed
        // clang-format on
        Int_t iModuleId   = 0;
        Int_t iModuleType = 7;
        Int_t iRpcMap     = 0;
Administrator's avatar
Administrator committed
        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)
Norbert Herrmann's avatar
Norbert Herrmann committed
              fviRpcChUId[iCh] = CbmTofAddress::GetUniqueAddress(iModuleId, iRpcMap, iStrMap, iSideMap, iModuleType);
Administrator's avatar
Administrator committed
            else
              fviRpcChUId[iCh] = 0;
            iCh++;
          }
        }
      }
Administrator's avatar
Administrator committed
        [[fallthrough]];  // fall through is intended
      case 8:             // ceramics
Administrator's avatar
Administrator committed
      {
        Int_t iModuleId   = 0;
        Int_t iModuleType = 8;
        for (Int_t iRpc = 0; iRpc < 8; iRpc++) {
Norbert Herrmann's avatar
Norbert Herrmann committed
          fviRpcChUId[iCh] = CbmTofAddress::GetUniqueAddress(iModuleId, 7 - iRpc, 0, 0, iModuleType);
Administrator's avatar
Administrator committed
          iCh++;
        }
        iCh += (24 + 2 * 32);
      }
        LOG(info) << " Map end ceramics  box  at GBTX  -  iCh = " << iCh;

        break;

Administrator's avatar
Administrator committed
      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;
            switch (fviRpcSide[iGbtx]) {
              case 0:; break;
              case 1:; break;
              case 2:
                switch (iFeet) {
                  case 1:
                    iRpcMap  = iRpc[4];
                    iSideMap = iSide[4];
                    break;
                  case 4:
                    iRpcMap  = iRpc[1];
                    iSideMap = iSide[1];
                    break;
                  default:;
                }
                break;
            }
Administrator's avatar
Administrator committed
            if (iSideMap > -1)
              fviRpcChUId[iCh] =
Norbert Herrmann's avatar
Norbert Herrmann committed
                CbmTofAddress::GetUniqueAddress(fviModuleId[iGbtx], iRpcMap, iStrMap, iSideMap, fviRpcType[iGbtx]);
Administrator's avatar
Administrator committed
            else
              fviRpcChUId[iCh] = 0;

            iCh++;
          }
        }
      } break;

      case 6:  // Buc box
      {
Norbert Herrmann's avatar
Norbert Herrmann committed
        LOG(info) << " DevMap Buc box  at GBTX  -  iCh = " << iCh;
Administrator's avatar
Administrator committed
        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;
              case 5:  // HD cosmic 2020, Buc2018, v20a
                iStrMap = 31 - iStr;
                break;
              case 6:  //BUC special
              {
                switch (fviModuleId[iGbtx]) {
                  case 0: iRpcMap = 0; break;
                  case 1: iRpcMap = 1; break;
                }
                if (iFeet > 2) iModuleIdMap = 1;
Administrator's avatar
Administrator committed
              } break;
Norbert Herrmann's avatar
Norbert Herrmann committed
              case 7: {
                // clang-format off
                const Int_t iChMap[160]={
             	  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,
                   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,
          		  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,
          		  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,
          		   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
                };
                // clang-format on
                Int_t iInd = iFeet * 32 + iStr;
                Int_t i    = 0;
                for (; i < 160; i++)
                  if (iInd == iChMap[i]) break;
                iStrMap        = i % 32;
                Int_t iFeetInd = (i - iStrMap) / 32;
                switch (iFeet) {
                  case 0:
                    iRpcMap  = 0;
                    iSideMap = 1;
                    break;
                  case 1:
                    iRpcMap  = 1;
                    iSideMap = 1;
                    break;
                  case 2:
                    iRpcMap  = 1;
                    iSideMap = 0;
                    break;
                  case 3:
                    iRpcMap  = 0;
                    iSideMap = 0;
                    break;
                  case 4: iSideMap = -1; break;
                }
                iModuleIdMap = fviModuleId[iGbtx];
                LOG(info) << "Buc of GBTX " << iGbtx
                          << Form(", Feet %1d, Str %2d, i %3d, FeetInd %1d, Rpc %1d, Side %1d, Str %2d ", iFeet, iStr,
                                  i, iFeetInd, iRpcMap, iSideMap, iStrMap);
              } break;
Administrator's avatar
Administrator committed
              default:;
            }
            if (iSideMap > -1)
Norbert Herrmann's avatar
Norbert Herrmann committed
              fviRpcChUId[iCh] =
                CbmTofAddress::GetUniqueAddress(iModuleIdMap, iRpcMap, iStrMap, iSideMap, fviRpcType[iGbtx]);
Administrator's avatar
Administrator committed
            else
              fviRpcChUId[iCh] = 0;

            iCh++;
          }
        }
      } break;

      case -1:
        LOG(info) << " Found unused GBTX link at iCh = " << iCh;
        iCh += 160;
        break;

Norbert Herrmann's avatar
Norbert Herrmann committed
      default: LOG(error) << "Invalid Type  specifier for Gbtx " << iGbtx << ": " << fviRpcType[iGbtx];
Administrator's avatar
Administrator committed
    }
  }

  for (UInt_t i = 0; i < uNrOfChannels; i = i + 8) {
    if (i % 64 == 0) LOG(info) << " Index " << i;
Norbert Herrmann's avatar
Norbert Herrmann committed
    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]);
Administrator's avatar
Administrator committed
  }  // for( UInt_t i = 0; i < uNrOfChannels; ++i)
Norbert Herrmann's avatar
Norbert Herrmann committed
void CbmDeviceUnpackTofMcbm2018::CreateHistograms()
{
Administrator's avatar
Administrator committed
  LOG(info) << "create Histos for " << fuNrOfGdpbs << " gDPBs ";
  fhRawTDigEvBmon =
    new TH1F(Form("Raw_TDig-EvBmon"), Form("Raw digi time difference to 1st digi ; time [ns]; cts"), 500, 0, 100.);
  //   fHM->Add( Form("Raw_TDig-EvBmon"), fhRawTDigEvBmon);
Administrator's avatar
Administrator committed
  fhRawTDigRef0 =
Norbert Herrmann's avatar
Norbert Herrmann committed
    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);

Administrator's avatar
Administrator committed
  fhRawTDigRef =
Norbert Herrmann's avatar
Norbert Herrmann committed
    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);

Norbert Herrmann's avatar
Norbert Herrmann committed
  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);

Administrator's avatar
Administrator committed
  fhRawTRefDig1 =
Norbert Herrmann's avatar
Norbert Herrmann committed
    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);

Norbert Herrmann's avatar
Norbert Herrmann committed
  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);

Administrator's avatar
Administrator committed
  fhRawTotCh.resize(fuNrOfGdpbs);
  fhChCount.resize(fuNrOfGdpbs);
  fhChanCoinc.resize(fuNrOfGdpbs * fuNrOfFeePerGdpb / 2);
  for (UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; uGdpb++) {
Norbert Herrmann's avatar
Norbert Herrmann committed
    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.);
Administrator's avatar
Administrator committed
    //      fHM->Add( Form("Raw_Tot_gDPB_%02u", uGdpb), fhRawTotCh[ uGdpb ]);

    fhChCount[uGdpb] =
Norbert Herrmann's avatar
Norbert Herrmann committed
      new TH1I(Form("ChCount_gDPB_%02u", uGdpb), Form("Channel counts gDPB %02u; channel; Hits", uGdpb),
               fuNrOfChannelsPerGdpb, 0., fuNrOfChannelsPerGdpb);
Administrator's avatar
Administrator committed
    //      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 ++ )
      */
Administrator's avatar
Administrator committed
    fhChanCoinc[uGdpb] =
Norbert Herrmann's avatar
Norbert Herrmann committed
      new TH2F(Form("fhChanCoinc_%02u", uGdpb), Form("Channels Coincidence %02u; Left; Right", uGdpb),
               fuNrOfChannelsPerGdpb, 0., fuNrOfChannelsPerGdpb, fuNrOfChannelsPerGdpb, 0., fuNrOfChannelsPerGdpb);
Administrator's avatar
Administrator committed
  }  // for( UInt_t uGdpb = 0; uGdpb < fuMinNbGdpb; uGdpb ++)
Norbert Herrmann's avatar
Norbert Herrmann committed
  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)
Norbert Herrmann's avatar
Norbert Herrmann committed
bool CbmDeviceUnpackTofMcbm2018::HandleData(FairMQMessagePtr& msg, int /*index*/)
{
Administrator's avatar
Administrator committed
  // Don't do anything with the data
  // Maybe add an message counter which counts the incomming messages and add
  // an output
Norbert Herrmann's avatar
Norbert Herrmann committed
  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);

Administrator's avatar
Administrator committed
  fles::StorableTimeslice component {0};
  inputArchive >> component;

  //  CheckTimeslice(component);

  DoUnpack(component, 0);

  BuildTint(0);

Norbert Herrmann's avatar
Norbert Herrmann committed
  if (fNumMessages % 10000 == 0) LOG(info) << "Processed " << fNumMessages << " time slices";
Norbert Herrmann's avatar
Norbert Herrmann committed
bool CbmDeviceUnpackTofMcbm2018::HandleParts(FairMQParts& parts, int /*index*/)
{
Administrator's avatar
Administrator committed
  // Don't do anything with the data
  // Maybe add an message counter which counts the incomming messages and add
  // an output
Norbert Herrmann's avatar
Norbert Herrmann committed
  LOG(debug) << "Received message number " << fNumMessages << " with " << parts.Size() << " parts";
Administrator's avatar
Administrator committed

  fles::StorableTimeslice ts {0};
Administrator's avatar
Administrator committed
  switch (fiSelectComponents) {
    case 0: {
Norbert Herrmann's avatar
Norbert Herrmann committed
      std::string msgStr(static_cast<char*>(parts.At(0)->GetData()), (parts.At(0))->GetSize());
      std::istringstream iss(msgStr);
      boost::archive::binary_iarchive inputArchive(iss);
Administrator's avatar
Administrator committed
      inputArchive >> ts;
      //CheckTimeslice(ts);
Administrator's avatar
Administrator committed
      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++) {
Norbert Herrmann's avatar
Norbert Herrmann committed
        std::string msgStr(static_cast<char*>(parts.At(i)->GetData()), (parts.At(i))->GetSize());
Administrator's avatar
Administrator committed
        std::istringstream iss(msgStr);
        boost::archive::binary_iarchive inputArchive(iss);
        //fles::StorableTimeslice component{i};
        inputArchive >> component;

        //      CheckTimeslice(component);
Administrator's avatar
Administrator committed
        fUnpackerAlgo->AddMsComponentToList(0, 0x60);  // TOF data
Norbert Herrmann's avatar
Norbert Herrmann committed
        LOG(debug) << "HandleParts message " << fNumMessages << " with indx " << component.index();
Administrator's avatar
Administrator committed
        DoUnpack(component, 0);
      }
    } break;
    default:;
Norbert Herrmann's avatar
Norbert Herrmann committed
  if (fNumMessages % 10000 == 0) LOG(info) << "Processed " << fNumMessages << " time slices";
Norbert Herrmann's avatar
Norbert Herrmann committed
bool CbmDeviceUnpackTofMcbm2018::HandleMessage(FairMQMessagePtr& msg, int /*index*/)
{
Administrator's avatar
Administrator committed
  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"

Administrator's avatar
Administrator committed
  if (strcmp(cmda, "STOP")) {
    LOG(info) << "STOP";
    fUnpackerAlgo->Finish();
    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;
}

Norbert Herrmann's avatar
Norbert Herrmann committed
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;
Administrator's avatar
Administrator committed

  if (kFALSE == fUnpackerAlgo->ProcessTs(ts)) {
Norbert Herrmann's avatar
Norbert Herrmann committed
    LOG(error) << "Failed processing TS " << ts.index() << " in unpacker algorithm class";
Administrator's avatar
Administrator committed
    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();
        });
   */

Norbert Herrmann's avatar
Norbert Herrmann committed
  LOG(debug) << "Insert " << vDigi.size() << " digis into DAQ buffer  with size " << fBuffer->GetSize();
Administrator's avatar
Administrator committed
  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)
Norbert Herrmann's avatar
Norbert Herrmann committed
      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(),
Administrator's avatar
Administrator committed
                       fBuffer->GetSize());
Administrator's avatar
Administrator committed
    fBuffer->InsertData<CbmTofDigi>(fDigi);
  }
  vDigi.clear();
  fUnpackerAlgo->ClearVector();
Administrator's avatar
Administrator committed
  return kTRUE;
Norbert Herrmann's avatar
Norbert Herrmann committed
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;
Administrator's avatar
Administrator committed
  double fdMaxDeltaT = (double) fiReqTint;  // in ns
  LOG(debug) << "BuildTint: Buffer size " << fBuffer->GetSize() << ", DeltaT "
Norbert Herrmann's avatar
Norbert Herrmann committed
             << (fBuffer->GetTimeLast() - fBuffer->GetTimeFirst()) / 1.E9 << " s";
  CbmTbDaqBuffer::Data data;
  CbmTofDigi* digi;
Administrator's avatar
Administrator committed
  while (fBuffer->GetSize() > 0) {
    Double_t fTimeBufferLast = fBuffer->GetTimeLast();

Administrator's avatar
Administrator committed
    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);

Administrator's avatar
Administrator committed
    Double_t dTEnd    = digi->GetTime() + fdMaxDeltaT;
    Double_t dTEndMax = digi->GetTime() + 2 * fdMaxDeltaT;
Norbert Herrmann's avatar
Norbert Herrmann committed
    LOG(debug) << Form("Next event at %f until %f, max %f ", digi->GetTime(), dTEnd, dTEndMax);
Administrator's avatar
Administrator committed
    if (dTEnd > fTimeBufferLast) {
      LOG(warn) << Form("Remaining buffer < %f with %d entries is not "
                        "sufficient for digi ending at %f -> skipped ",
Norbert Herrmann's avatar
Norbert Herrmann committed
                        fTimeBufferLast, fBuffer->GetSize(), dTEnd);
Norbert Herrmann's avatar
Norbert Herrmann committed
    LOG(debug) << "BuildTint0 with digi " << Form("0x%08x at %012.2f", digi->GetAddress(), digi->GetTime());
    Bool_t bDet[fiReqDigiAddr.size()][2];
Administrator's avatar
Administrator committed
    for (UInt_t i = 0; i < fiReqDigiAddr.size(); i++)
      for (Int_t j = 0; j < 2; j++)
        bDet[i][j] = kFALSE;  //initialize
    Bool_t bPul[fiReqDigiAddr.size()][2];
Administrator's avatar
Administrator committed
    for (UInt_t i = 0; i < fiReqDigiAddr.size(); i++)
      for (Int_t j = 0; j < 2; j++)
        bPul[i][j] = kFALSE;  //initialize
    Bool_t bBeam = kFALSE;

    std::vector<CbmTofDigi*> vdigi;
    UInt_t nDigi = 0;
    //const Int_t AddrMask=0x003FFFFF;
    const Int_t AddrMask = 0x001FFFFF;
Administrator's avatar
Administrator committed
    Bool_t bOut          = kFALSE;
Norbert Herrmann's avatar
Norbert Herrmann committed
    Int_t iBucMul        = 0;
Administrator's avatar
Administrator committed

    while (data.second != ECbmModuleId::kNotExist) {  // build digi array
      digi = boost::any_cast<CbmTofDigi*>(data.first);
Norbert Herrmann's avatar
Norbert Herrmann committed
      LOG(debug) << "GetNextData " << digi << ", " << data.second << ",  " << Form("%f %f", digi->GetTime(), dTEnd)
                 << ", Mul " << nDigi;
Administrator's avatar
Administrator committed
      if (nDigi == vdigi.size()) vdigi.resize(nDigi + 100);
      vdigi[nDigi++] = digi;
Norbert Herrmann's avatar
Norbert Herrmann committed

      Int_t iAddr = digi->GetAddress() & AddrMask;
      if (iAddr == 0x00003006 || iAddr == 0x0000b006) {
        iBucMul++;
        LOG(debug) << Form("Event %10d: BucMul %2d, addr 0x%08x, side %d, strip %2d, rpc %d", fEventHeader[0], iBucMul,
                           digi->GetAddress(), (Int_t) digi->GetSide(), (Int_t) digi->GetChannel(),
                           (Int_t) digi->GetRpc());
      }
Administrator's avatar
Administrator committed
      for (UInt_t i = 0; i < fiReqDigiAddr.size(); i++)
        if ((digi->GetAddress() & AddrMask) == fiReqDigiAddr[i]) {
          Int_t j    = ((CbmTofDigi*) digi)->GetSide();
          bDet[i][j] = kTRUE;
          if (fiReqDigiAddr[i] == (Int_t) fiReqBeam) {
            bBeam = kTRUE;
Norbert Herrmann's avatar
Norbert Herrmann committed
            LOG(debug) << "Found ReqBeam at index " << nDigi - 1 << ", req " << i;