Skip to content
Snippets Groups Projects
CbmDeviceUnpackTofStar2018.cxx 29.1 KiB
Newer Older
/* Copyright (C) 2018-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
   SPDX-License-Identifier: GPL-3.0-only
   Authors: Florian Uhlig [committer] */
/**
 * CbmDeviceUnpackTofStar2018.cxx
 *
 * @since 2018-04-24
 * @author F. Uhlig
 */

#include "CbmDeviceUnpackTofStar2018.h"

#include "CbmTofUnpackPar.h"
//#include "CbmHistManager.h"
#include "CbmTbDaqBuffer.h"
#include "CbmTofDigiExp.h"

#include "StorableTimeslice.hpp"

#include "FairMQLogger.h"
Administrator's avatar
Administrator committed
#include "FairMQProgOptions.h"  // device->fConfig

#include "TH1.h"
#include "TH2.h"

#include <boost/archive/binary_iarchive.hpp>

#include <iomanip>
#include <stdexcept>
#include <string>
Administrator's avatar
Administrator committed
struct InitTaskError : std::runtime_error {
  using std::runtime_error::runtime_error;
};
Administrator's avatar
Administrator committed
static Int_t iMess  = 0;
const Int_t DetMask = 0x0001FFFF;

CbmDeviceUnpackTofStar2018::CbmDeviceUnpackTofStar2018()
  : fNumMessages(0)
  , fuMsAcceptsPercent(100)
  , fuOverlapMsNb(0)
Administrator's avatar
Administrator committed
  , fuMinNbGdpb(0)
  , fuCurrNbGdpb(0)
  , fuNrOfGdpbs(0)
  , fuNrOfFebsPerGdpb(0)
  , fuNrOfGet4PerFeb(0)
  , fuNrOfChannelsPerGet4(0)
  , fuNrOfChannelsPerFeet(0)
  , fuNrOfGet4(0)
  , fuNrOfGet4PerGdpb(0)
  , fuNrOfChannelsPerGdpb(0)
Administrator's avatar
Administrator committed
  , fMsgCounter(11, 0)  // length of enum MessageTypes initialized with 0
  , fGdpbIdIndexMap()
  , fuGdpbId(0)
  , fuGdpbNr(0)
  , fuGet4Id(0)
  , fuGet4Nr(0)
Administrator's avatar
Administrator committed
  //  , fHM(new CbmHistManager())
  , fvulCurrentEpoch()
  , fvbFirstEpochSeen()
  , fNofEpochs(0)
  , fulCurrentEpochTime(0.)
  , fEquipmentId(0)
  , fdMsIndex(0.)
  , fdTShiftRef(0.)
Administrator's avatar
Administrator committed
  , fbEpochSuppModeOn(kFALSE)
  , fbGet4M24b(kFALSE)
  , fbGet4v20(kFALSE)
  , fbMergedEpochsOn(kFALSE)
  , fDigi(nullptr)
  , fUnpackPar(nullptr)
  , fdRefTime(0.)
  , 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)
  , fvmEpSupprBuffer()
  , fBuffer(CbmTbDaqBuffer::Instance())
Administrator's avatar
Administrator committed
  , fulGdpbTsMsb(0.)
  , fulGdpbTsLsb(0.)
  , fulStarTsMsb(0.)
  , fulStarTsMid(0.)
  , fulGdpbTsFullLast(0.)
  , fulStarTsFullLast(0.)
  , fuStarTokenLast(0)
Administrator's avatar
Administrator committed
  , fuStarDaqCmdLast(0)
  , fuStarTrigCmdLast(0)
{
}
Administrator's avatar
Administrator committed

