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"
#include "TH1.h"
#include "TH2.h"
#include <boost/archive/binary_iarchive.hpp>
#include <iomanip>
#include <stdexcept>
struct InitTaskError : std::runtime_error {
using std::runtime_error::runtime_error;
};
static Int_t iMess = 0;
const Int_t DetMask = 0x0001FFFF;
CbmDeviceUnpackTofStar2018::CbmDeviceUnpackTofStar2018()
: fNumMessages(0)
, fuMsAcceptsPercent(100)
, fuOverlapMsNb(0)
, fuNrOfGdpbs(0)
, fuNrOfFebsPerGdpb(0)
, fuNrOfGet4PerFeb(0)
, fuNrOfChannelsPerGet4(0)
, fuNrOfChannelsPerFeet(0)
, fuNrOfGet4(0)
, fuNrOfGet4PerGdpb(0)
, fuNrOfChannelsPerGdpb(0)
, fMsgCounter(11, 0) // length of enum MessageTypes initialized with 0
, fGdpbIdIndexMap()
, fuGdpbId(0)
, fuGdpbNr(0)
, fuGet4Id(0)
, fuGet4Nr(0)
, fvulCurrentEpoch()
, fvbFirstEpochSeen()
, fNofEpochs(0)
, fulCurrentEpochTime(0.)
, fEquipmentId(0)
, fdMsIndex(0.)
, fdTShiftRef(0.)
, fbEpochSuppModeOn(kFALSE)
, fbGet4M24b(kFALSE)
, fbGet4v20(kFALSE)
, fbMergedEpochsOn(kFALSE)
, fDigi(nullptr)
, fUnpackPar(nullptr)
, fdRefTime(0.)
, fdLastDigiTime(0.)
, fdFirstDigiTimeDif(0.)
, fdEvTime0(0.)
, fhRawTDigRef0(nullptr)
, fhRawTDigRef(nullptr)
, fhRawTRefDig0(nullptr)
, fhRawTRefDig1(nullptr)
, fhRawDigiLastDigi(nullptr)
, fhRawTotCh()
, fhChCount()
, fvbChanThere()
, fhChanCoinc()
, fhDetChanCoinc(nullptr)
, fvmEpSupprBuffer()
, fBuffer(CbmTbDaqBuffer::Instance())
, fulGdpbTsMsb(0.)
, fulGdpbTsLsb(0.)
, fulStarTsMsb(0.)
, fulStarTsMid(0.)
, fulGdpbTsFullLast(0.)
, fulStarTsFullLast(0.)
, fuStarTokenLast(0)
, fuStarTrigCmdLast(0)
{
}
void CbmDeviceUnpackTofStar2018::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.
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.");
OnData(entry.first, &CbmDeviceUnpackTofStar2018::HandleData);
}
InitContainers();
}
catch (InitTaskError& e) {
bool CbmDeviceUnpackTofStar2018::IsChannelNameAllowed(std::string channelName)
{
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;
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.";
// 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
LOG(info) << "Requesting parameter container CbmTofUnpackPar, sending message: " << message;
FairMQMessagePtr req(NewSimpleMessage("CbmTofUnpackPar,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 = static_cast<CbmTofUnpackPar*>(tmsg.ReadObject(tmsg.GetClass()));
LOG(info) << "Received parameter from the server:";
fUnpackPar->print();
LOG(error) << "Received empty reply. Parameter not available";
}
Bool_t initOK = ReInitContainers();
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.";
fuNrOfGdpbs = fUnpackPar->GetNrOfRocs();
LOG(info) << "Nr. of Tof GDPBs: " << fuNrOfGdpbs;
fuMinNbGdpb = fuNrOfGdpbs;
fuNrOfFebsPerGdpb = fUnpackPar->GetNrOfFebsPerGdpb();
LOG(info) << "Nr. of FEBS per Tof GDPB: " << fuNrOfFebsPerGdpb;
fuNrOfGet4PerFeb = fUnpackPar->GetNrOfGet4PerFeb();
LOG(info) << "Nr. of GET4 per Tof FEB: " << fuNrOfGet4PerFeb;
fuNrOfChannelsPerGet4 = fUnpackPar->GetNrOfChannelsPerGet4();
LOG(info) << "Nr. of channels per GET4: " << fuNrOfChannelsPerGet4;
fuNrOfChannelsPerFeet = fuNrOfGet4PerFeb * fuNrOfChannelsPerGet4;
LOG(info) << "Nr. of channels per FEET: " << fuNrOfChannelsPerFeet;
fuNrOfGet4 = fuNrOfGdpbs * fuNrOfFebsPerGdpb * fuNrOfGet4PerFeb;
LOG(info) << "Nr. of GET4s: " << fuNrOfGet4;
fuNrOfGet4PerGdpb = fuNrOfFebsPerGdpb * fuNrOfGet4PerFeb;
LOG(info) << "Nr. of GET4s per GDPB: " << fuNrOfGet4PerGdpb;
fuNrOfChannelsPerGdpb = fuNrOfGet4PerGdpb * fuNrOfChannelsPerGet4;
LOG(info) << "Nr. of channels per GDPB: " << fuNrOfChannelsPerGdpb;
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;
UInt_t uNrOfChannels = fUnpackPar->GetNumberOfChannels();
LOG(info) << "Nr. of mapped Tof channels: " << uNrOfChannels;
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)
LOG(info) << "Plot Channel Rate => " << (fUnpackPar->IsChannelRateEnabled() ? "ON" : "OFF");
if (fbEpochSuppModeOn) fvmEpSupprBuffer.resize(fuNrOfGet4);
void CbmDeviceUnpackTofStar2018::CreateHistograms()
{
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);
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);
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);
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 * 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.);
// 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),
fuNrOfChannelsPerFeet, 0., fuNrOfChannelsPerFeet,
fuNrOfChannelsPerFeet, 0., fuNrOfChannelsPerFeet );
} // for( UInt_t uLeftFeb = 0; uLeftFeb < fuNrOfFebsPerGdpb / 2; uLeftFeb ++ )
*/
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 CbmDeviceUnpackTofStar2018::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(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);
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;
// 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));
if (0 < size) LOG(debug) << "Microslice " << m << ": " << fdMsIndex << " has size: " << size;
// 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;
// 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);
if(fair::Logger::Logging(fair::Severity::debug)
{
mess.printDataCout();
// 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";
continue;
}
switch (mess.getMessageType()) {
case ngdpb::MSG_HIT:
case ngdpb::MSG_EPOCH:
case ngdpb::MSG_GET4: {
if (fbGet4M24b) FillHitInfo(mess);
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++) {
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
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
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.";
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)
void CbmDeviceUnpackTofStar2018::FillHitInfo(ngdpb::Message mess)
{
// --- 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();
ULong_t ulCurEpochGdpbGet4 = fvulCurrentEpoch[fuGet4Nr];
if (kTRUE == fvbFirstEpochSeen[fuGet4Nr]) {
// In Ep. Suppr. Mode, receive following epoch instead of previous
if (0 < ulCurEpochGdpbGet4) ulCurEpochGdpbGet4--;
else
ulCurEpochGdpbGet4 = get4v1x::kuEpochCounterSz; // Catch epoch cycle!
// 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
// if( !fbGet4M24b )
// uFts = mess.getGdpbHitFullTs() % 112;
} // if( fbGet4v20 )
else {
// ulhitTime = mess.getMsgFullTime(ulCurEpochGdpbGet4);
dHitTime = mess.getMsgFullTimeD(ulCurEpochGdpbGet4);
} // else of if( fbGet4v20 )
// UInt_t uFebIdx = (uGet4Id / fuNrOfGet4PerFeb);
// UInt_t uFullFebIdx = (fuGdpbNr * fuNrOfFebsPerGdpb) + uFebIdx;
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;
return;
} // if( fUnpackPar->GetNumberOfChannels() < uChanUId )
UInt_t uChanUId = fUnpackPar->GetChannelToDetUIdMap(uChanInSyst);
if (0 == uChanUId) return; // Hit not mapped to digi
if( (uChanUId & DetMask) == 0x00001006 )
{
UInt_t uDetChan = (uChanUId & 0xFF000000) >> 24;
if( (uChanUId & 0x00800000) == 0x00800000 )
uDetChan += 32;
fbDetChanThere[ uDetChan ] = kTRUE;
} // if( (uChanUId & DetMask) == 0x00001006 )
*/
// fhRawDigiLastDigi->Fill( dHitTime - fdLastDigiTime );
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;
// Histograms filling
fhRawTotCh[fuGdpbNr]->Fill(uChanInGdpb, dHitTot);
fhChCount[fuGdpbNr]->Fill(uChanInGdpb);
void CbmDeviceUnpackTofStar2018::FillEpochInfo(ngdpb::Message mess)
{
// LOG(debug) << "Get4Nr "<<fuGet4Nr<< " in epoch "<<ulEpochNr;
if (kFALSE == fvbFirstEpochSeen[fuGet4Nr]) fvbFirstEpochSeen[fuGet4Nr] = kTRUE;
fulCurrentEpochTime = mess.getMsgFullTime(ulEpochNr);
fNofEpochs++;
/// 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);
else
mess.setEpoch2Number(get4v1x::kuEpochCounterSz);
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);
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 )
*/
fvmEpSupprBuffer[fuGet4Nr].clear();
} // if( 0 < fvmEpSupprBuffer[fGet4Nr] )
void CbmDeviceUnpackTofStar2018::PrintSlcInfo(ngdpb::Message /*mess*/)
{
/// 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)
{
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)
<< std::fixed << Double_t(fulCurrentEpochTime) * 1.e-9 << " s "
<< " for board ID " << std::hex << std::setw(4) << fuGdpbId << std::dec;
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";
case ngdpb::SYSMSG_CLOSYSYNC_ERROR: LOG(info) << "Closy synchronization error"; break;
case ngdpb::SYSMSG_TS156_SYNC: LOG(info) << "156.25MHz timestamp reset"; break;
LOG(info) << "Unknown GET4 message, data: " << std::hex << std::setw(8) << mess.getGdpbSysUnkwData() << std::dec;
void CbmDeviceUnpackTofStar2018::FillStarTrigInfo(ngdpb::Message mess)
{
Int_t iMsgIndex = mess.getStarTrigMsgIndex();
//mess.printDataCout();
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)
&& (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)
<< 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);
*/
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;
} // 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
fBuffer->InsertData<CbmTofDigiExp>(fDigi);
break;
} // case 3
default: LOG(error) << "Unknown Star Trigger messageindex: " << iMsgIndex;
} // switch( iMsgIndex )
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)
{
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;
for (size_t m = 0; m < ts.num_microslices(c); ++m) {
PrintMicroSliceDescriptor(ts.descriptor(c,m));
}
*/
}
return true;
}