void CbmDeviceUnpackTofStar2018::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.
  int noChannel = fChannels.size();
  LOG(info) << "Number of defined input channels: " << noChannel;
  for (auto const& entry : fChannels) {
    LOG(info) << "Channel name: " << entry.first;
    if (!IsChannelNameAllowed(entry.first)) throw InitTaskError("Channel name does not match.");
Administrator's avatar
Administrator committed
    OnData(entry.first, &CbmDeviceUnpackTofStar2018::HandleData);
  }
  InitContainers();
}
catch (InitTaskError& e) {
Administrator's avatar
Administrator committed
  LOG(error) << e.what();
  ChangeState(ERROR_FOUND);
bool CbmDeviceUnpackTofStar2018::IsChannelNameAllowed(std::string channelName)
{
Administrator's avatar
Administrator committed
  for (auto const& entry : fAllowedChannels) {
    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;
      LOG(info) << "Channel name " << channelName << " found in list of allowed channel names at position " << idx;
  LOG(info) << "Channel name " << channelName << " not found in list of allowed channel names.";
  LOG(error) << "Stop device.";
  return false;
}

Bool_t CbmDeviceUnpackTofStar2018::InitContainers()
{
  LOG(info) << "Init parameter containers for CbmDeviceUnpackTofStar2018.";
Administrator's avatar
Administrator committed

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

  FairMQMessagePtr req(NewSimpleMessage("CbmTofUnpackPar,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());
        fUnpackPar = static_cast<CbmTofUnpackPar*>(tmsg.ReadObject(tmsg.GetClass()));
Administrator's avatar
Administrator committed
        LOG(info) << "Received parameter from the server:";
        fUnpackPar->print();
Administrator's avatar
Administrator committed
        LOG(error) << "Received empty reply. Parameter not available";
      }
  Bool_t initOK = ReInitContainers();
Administrator's avatar
Administrator committed

  CreateHistograms();
Administrator's avatar
Administrator committed

  fvulCurrentEpoch.resize(fuNrOfGdpbs * fuNrOfGet4PerGdpb);
  fvbFirstEpochSeen.resize(fuNrOfGdpbs * fuNrOfGet4PerGdpb);
  fvbChanThere.resize(fUnpackPar->GetNumberOfChannels(), 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 )

Bool_t CbmDeviceUnpackTofStar2018::ReInitContainers()
{
  LOG(info) << "ReInit parameter containers for CbmDeviceUnpackTofStar2018.";
Administrator's avatar
Administrator committed

  fuNrOfGdpbs = fUnpackPar->GetNrOfRocs();
  LOG(info) << "Nr. of Tof GDPBs: " << fuNrOfGdpbs;
  fuMinNbGdpb = fuNrOfGdpbs;
Administrator's avatar
Administrator committed

  fuNrOfFebsPerGdpb = fUnpackPar->GetNrOfFebsPerGdpb();
  LOG(info) << "Nr. of FEBS per Tof GDPB: " << fuNrOfFebsPerGdpb;
Administrator's avatar
Administrator committed

  fuNrOfGet4PerFeb = fUnpackPar->GetNrOfGet4PerFeb();
  LOG(info) << "Nr. of GET4 per Tof FEB: " << fuNrOfGet4PerFeb;
Administrator's avatar
Administrator committed

  fuNrOfChannelsPerGet4 = fUnpackPar->GetNrOfChannelsPerGet4();
  LOG(info) << "Nr. of channels per GET4: " << fuNrOfChannelsPerGet4;
Administrator's avatar
Administrator committed

  fuNrOfChannelsPerFeet = fuNrOfGet4PerFeb * fuNrOfChannelsPerGet4;
  LOG(info) << "Nr. of channels per FEET: " << fuNrOfChannelsPerFeet;
Administrator's avatar
Administrator committed

  fuNrOfGet4 = fuNrOfGdpbs * fuNrOfFebsPerGdpb * fuNrOfGet4PerFeb;
  LOG(info) << "Nr. of GET4s: " << fuNrOfGet4;
Administrator's avatar
Administrator committed

  fuNrOfGet4PerGdpb = fuNrOfFebsPerGdpb * fuNrOfGet4PerFeb;
  LOG(info) << "Nr. of GET4s per GDPB: " << fuNrOfGet4PerGdpb;
Administrator's avatar
Administrator committed

  fuNrOfChannelsPerGdpb = fuNrOfGet4PerGdpb * fuNrOfChannelsPerGet4;
  LOG(info) << "Nr. of channels per GDPB: " << fuNrOfChannelsPerGdpb;
Administrator's avatar
Administrator committed

  fGdpbIdIndexMap.clear();
Administrator's avatar
Administrator committed
  for (UInt_t i = 0; i < fuNrOfGdpbs; ++i) {
    fGdpbIdIndexMap[fUnpackPar->GetRocId(i)] = i;
    LOG(info) << "GDPB Id of TOF  " << i << " : " << std::hex << fUnpackPar->GetRocId(i) << std::dec;
Administrator's avatar
Administrator committed
  }  // for( UInt_t i = 0; i < fuNrOfGdpbs; ++i )
  UInt_t uNrOfChannels = fUnpackPar->GetNumberOfChannels();
  LOG(info) << "Nr. of mapped Tof channels: " << uNrOfChannels;
Administrator's avatar
Administrator committed
  for (UInt_t i = 0; i < uNrOfChannels; ++i) {
    if (i % 8 == 0) LOG(info);
    LOG(info) << Form(" 0x%08x", fUnpackPar->GetChannelToDetUIdMap(i));
  }  // for( UInt_t i = 0; i < uNrOfChannels; ++i)
Administrator's avatar
Administrator committed

  LOG(info) << "Plot Channel Rate => " << (fUnpackPar->IsChannelRateEnabled() ? "ON" : "OFF");
Administrator's avatar
Administrator committed

  if (fbEpochSuppModeOn) fvmEpSupprBuffer.resize(fuNrOfGet4);

void CbmDeviceUnpackTofStar2018::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 =
    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 =
    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);
Administrator's avatar
Administrator 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 =
    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);
Administrator's avatar
Administrator 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 * fuNrOfFebsPerGdpb / 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.);
Administrator's avatar
Administrator committed
    //      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);
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),
	fuNrOfChannelsPerFeet, 0., fuNrOfChannelsPerFeet,
	fuNrOfChannelsPerFeet, 0., fuNrOfChannelsPerFeet );
	} // for( UInt_t uLeftFeb = 0; uLeftFeb < fuNrOfFebsPerGdpb / 2; uLeftFeb ++ )
      */
Administrator's avatar
Administrator committed
    fhChanCoinc[uGdpb] =
      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 ++)
  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 CbmDeviceUnpackTofStar2018::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
  LOG(info) << "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);

  return true;
}

Bool_t CbmDeviceUnpackTofStar2018::DoUnpack(const fles::Timeslice& ts, size_t component)
{
  LOG(debug) << "Timeslice contains " << ts.num_microslices(component) << " microslices of component " << component;
Administrator's avatar
Administrator committed

  // Loop over microslices
  Int_t iMessageType   = -111;
  size_t numCompMsInTs = ts.num_microslices(component);
  for (size_t m = 0; m < numCompMsInTs; ++m) {
    // Jump some microslices if needed
    //      if( fuMsAcceptsPercent < m)
    //         continue;

    // Ignore overlap ms if number defined by user
    if (numCompMsInTs - fuOverlapMsNb <= m) continue;

    constexpr uint32_t kuBytesPerMessage = 8;

    auto msDescriptor        = ts.descriptor(component, m);
    fEquipmentId             = msDescriptor.eq_id;
    fdMsIndex                = static_cast<double>(msDescriptor.idx);
    const uint8_t* msContent = reinterpret_cast<const uint8_t*>(ts.content(component, m));
Administrator's avatar
Administrator committed

    uint32_t size = msDescriptor.size;
    if (0 < size) LOG(debug) << "Microslice " << m << ": " << fdMsIndex << " has size: " << size;
Administrator's avatar
Administrator committed

    // If not integer number of message in input buffer, print warning/error
    if (0 != (size % kuBytesPerMessage))
      LOG(error) << "The input microslice buffer does NOT "
                 << "contain only complete nDPB messages!";

    // If not integer number of message in input buffer, print warning/error
    if (0 != (size % kuBytesPerMessage))
      LOG(error) << "The input microslice buffer does NOT "
                 << "contain only complete nDPB messages!";

    // Compute the number of complete messages in the input microslice buffer
    uint32_t uNbMessages = (size - (size % kuBytesPerMessage)) / kuBytesPerMessage;
Administrator's avatar
Administrator committed

    // Prepare variables for the loop on contents
    const uint64_t* pInBuff = reinterpret_cast<const uint64_t*>(msContent);
    for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx++) {
      // Fill message
      uint64_t ulData = static_cast<uint64_t>(pInBuff[uIdx]);
      ngdpb::Message mess(ulData);
Administrator's avatar
Administrator committed
      /*
         if(fair::Logger::Logging(fair::Severity::debug)
         {
            mess.printDataCout();
Administrator's avatar
Administrator committed
      // Increment counter for different message types
      iMessageType = mess.getMessageType();
      fMsgCounter[iMessageType]++;

      fuGdpbId = mess.getRocNumber();
      fuGdpbNr = fGdpbIdIndexMap[fuGdpbId];

      fuGet4Id = mess.getGdpbGenChipId();
      fuGet4Nr = (fuGdpbNr * fuNrOfGet4PerGdpb) + fuGet4Id;

      if (fuNrOfGet4PerGdpb <= fuGet4Id && ngdpb::MSG_STAR_TRI != iMessageType
          && (get4v1x::kuChipIdMergedEpoch != fuGet4Id || kFALSE == fbMergedEpochsOn)) {
        LOG(warn) << "Message with Get4 ID too high: " << fuGet4Id << " VS " << fuNrOfGet4PerGdpb
                  << " set in parameters, message ignored";
Administrator's avatar
Administrator committed
        continue;
      }

      switch (mess.getMessageType()) {
        case ngdpb::MSG_HIT:
        case ngdpb::MSG_EPOCH:
        case ngdpb::MSG_GET4: {
          if (fbGet4M24b) FillHitInfo(mess);
Administrator's avatar
Administrator committed
          else
            PrintGenInfo(mess);
          break;
        }  // case old non tof messages
        case ngdpb::MSG_EPOCH2: {
          if (get4v1x::kuChipIdMergedEpoch == fuGet4Id && kTRUE == fbMergedEpochsOn) {
            for (uint32_t uGet4Index = 0; uGet4Index < fuNrOfGet4PerGdpb; uGet4Index++) {
Administrator's avatar
Administrator committed
              fuGet4Id = uGet4Index;
              fuGet4Nr = (fuGdpbNr * fuNrOfGet4PerGdpb) + fuGet4Id;
              ngdpb::Message tmpMess(mess);
              tmpMess.setGdpbGenChipId(uGet4Index);
              //                     fHistGet4MessType->Fill(uGet4Index, ngdpb::GET4_32B_EPOCH);
              FillEpochInfo(tmpMess);
            }  // for( uint32_t uGet4Index = 0; uGet4Index < fuNrOfGet4PerGdpb; uGetIndex ++ )
          }    // if this epoch message is a merged one valiud for all chips
Administrator's avatar
Administrator committed
          else {
            //                  fHistGet4MessType->Fill( fuGet4Nr, ngdpb::GET4_32B_EPOCH );
            FillEpochInfo(mess);
          }  // if single chip epoch message
          break;
        }  // case ngdpb::MSG_EPOCH2:
        case ngdpb::MSG_GET4_32B: {
          if (fbEpochSuppModeOn) {
            fvmEpSupprBuffer[fuGet4Nr].push_back(mess);
            LOG(debug) << "Add 32B message from Gdpb " << fuGdpbNr << " to EpSupprBuffer of Get4 " << fuGet4Nr
                       << " size " << fvmEpSupprBuffer[fuGet4Nr].size();
          }
          else
Administrator's avatar
Administrator committed
            FillHitInfo(mess);
          break;

        }  // case ngdpb::MSG_GET4_32B:
        case ngdpb::MSG_GET4_SLC: {
          PrintSlcInfo(mess);
          break;
        }  // case ngdpb::MSG_GET4_SLC:
        case ngdpb::MSG_GET4_SYS: {
          if (100 > iMess++) PrintSysInfo(mess);
          break;
        }  // case ngdpb::MSG_GET4_SYS:
        case ngdpb::MSG_STAR_TRI: {
          FillStarTrigInfo(mess);
          break;
        }  // case ngdpb::MSG_STAR_TRI:
        default: {
          if (100 > iMess++)
            LOG(error) << "Message (" << iMess << ") type " << std::hex << std::setw(2)
                       << static_cast<uint16_t>(mess.getMessageType()) << " not included in Get4 unpacker.";
Administrator's avatar
Administrator committed
          if (100 == iMess) LOG(error) << "Stop reporting MSG errors... ";
        }  // default:
      }    // switch( mess.getMessageType() )

    }  // for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx ++)

  }  // for (size_t m = 0; m < numCompMsInTs; ++m)
Administrator's avatar
Administrator committed
  return kTRUE;
}
void CbmDeviceUnpackTofStar2018::FillHitInfo(ngdpb::Message mess)
{
Administrator's avatar
Administrator committed
  // --- Get absolute time, GET4 ID and channel number
  UInt_t uGet4Id  = mess.getGdpbGenChipId();
  UInt_t uChannel = mess.getGdpbHitChanId();
  UInt_t uTot     = mess.getGdpbHit32Tot();
  //   UInt_t uFts        = mess.getGdpbHitFineTs();
Administrator's avatar
Administrator committed
  ULong_t ulCurEpochGdpbGet4 = fvulCurrentEpoch[fuGet4Nr];
Administrator's avatar
Administrator committed
  if (kTRUE == fvbFirstEpochSeen[fuGet4Nr]) {
    // In Ep. Suppr. Mode, receive following epoch instead of previous
    if (0 < ulCurEpochGdpbGet4) ulCurEpochGdpbGet4--;
Administrator's avatar
Administrator committed
    else
      ulCurEpochGdpbGet4 = get4v1x::kuEpochCounterSz;  // Catch epoch cycle!
Administrator's avatar
Administrator committed
    //      ULong_t  ulhitTime;
    Double_t dHitTime;
    if (fbGet4v20) {
      //	ulhitTime = mess.getMsgG4v2FullTime(  ulCurEpochGdpbGet4 );
      dHitTime = mess.getMsgG4v2FullTimeD(ulCurEpochGdpbGet4);

      // In 32b mode the coarse counter is already computed back to 112 FTS bins
      // => need to hide its contribution from the Finetime
      // => FTS = Fullt TS modulo 112
Administrator's avatar
Administrator committed
      //	if( !fbGet4M24b )
      //	  uFts = mess.getGdpbHitFullTs() % 112;
    }  // if( fbGet4v20 )
    else {
      //         ulhitTime  = mess.getMsgFullTime(ulCurEpochGdpbGet4);
      dHitTime = mess.getMsgFullTimeD(ulCurEpochGdpbGet4);
    }  // else of if( fbGet4v20 )
Administrator's avatar
Administrator committed
    Double_t dHitTot = uTot;  // in bins
Administrator's avatar
Administrator committed
    //      UInt_t uFebIdx     = (uGet4Id / fuNrOfGet4PerFeb);
    //      UInt_t uFullFebIdx = (fuGdpbNr * fuNrOfFebsPerGdpb) + uFebIdx;
Administrator's avatar
Administrator committed
    UInt_t uChanInGdpb = uGet4Id * fuNrOfChannelsPerGet4 + uChannel;
    Int_t uChanInSyst  = fuGdpbNr * fuNrOfChannelsPerGdpb + uChanInGdpb;
    if (fUnpackPar->GetNumberOfChannels() < uChanInSyst) {
      LOG(error) << "Invalid mapping index " << uChanInSyst << " VS " << fUnpackPar->GetNumberOfChannels() << ", from "
                 << fuGdpbNr << ", " << uGet4Id << ", " << uChannel;
Administrator's avatar
Administrator committed
      return;
    }  // if( fUnpackPar->GetNumberOfChannels() < uChanUId )
Administrator's avatar
Administrator committed
    fvbChanThere[uChanInSyst] = kTRUE;
Administrator's avatar
Administrator committed
    UInt_t uChanUId = fUnpackPar->GetChannelToDetUIdMap(uChanInSyst);
    if (0 == uChanUId) return;  // Hit not mapped to digi
Administrator's avatar
Administrator committed
    /*
      if( (uChanUId & DetMask) == 0x00001006 )
      {
         UInt_t uDetChan = (uChanUId & 0xFF000000) >> 24;
         if( (uChanUId & 0x00800000) == 0x00800000 )
            uDetChan += 32;

         fbDetChanThere[ uDetChan ] = kTRUE;
      } // if( (uChanUId & DetMask) == 0x00001006 )
      */
Administrator's avatar
Administrator committed
    //      fhRawDigiLastDigi->Fill( dHitTime - fdLastDigiTime );
Administrator's avatar
Administrator committed
    if ((uChanUId & DetMask) != 0x00005006) dHitTime += fdTShiftRef;
    fdLastDigiTime = dHitTime;
    LOG(debug) << Form("Insert 0x%08x digi with time ", uChanUId) << dHitTime << Form(", Tot %4.0f", dHitTot)
               << " into buffer with " << fBuffer->GetSize() << " data from "
               << Form("%11.1f to %11.1f ", fBuffer->GetTimeFirst(), fBuffer->GetTimeLast()) << " at epoch "
               << ulCurEpochGdpbGet4;
Administrator's avatar
Administrator committed
    fDigi = new CbmTofDigiExp(uChanUId, dHitTime, dHitTot);
Administrator's avatar
Administrator committed
    fBuffer->InsertData<CbmTofDigiExp>(fDigi);
Administrator's avatar
Administrator committed
    // Histograms filling
    fhRawTotCh[fuGdpbNr]->Fill(uChanInGdpb, dHitTot);
    fhChCount[fuGdpbNr]->Fill(uChanInGdpb);
Administrator's avatar
Administrator committed
  }  // if( kTRUE == fvbFirstEpochSeen[ fuGet4Nr ] )
void CbmDeviceUnpackTofStar2018::FillEpochInfo(ngdpb::Message mess)
{
Administrator's avatar
Administrator committed
  ULong64_t ulEpochNr = mess.getGdpbEpEpochNb();
Administrator's avatar
Administrator committed
  //   LOG(debug) << "Get4Nr "<<fuGet4Nr<< " in epoch "<<ulEpochNr;
Administrator's avatar
Administrator committed
  fvulCurrentEpoch[fuGet4Nr] = ulEpochNr;
  if (kFALSE == fvbFirstEpochSeen[fuGet4Nr]) fvbFirstEpochSeen[fuGet4Nr] = kTRUE;
Administrator's avatar
Administrator committed
  fulCurrentEpochTime = mess.getMsgFullTime(ulEpochNr);
  fNofEpochs++;
Administrator's avatar
Administrator committed
  /// In Ep. Suppr. Mode, receive following epoch instead of previous
  /// Re-align the epoch number of the message in case it will be used later:
  /// We received the epoch after the data instead of the one before!
  if (0 < ulEpochNr) mess.setEpoch2Number(ulEpochNr - 1);
Administrator's avatar
Administrator committed
  else
    mess.setEpoch2Number(get4v1x::kuEpochCounterSz);
Administrator's avatar
Administrator committed
  Int_t iBufferSize = fvmEpSupprBuffer[fuGet4Nr].size();
  if (0 < iBufferSize) {
    LOG(debug) << "Now processing " << iBufferSize << " stored messages for get4 " << fuGet4Nr << " with epoch number "
               << (fvulCurrentEpoch[fuGet4Nr] - 1);
Administrator's avatar
Administrator committed
    for (Int_t iMsgIdx = 0; iMsgIdx < iBufferSize; iMsgIdx++) {
      FillHitInfo(fvmEpSupprBuffer[fuGet4Nr][iMsgIdx]);
    }  // for( Int_t iMsgIdx = 0; iMsgIdx < iBufferSize; iMsgIdx++ )
       /*
      for( UInt_t uLeftFeb = fuGdpbNr * fuNrOfFebsPerGdpb / 2;
           uLeftFeb < (fuGdpbNr + 1) * fuNrOfFebsPerGdpb / 2;
           ++uLeftFeb )
      {
         for( UInt_t uChanA = 2*uLeftFeb * fuNrOfChannelsPerFeet;
              uChanA < (2*uLeftFeb + 1) * fuNrOfChannelsPerFeet;
              ++uChanA )
         {
            if( kTRUE == fvbChanThere[ uChanA ] )
            {
               for( UInt_t uChanB = (2*uLeftFeb + 1) * fuNrOfChannelsPerFeet;
                    uChanB < (2*uLeftFeb + 2) * fuNrOfChannelsPerFeet;
                    ++uChanB )
               {
                  if( kTRUE == fvbChanThere[ uChanB ] )
                  {
                     fhChanCoinc[ uLeftFeb  ]->Fill( uChanA, uChanB );
                  }
               }
            }
         }
      } // for( UInt_t uLeftFeb = 0; uLeftFeb < fuNrOfFebsPerGdpb / 2; ++uLeftFeb )
*/
Administrator's avatar
Administrator committed
    fvmEpSupprBuffer[fuGet4Nr].clear();
  }  // if( 0 < fvmEpSupprBuffer[fGet4Nr] )
void CbmDeviceUnpackTofStar2018::PrintSlcInfo(ngdpb::Message /*mess*/)
{
Administrator's avatar
Administrator committed
  /// Nothing to do, maybe later use it to trakc parameter changes like treshold?
  /*
  if( fGdpbIdIndexMap.end() != fGdpbIdIndexMap.find( rocId ) )
     LOG(info) << "GET4 Slow Control message, epoch " << static_cast<Int_t>(fCurrentEpoch[rocId][get4Id])
                << ", time " << std::setprecision(9) << std::fixed
                << Double_t(fulCurrentEpochTime) * 1.e-9 << " s "
                << " for board ID " << std::hex << std::setw(4) << rocId << std::dec
                << " +++++++ > Chip = " << std::setw(2) << mess.getGdpbGenChipId()
                << ", Chan = " << std::setw(1) << mess.getGdpbSlcChan()
                << ", Edge = " << std::setw(1) << mess.getGdpbSlcEdge()
                << ", Type = " << std::setw(1) << mess.getGdpbSlcType()
                << ", Data = " << std::hex << std::setw(6) << mess.getGdpbSlcData() << std::dec
                << ", Type = " << mess.getGdpbSlcCrc();
*/
}

void CbmDeviceUnpackTofStar2018::PrintGenInfo(ngdpb::Message mess)
{
Administrator's avatar
Administrator committed
  Int_t mType    = mess.getMessageType();
  Int_t rocId    = mess.getRocNumber();
  Int_t get4Id   = mess.getGdpbGenChipId();
  Int_t channel  = mess.getGdpbHitChanId();
  uint64_t uData = mess.getData();
  if (100 > iMess++)
    LOG(info) << "Get4 MSG type " << mType << " from rocId " << rocId << ", getId " << get4Id << ", (hit channel) "
              << channel << Form(" hex data %0lx ", uData);
void CbmDeviceUnpackTofStar2018::PrintSysInfo(ngdpb::Message mess)
{
  LOG(info) << "GET4 System message,       epoch " << (fvulCurrentEpoch[fuGet4Nr]) << ", time " << std::setprecision(9)
Administrator's avatar
Administrator committed
            << std::fixed << Double_t(fulCurrentEpochTime) * 1.e-9 << " s "
            << " for board ID " << std::hex << std::setw(4) << fuGdpbId << std::dec;
Administrator's avatar
Administrator committed
  switch (mess.getGdpbSysSubType()) {
    case ngdpb::SYSMSG_GET4_EVENT: {
      LOG(info) << " +++++++ > Chip = " << std::setw(2) << mess.getGdpbGenChipId() << ", Chan = " << std::setw(1)
                << mess.getGdpbSysErrChanId() << ", Edge = " << std::setw(1) << mess.getGdpbSysErrEdge()
                << ", Empt = " << std::setw(1) << mess.getGdpbSysErrUnused() << ", Data = " << std::hex << std::setw(2)
                << mess.getGdpbSysErrData() << std::dec << " -- GET4 V1 Error Event";
Administrator's avatar
Administrator committed
      break;
    }  //
    case ngdpb::SYSMSG_CLOSYSYNC_ERROR: LOG(info) << "Closy synchronization error"; break;
    case ngdpb::SYSMSG_TS156_SYNC: LOG(info) << "156.25MHz timestamp reset"; break;
Administrator's avatar
Administrator committed
    case ngdpb::SYSMSG_GDPB_UNKWN:
      LOG(info) << "Unknown GET4 message, data: " << std::hex << std::setw(8) << mess.getGdpbSysUnkwData() << std::dec;
Administrator's avatar
Administrator committed
      break;
  }  // switch( getGdpbSysSubType() )
void CbmDeviceUnpackTofStar2018::FillStarTrigInfo(ngdpb::Message mess)
{
  Int_t iMsgIndex = mess.getStarTrigMsgIndex();

  //mess.printDataCout();

Administrator's avatar
Administrator committed
  switch (iMsgIndex) {
    case 0: fulGdpbTsMsb = mess.getGdpbTsMsbStarA(); break;
    case 1:
      fulGdpbTsLsb = mess.getGdpbTsLsbStarB();
      fulStarTsMsb = mess.getStarTsMsbStarB();
      break;
    case 2: fulStarTsMid = mess.getStarTsMidStarC(); break;
    case 3: {
      ULong64_t ulNewGdpbTsFull = (fulGdpbTsMsb << 24) + (fulGdpbTsLsb);
      ULong64_t ulNewStarTsFull = (fulStarTsMsb << 48) + (fulStarTsMid << 8) + mess.getStarTsLsbStarD();
      UInt_t uNewToken          = mess.getStarTokenStarD();
      UInt_t uNewDaqCmd         = mess.getStarDaqCmdStarD();
      UInt_t uNewTrigCmd        = mess.getStarTrigCmdStarD();
      if ((uNewToken == fuStarTokenLast) && (ulNewGdpbTsFull == fulGdpbTsFullLast)
          && (ulNewStarTsFull == fulStarTsFullLast) && (uNewDaqCmd == fuStarDaqCmdLast)
Administrator's avatar
Administrator committed
          && (uNewTrigCmd == fuStarTrigCmdLast)) {
        LOG(debug) << "Possible error: identical STAR tokens found twice in a "
                      "row => ignore 2nd! "
                   << Form("token = %5u ", fuStarTokenLast) << Form("gDPB ts  = %12llu ", fulGdpbTsFullLast)
                   << Form("STAR ts = %12llu ", fulStarTsFullLast) << Form("DAQ cmd = %2u ", fuStarDaqCmdLast)
Administrator's avatar
Administrator committed
                   << Form("TRG cmd = %2u ", fuStarTrigCmdLast);
        return;
      }  // if exactly same message repeated
         /*
         if( (uNewToken != fuStarTokenLast + 1) &&
             0 < fulGdpbTsFullLast && 0 < fulStarTsFullLast &&
             ( 4095 != fuStarTokenLast || 1 != uNewToken)  )
            LOG(warn) << "Possible error: STAR token did not increase by exactly 1! "
                         << Form("old = %5u vs new = %5u ", fuStarTokenLast,   uNewToken)
                         << Form("old = %12llu vs new = %12llu ", fulGdpbTsFullLast, ulNewGdpbTsFull)
                         << Form("old = %12llu vs new = %12llu ", fulStarTsFullLast, ulNewStarTsFull)
                         << Form("old = %2u vs new = %2u ", fuStarDaqCmdLast,  uNewDaqCmd)
                         << Form("old = %2u vs new = %2u ", fuStarTrigCmdLast, uNewTrigCmd);
*/
Administrator's avatar
Administrator committed
      fulGdpbTsFullLast = ulNewGdpbTsFull;
      fulStarTsFullLast = ulNewStarTsFull;
      fuStarTokenLast   = uNewToken;
      fuStarDaqCmdLast  = uNewDaqCmd;
      fuStarTrigCmdLast = uNewTrigCmd;

      Double_t dTot  = 1.;
      Double_t dTime = fulGdpbTsFullLast * 6.25;
      if (0. == fdFirstDigiTimeDif && 0. != fdLastDigiTime) {
        fdFirstDigiTimeDif = dTime - fdLastDigiTime;
        LOG(info) << "Reference fake digi time shift initialized to " << fdFirstDigiTimeDif
                  << ", default: " << fdTShiftRef;
Administrator's avatar
Administrator committed
      }  // if( 0. == fdFirstDigiTimeDif && 0. != fdLastDigiTime )

      //         dTime -= fdFirstDigiTimeDif;
      // dTime += fdTShiftRef;

      LOG(debug) << "Insert fake digi with time " << dTime << ", Tot " << dTot;
      fhRawTRefDig0->Fill(dTime - fdLastDigiTime);
      fhRawTRefDig1->Fill(dTime - fdLastDigiTime);

      fDigi = new CbmTofDigiExp(0x00005006, dTime, dTot);  // fake start counter signal
Administrator's avatar
Administrator committed
      fBuffer->InsertData<CbmTofDigiExp>(fDigi);
      break;
    }  // case 3
    default: LOG(error) << "Unknown Star Trigger messageindex: " << iMsgIndex;
  }  // switch( iMsgIndex )
Administrator's avatar
Administrator committed
CbmDeviceUnpackTofStar2018::~CbmDeviceUnpackTofStar2018() {}
void CbmDeviceUnpackTofStar2018::PrintMicroSliceDescriptor(const fles::MicrosliceDescriptor& mdsc)
{
  LOG(info) << "Header ID: Ox" << std::hex << static_cast<int>(mdsc.hdr_id) << std::dec;
  LOG(info) << "Header version: Ox" << std::hex << static_cast<int>(mdsc.hdr_ver) << std::dec;
  LOG(info) << "Equipement ID: " << mdsc.eq_id;
  LOG(info) << "Flags: " << mdsc.flags;
  LOG(info) << "Sys ID: Ox" << std::hex << static_cast<int>(mdsc.sys_id) << std::dec;
  LOG(info) << "Sys version: Ox" << std::hex << static_cast<int>(mdsc.sys_ver) << std::dec;
  LOG(info) << "Microslice Idx: " << mdsc.idx;
  LOG(info) << "Checksum: " << mdsc.crc;
  LOG(info) << "Size: " << mdsc.size;
  LOG(info) << "Offset: " << mdsc.offset;
}

bool CbmDeviceUnpackTofStar2018::CheckTimeslice(const fles::Timeslice& ts)
{
Administrator's avatar
Administrator committed
  if (0 == ts.num_components()) {
    LOG(error) << "No Component in TS " << ts.index();
    return 1;
  }
  LOG(info) << "Found " << ts.num_components() << " different components in timeslice";

  for (size_t c = 0; c < ts.num_components(); ++c) {
    LOG(info) << "Found " << ts.num_microslices(c) << " microslices in component " << c;
    LOG(info) << "Component " << c << " has a size of " << ts.size_component(c) << " bytes";
    LOG(info) << "Sys ID: Ox" << std::hex << static_cast<int>(ts.descriptor(0, 0).sys_id) << std::dec;
Administrator's avatar
Administrator committed
    /*
    for (size_t m = 0; m < ts.num_microslices(c); ++m) {
      PrintMicroSliceDescriptor(ts.descriptor(c,m));
    }
*/
  }

  return true;
}