From b24d66b11fbb6f96d25fcf2d0d1489923e1091d2 Mon Sep 17 00:00:00 2001 From: P-A Loizeau <p.-a.loizeau@gsi.de> Date: Mon, 19 Jul 2021 22:34:23 +0200 Subject: [PATCH] Add TOF CRI unpacker in new scheme. Include temp fix for strange epoch offset. Changed severity for large amount of LOG statements Changed default from info to debug for a larger amount of tof log messages. Otherwise, it makes info reading with all subsystems almost impossible. --- core/data/CbmTsEventHeader.h | 5 + core/data/raw/CriGet4Mess001.cxx | 16 +- core/data/raw/CriGet4Mess001.h | 10 +- core/detectors/tof/CbmMcbm2018TofPar.cxx | 62 ++- core/detectors/tof/CbmMcbm2018TofPar.h | 28 +- fles/mcbm2018/unpacker/CbmCriGet4RawPrint.cxx | 141 +++--- macro/beamtime/mcbm2021/.gitignore | 1 + macro/beamtime/mcbm2021/check_timing_any.C | 137 ++++++ macro/beamtime/mcbm2021/mTofCriPar.par | 35 ++ macro/run/run_unpack_tsa.C | 17 +- .../detectors/sts/unpack/CbmStsUnpackAlgo.cxx | 1 - reco/detectors/tof/CMakeLists.txt | 28 +- reco/detectors/tof/CbmTofRecoLinkDef.h | 3 + .../detectors/tof/unpack/CbmTofUnpackAlgo.cxx | 403 ++++++++++++++++++ reco/detectors/tof/unpack/CbmTofUnpackAlgo.h | 191 +++++++++ .../tof/unpack/CbmTofUnpackConfig.cxx | 67 +++ .../detectors/tof/unpack/CbmTofUnpackConfig.h | 90 ++++ reco/steer/CMakeLists.txt | 4 +- reco/steer/CbmRecoUnpack.cxx | 12 +- reco/steer/CbmRecoUnpack.h | 20 +- 20 files changed, 1112 insertions(+), 159 deletions(-) create mode 100644 macro/beamtime/mcbm2021/check_timing_any.C create mode 100644 macro/beamtime/mcbm2021/mTofCriPar.par create mode 100644 reco/detectors/tof/unpack/CbmTofUnpackAlgo.cxx create mode 100644 reco/detectors/tof/unpack/CbmTofUnpackAlgo.h create mode 100644 reco/detectors/tof/unpack/CbmTofUnpackConfig.cxx create mode 100644 reco/detectors/tof/unpack/CbmTofUnpackConfig.h diff --git a/core/data/CbmTsEventHeader.h b/core/data/CbmTsEventHeader.h index dbc8a2b456..70bed2b20b 100644 --- a/core/data/CbmTsEventHeader.h +++ b/core/data/CbmTsEventHeader.h @@ -34,6 +34,8 @@ public: ULong64_t GetNDigisTrd(ULong64_t) { return fNDigisTrd; } /** @brief Get the number of digis in this Ts */ ULong64_t GetNDigisTrd2D(ULong64_t) { return fNDigisTrd2D; } + /** @brief Get the number of digis in this Ts */ + ULong64_t GetNDigisTof(ULong64_t) { return fNDigisTof; } /** @brief Set the Ts Start Time @param value Start time of the TS */ void SetTsStartTime(uint64_t value) { fTsStartTime = value; } @@ -48,6 +50,8 @@ public: void SetNDigisTrd(ULong64_t value) { fNDigisTrd = value; } /** @brief Set the number of digis in this Ts */ void SetNDigisTrd2D(ULong64_t value) { fNDigisTrd2D = value; } + /** @brief Set the number of digis in this Ts */ + void SetNDigisTof(ULong64_t value) { fNDigisTof = value; } protected: @@ -59,6 +63,7 @@ protected: ULong64_t fNDigisSts = 0; ULong64_t fNDigisTrd = 0; ULong64_t fNDigisTrd2D = 0; + ULong64_t fNDigisTof = 0; ClassDef(CbmTsEventHeader, 3) diff --git a/core/data/raw/CriGet4Mess001.cxx b/core/data/raw/CriGet4Mess001.cxx index 4728a47069..562462c4dc 100644 --- a/core/data/raw/CriGet4Mess001.cxx +++ b/core/data/raw/CriGet4Mess001.cxx @@ -166,7 +166,10 @@ void critof001::Message::printDataCout(unsigned kind, uint32_t epoch) const { pr * documentation. */ -void critof001::Message::printDataLog(unsigned kind, uint32_t epoch) const { printData(msg_print_FairLog, kind, epoch); } +void critof001::Message::printDataLog(unsigned kind, uint32_t epoch) const +{ + printData(msg_print_FairLog, kind, epoch); +} //---------------------------------------------------------------------------- //! Print message in binary or human readable format to a stream. @@ -207,9 +210,8 @@ void critof001::Message::printData(unsigned outType, unsigned kind, uint32_t epo arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7], arr[7], arr[6], arr[5], arr[4], arr[3], arr[2], arr[1], arr[0]); */ - snprintf(buf, sizeof(buf), - "LE= %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X ", - arr[7], arr[6], arr[5], arr[4], arr[3], arr[2], arr[1], arr[0]); + snprintf(buf, sizeof(buf), "LE= %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X ", arr[7], arr[6], arr[5], arr[4], arr[3], + arr[2], arr[1], arr[0]); if (msg_print_Cout == outType) std::cout << buf; @@ -234,8 +236,8 @@ void critof001::Message::printData(unsigned outType, unsigned kind, uint32_t epo snprintf(buf, sizeof(buf), "EPOCH @%17.11f Get4:%2d Epoche2:%10u 0x%08x Sync:%x " "Dataloss:%x Epochloss:%x Epochmissmatch:%x", - timeInSec, getGet4Idx(), getGdpbEpEpochNb(), getGdpbEpEpochNb(), getGdpbEpSync(), - getGdpbEpDataLoss(), getGdpbEpEpochLoss(), getGdpbEpMissmatch()); + timeInSec, getGet4Idx(), getGdpbEpEpochNb(), getGdpbEpEpochNb(), getGdpbEpSync(), getGdpbEpDataLoss(), + getGdpbEpEpochLoss(), getGdpbEpMissmatch()); if (msg_print_Cout == outType) std::cout << buf << std::endl; else if (msg_print_File == outType) @@ -275,7 +277,7 @@ void critof001::Message::printData(unsigned outType, unsigned kind, uint32_t epo if (kind & msg_print_Data) { // const uint8_t* arr = reinterpret_cast<const uint8_t*> ( &data ); switch (getMessageType()) { -/* + /* case MSG_HIT: { snprintf(buf, sizeof(buf), "Get4 32 bits, Get4:%3d Channel %1d Ts:0x%03x Ft:0x%02x " diff --git a/core/data/raw/CriGet4Mess001.h b/core/data/raw/CriGet4Mess001.h index aea57694a0..69ede4b8f5 100644 --- a/core/data/raw/CriGet4Mess001.h +++ b/core/data/raw/CriGet4Mess001.h @@ -39,7 +39,7 @@ namespace critof001 // alternatively: (kiCoarseTime>>kiCtShift + 1)*kdClockCycleSize const double kdEpochInPs = static_cast<double>(kuCoarseCounterSize) * kdClockCycleSize; const double kdEpochInNs = kdEpochInPs / 1000.0; - const double kuEpochInNs = static_cast<uint64_t>(kdEpochInNs); /// Works as epoch integer in ns! + const double kuEpochInNs = static_cast<uint64_t>(kdEpochInNs); /// Works as epoch integer in ns! // Epoch counter size in epoch const uint32_t kuEpochCounterSz = 0xFFFFFF; @@ -65,10 +65,10 @@ namespace critof001 enum MessageTypes { - MSG_HIT = 0, - MSG_EPOCH = 1, - MSG_SLOWC = 2, - MSG_SYST = 3 + MSG_HIT = 0, + MSG_EPOCH = 1, + MSG_SLOWC = 2, + MSG_SYST = 3 }; enum SysMessageTypes diff --git a/core/detectors/tof/CbmMcbm2018TofPar.cxx b/core/detectors/tof/CbmMcbm2018TofPar.cxx index 145ab9684d..371274b81a 100644 --- a/core/detectors/tof/CbmMcbm2018TofPar.cxx +++ b/core/detectors/tof/CbmMcbm2018TofPar.cxx @@ -9,6 +9,9 @@ #include "CbmMcbm2018TofPar.h" +#include "CbmTofAddress.h" +#include "CbmTofDetectorId_v14a.h" // in cbmdata/tof + #include "FairDetParIo.h" #include "FairParIo.h" #include "FairParamList.h" @@ -17,8 +20,6 @@ #include "TString.h" #include "gDpbMessv100.h" -#include "CbmTofAddress.h" -#include "CbmTofDetectorId_v14a.h" // in cbmdata/tof // ----- Standard constructor ------------------------------------------ CbmMcbm2018TofPar::CbmMcbm2018TofPar(const char* name, const char* title, const char* context) @@ -205,8 +206,8 @@ Double_t CbmMcbm2018TofPar::GetPadiThresholdVal(UInt_t uCode) // ------------------------------------------------------------------------- void CbmMcbm2018TofPar::BuildChannelsUidMap() { - UInt_t uNrOfGbtx = fiNrOfGbtx; - UInt_t uNrOfGet4 = fiNrOfGdpb * fiNrOfFeesPerGdpb * fiNrOfGet4PerFee; + UInt_t uNrOfGbtx = fiNrOfGbtx; + UInt_t uNrOfGet4 = fiNrOfGdpb * fiNrOfFeesPerGdpb * fiNrOfGet4PerFee; UInt_t uNrOfChannels = uNrOfGet4 * fiNrOfChannelsPerGet4; fviRpcChUId.resize(uNrOfChannels); @@ -258,18 +259,17 @@ void CbmMcbm2018TofPar::BuildChannelsUidMap() default: { LOG(error) << "Invalid Tof Type specifier "; } - } // switch (fiRpcType[uGbtx]) - } // for (UInt_t uGbtx = 0; uGbtx < uNrOfGbtx; ++uGbtx) - + } // switch (fiRpcType[uGbtx]) + } // for (UInt_t uGbtx = 0; uGbtx < uNrOfGbtx; ++uGbtx) } // ------------------------------------------------------------------------- -void CbmMcbm2018TofPar::BuildChannelsUidMapCbm(UInt_t & uCh, UInt_t uGbtx) +void CbmMcbm2018TofPar::BuildChannelsUidMapCbm(UInt_t& uCh, UInt_t uGbtx) { if (fiRpcSide[uGbtx] < 2) { // mTof modules LOG(info) << " Map mTof box " << fiModuleId[uGbtx] << " at GBTX - uCh = " << uCh; const Int_t RpcMap[5] = {4, 2, 0, 3, 1}; for (Int_t iRpc = 0; iRpc < fiNrOfRpc[uGbtx]; iRpc++) { - Int_t iStrMax = 32; + Int_t iStrMax = 32; UInt_t uChNext = 1; for (Int_t iStr = 0; iStr < iStrMax; iStr++) { @@ -278,18 +278,18 @@ void CbmMcbm2018TofPar::BuildChannelsUidMapCbm(UInt_t & uCh, UInt_t uGbtx) if (fiRpcSide[uGbtx] == 0) iStrMap = 31 - iStr; if (fiModuleId[uGbtx] > -1) - fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(fiModuleId[uGbtx], iRpcMap, iStrMap, - fiRpcSide[uGbtx], fiRpcType[uGbtx]); + fviRpcChUId[uCh] = + CbmTofAddress::GetUniqueAddress(fiModuleId[uGbtx], iRpcMap, iStrMap, fiRpcSide[uGbtx], fiRpcType[uGbtx]); else fviRpcChUId[uCh] = 0; // LOG(debug)<<Form("Map Ch %d to Address 0x%08x",uCh,fviRpcChUId[uCh]); uCh += uChNext; - } // for (Int_t iStr = 0; iStr < iStrMax; iStr++) - } // for (Int_t iRpc = 0; iRpc < fiNrOfRpc[uGbtx]; iRpc++) - } // if (fiRpcSide[uGbtx] < 2) + } // for (Int_t iStr = 0; iStr < iStrMax; iStr++) + } // for (Int_t iRpc = 0; iRpc < fiNrOfRpc[uGbtx]; iRpc++) + } // if (fiRpcSide[uGbtx] < 2) } // ------------------------------------------------------------------------- -void CbmMcbm2018TofPar::BuildChannelsUidMapStar(UInt_t & uCh, UInt_t uGbtx) +void CbmMcbm2018TofPar::BuildChannelsUidMapStar(UInt_t& uCh, UInt_t uGbtx) { if (fiRpcSide[uGbtx] < 2) { // mTof modules @@ -305,8 +305,8 @@ void CbmMcbm2018TofPar::BuildChannelsUidMapStar(UInt_t & uCh, UInt_t uGbtx) if (fiRpcSide[uGbtx] == 0) iStrMap = 31 - iStr; if (fiModuleId[uGbtx] > -1) - fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(fiModuleId[uGbtx], iRpcMap, iStrMap, - fiRpcSide[uGbtx], fiRpcType[uGbtx]); + fviRpcChUId[uCh] = + CbmTofAddress::GetUniqueAddress(fiModuleId[uGbtx], iRpcMap, iStrMap, fiRpcSide[uGbtx], fiRpcType[uGbtx]); else fviRpcChUId[uCh] = 0; // LOG(DEBUG)<<Form("Map Ch %d to Address 0x%08x",uCh,fviRpcChUId[uCh]); @@ -317,7 +317,7 @@ void CbmMcbm2018TofPar::BuildChannelsUidMapStar(UInt_t & uCh, UInt_t uGbtx) uCh += 64; } // ------------------------------------------------------------------------- -void CbmMcbm2018TofPar::BuildChannelsUidMapT0(UInt_t & uCh, UInt_t uGbtx) +void CbmMcbm2018TofPar::BuildChannelsUidMapT0(UInt_t& uCh, UInt_t uGbtx) { LOG(info) << " Map diamond at GBTX - uCh = " << uCh; for (UInt_t uFee = 0; uFee < kuNbFeePerGbtx; ++uFee) { @@ -333,8 +333,7 @@ void CbmMcbm2018TofPar::BuildChannelsUidMapT0(UInt_t & uCh, UInt_t uGbtx) /// => 1 T0 channel per GET4 /// => 1-2 eLinks per GET4 => GET4 ID = GET4 * 2 (+ 1) UInt_t uChannelT0 = uFeeCh / 8 + 4 * fiRpcSide[uGbtx]; - fviRpcChUId[uCh] = - CbmTofAddress::GetUniqueAddress(fiModuleId[uGbtx], 0, uChannelT0, 0, fiRpcType[uGbtx]); + fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(fiModuleId[uGbtx], 0, uChannelT0, 0, fiRpcType[uGbtx]); LOG(info) << Form("T0 channel: %u from GBTx %2u Fee %2u " "Channel %2u, indx %d address %08x", uChannelT0, uGbtx, uFeeCh, uCh, uCh, fviRpcChUId[uCh]); @@ -351,7 +350,7 @@ void CbmMcbm2018TofPar::BuildChannelsUidMapT0(UInt_t & uCh, UInt_t uGbtx) } // for( UInt_t uFee = 0; uFee < kuNbChannelsPerFee; ++uFee ) } // ------------------------------------------------------------------------- -void CbmMcbm2018TofPar::BuildChannelsUidMapCern(UInt_t & uCh, UInt_t /*uGbtx*/) +void CbmMcbm2018TofPar::BuildChannelsUidMapCern(UInt_t& uCh, UInt_t /*uGbtx*/) { LOG(info) << " Map CERN 20 gap at GBTX - uCh = " << uCh; // clang-format off @@ -376,7 +375,7 @@ void CbmMcbm2018TofPar::BuildChannelsUidMapCern(UInt_t & uCh, UInt_t /*uGbtx*/) LOG(info) << " Map end CERN 20 gap at GBTX - uCh = " << uCh; } // ------------------------------------------------------------------------- -void CbmMcbm2018TofPar::BuildChannelsUidMapCera(UInt_t & uCh, UInt_t /*uGbtx*/) +void CbmMcbm2018TofPar::BuildChannelsUidMapCera(UInt_t& uCh, UInt_t /*uGbtx*/) { Int_t iModuleId = 0; Int_t iModuleType = 8; @@ -388,7 +387,7 @@ void CbmMcbm2018TofPar::BuildChannelsUidMapCera(UInt_t & uCh, UInt_t /*uGbtx*/) LOG(info) << " Map end ceramics box at GBTX - uCh = " << uCh; } // ------------------------------------------------------------------------- -void CbmMcbm2018TofPar::BuildChannelsUidMapStar2(UInt_t & uCh, UInt_t uGbtx) +void CbmMcbm2018TofPar::BuildChannelsUidMapStar2(UInt_t& uCh, UInt_t uGbtx) { LOG(info) << " Map Star2 box " << fiModuleId[uGbtx] << " at GBTX - uCh = " << uCh; const Int_t iRpc[5] = {1, -1, 1, 0, 0}; @@ -429,11 +428,11 @@ void CbmMcbm2018TofPar::BuildChannelsUidMapStar2(UInt_t & uCh, UInt_t uGbtx) } } // ------------------------------------------------------------------------- -void CbmMcbm2018TofPar::BuildChannelsUidMapBuc(UInt_t & uCh, UInt_t uGbtx) +void CbmMcbm2018TofPar::BuildChannelsUidMapBuc(UInt_t& uCh, UInt_t uGbtx) { LOG(info) << " Map Buc box at GBTX - uCh = " << uCh; - Int_t iModuleIdMap = fiModuleId[uGbtx]; + Int_t iModuleIdMap = fiModuleId[uGbtx]; 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++) { @@ -517,20 +516,19 @@ void CbmMcbm2018TofPar::BuildChannelsUidMapBuc(UInt_t & uCh, UInt_t uGbtx) } iModuleIdMap = fiModuleId[uGbtx]; LOG(info) << "Buc of GBTX " << uGbtx << " Ch " << uCh - << Form(", Feet %1d, Str %2d, Ind %3d, i %3d, FeetInd %1d, Rpc %1d, Side %1d, Str %2d ", - iFeet, iStr, iInd, i, iFeetInd, iRpcMap, iSideMap, iStrMap); + << Form(", Feet %1d, Str %2d, Ind %3d, i %3d, FeetInd %1d, Rpc %1d, Side %1d, Str %2d ", iFeet, + iStr, iInd, i, iFeetInd, iRpcMap, iSideMap, iStrMap); } break; default:; - } // switch (fiRpcSide[uGbtx]) + } // switch (fiRpcSide[uGbtx]) if (iSideMap > -1) - fviRpcChUId[uCh] = - CbmTofAddress::GetUniqueAddress(iModuleIdMap, iRpcMap, iStrMap, iSideMap, fiRpcType[uGbtx]); + fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(iModuleIdMap, iRpcMap, iStrMap, iSideMap, fiRpcType[uGbtx]); else fviRpcChUId[uCh] = 0; uCh++; - } // for (Int_t iStr = 0; iStr < 32; iStr++) - } // for (Int_t iFeet = 0; iFeet < 5; iFeet++) + } // for (Int_t iStr = 0; iStr < 32; iStr++) + } // for (Int_t iFeet = 0; iFeet < 5; iFeet++) } // ------------------------------------------------------------------------- diff --git a/core/detectors/tof/CbmMcbm2018TofPar.h b/core/detectors/tof/CbmMcbm2018TofPar.h index 6657d5224c..e134514187 100644 --- a/core/detectors/tof/CbmMcbm2018TofPar.h +++ b/core/detectors/tof/CbmMcbm2018TofPar.h @@ -72,7 +72,7 @@ public: inline Int_t GetRpcType(Int_t i) { return fiRpcType[i]; } inline Int_t GetRpcSide(Int_t i) { return fiRpcSide[i]; } inline Int_t GetModuleId(Int_t i) { return fiModuleId[i]; } - inline std::vector< Int_t > GetRpcChUidMap() { return fviRpcChUId; } + inline std::vector<Int_t> GetRpcChUidMap() { return fviRpcChUId; } inline Int_t GetNbMsTot() { return fiNbMsTot; } inline Int_t GetNbMsOverlap() { return fiNbMsOverlap; } @@ -85,13 +85,13 @@ public: private: void BuildChannelsUidMap(); - void BuildChannelsUidMapCbm(UInt_t & uCh, UInt_t uGbtx); - void BuildChannelsUidMapStar(UInt_t & uCh, UInt_t uGbtx); - void BuildChannelsUidMapT0(UInt_t & uCh, UInt_t uGbtx); - void BuildChannelsUidMapCern(UInt_t & uCh, UInt_t uGbtx); - void BuildChannelsUidMapCera(UInt_t & uCh, UInt_t uGbtx); - void BuildChannelsUidMapStar2(UInt_t & uCh, UInt_t uGbtx); - void BuildChannelsUidMapBuc(UInt_t & uCh, UInt_t uGbtx); + void BuildChannelsUidMapCbm(UInt_t& uCh, UInt_t uGbtx); + void BuildChannelsUidMapStar(UInt_t& uCh, UInt_t uGbtx); + void BuildChannelsUidMapT0(UInt_t& uCh, UInt_t uGbtx); + void BuildChannelsUidMapCern(UInt_t& uCh, UInt_t uGbtx); + void BuildChannelsUidMapCera(UInt_t& uCh, UInt_t uGbtx); + void BuildChannelsUidMapStar2(UInt_t& uCh, UInt_t uGbtx); + void BuildChannelsUidMapBuc(UInt_t& uCh, UInt_t uGbtx); /// Constants /// Data format @@ -146,12 +146,12 @@ private: Int_t fiNrOfGet4PerFee; // Number of GET4 chips which are connected to one FEB Int_t fiNrOfChannelsPerGet4; // Number of channels per GET4 - Int_t fiNrOfGbtx; // Total number of Gbtx links - Int_t fiNrOfModule; // Total number of Modules - TArrayI fiNrOfRpc; // number of Rpcs connected to Gbtx link, i.e. 3 or 5 - TArrayI fiRpcType; // type of Rpcs connected to Gbtx link - TArrayI fiRpcSide; // side of Rpcs connected to Gbtx link, i.e. 0 or 1 - TArrayI fiModuleId; // Module Identifier connected to Gbtx link, has to match geometry + Int_t fiNrOfGbtx; // Total number of Gbtx links + Int_t fiNrOfModule; // Total number of Modules + TArrayI fiNrOfRpc; // number of Rpcs connected to Gbtx link, i.e. 3 or 5 + TArrayI fiRpcType; // type of Rpcs connected to Gbtx link + TArrayI fiRpcSide; // side of Rpcs connected to Gbtx link, i.e. 0 or 1 + TArrayI fiModuleId; // Module Identifier connected to Gbtx link, has to match geometry std::vector<Int_t> fviRpcChUId = {}; // UID/address for each channel, build from type, side and module Int_t fiNbMsTot; // Total number of MS per link in TS diff --git a/fles/mcbm2018/unpacker/CbmCriGet4RawPrint.cxx b/fles/mcbm2018/unpacker/CbmCriGet4RawPrint.cxx index bd8f30be67..fd0713209b 100644 --- a/fles/mcbm2018/unpacker/CbmCriGet4RawPrint.cxx +++ b/fles/mcbm2018/unpacker/CbmCriGet4RawPrint.cxx @@ -44,10 +44,7 @@ Bool_t CbmCriGet4RawPrint::Init() return kTRUE; } -void CbmCriGet4RawPrint::SetParContainers() -{ - LOG(info) << "Setting parameter containers for " << GetName(); -} +void CbmCriGet4RawPrint::SetParContainers() { LOG(info) << "Setting parameter containers for " << GetName(); } Bool_t CbmCriGet4RawPrint::InitContainers() { @@ -80,7 +77,7 @@ Bool_t CbmCriGet4RawPrint::DoUnpack(const fles::Timeslice& ts, size_t /*componen { static const uint8_t NGET4 = 80; - static const uint8_t NERROR = 0x16; + // static const uint8_t NERROR = 0x16; char buf[256]; @@ -88,11 +85,11 @@ Bool_t CbmCriGet4RawPrint::DoUnpack(const fles::Timeslice& ts, size_t /*componen uint32_t nGet4, epoch, msgType, errorCode; static int32_t pEpochDiff[NGET4]; int32_t epochDiff; - static uint32_t pErrorCnt[NGET4]={ 0 }; - static uint32_t pHitsCnt[NGET4]={ 0 }; - static uint32_t pTotCnt[NGET4]={ 0 }; + // static uint32_t pErrorCnt[NGET4] = {0}; + // static uint32_t pHitsCnt[NGET4] = {0}; + // static uint32_t pTotCnt[NGET4] = {0}; - static uint32_t pErrorCntMatrix[NGET4][NERROR]; + // static uint32_t pErrorCntMatrix[NGET4][NERROR]; static uint32_t procEpochUntilError = 0; @@ -162,74 +159,66 @@ Bool_t CbmCriGet4RawPrint::DoUnpack(const fles::Timeslice& ts, size_t /*componen //mess.printDataCout( critof001::msg_print_Hex | critof001::msg_print_Prefix | critof001::msg_print_Data ); msgType = ulData & 0xF; - nGet4 = (ulData>>40) & 0xFF; - epoch = (ulData>>8) & 0xFFFFFF; - epoch &= 0xFFFFFF; - errorCode = (ulData>>4) & 0x7F; - /*snprintf(buf, sizeof(buf), + nGet4 = (ulData >> 40) & 0xFF; + epoch = (ulData >> 8) & 0xFFFFFF; + epoch &= 0xFFFFFF; + errorCode = (ulData >> 4) & 0x7F; + /*snprintf(buf, sizeof(buf), "Data: 0x%016lx - %d - 0x06%X ", ulData, nGet4, epoch); std::cout << buf << std::endl; */ - //if (fuCurrentEquipmentId == 0xabc0) - { - //------------------- TLAST ----------------------------// - if ((ulData & 0xFFFFFFFFFFFF)==0xdeadbeeeeeef) - { - } - //------------------- EPOCH ----------------------------// - else if (msgType == 0x01) - { - if (nGet4 == 0xFF) { - - procEpochUntilError++; - if (lastGlobalEpoch!=0xFFFFFF){ - if ((lastGlobalEpoch + 1) != epoch){ - snprintf(buf, sizeof(buf), - "Error global epoch, last epoch, current epoch, diff 0x%06x 0x%06x %d 0x%016lx %d", - lastGlobalEpoch, epoch, lastGlobalEpoch - epoch, ulData, procEpochUntilError); - - std::cout << buf << std::endl; - procEpochUntilError=0; - } - } - else{ - snprintf(buf, sizeof(buf), - "Global epoch overflow, last epoch, current epoch 0x%06x 0x%06x", - lastGlobalEpoch, epoch); - - std::cout << buf << std::endl; - } - - - lastGlobalEpoch = epoch; - snprintf(buf, sizeof(buf),"Global epoch %d",epoch); - std::cout << Form("%5d/%5d ", uIdx, uNbMessages) << buf << std::endl; - - - } - else if (nGet4 <= 120){ - - if (lastGlobalEpoch > epoch) - epochDiff = lastGlobalEpoch - epoch; - else - epochDiff = 0xFFFFFF + lastGlobalEpoch - epoch; - - if (epochDiff != pEpochDiff[nGet4]){ - snprintf(buf, sizeof(buf), - "eTime %d - Error epoch drift Get4 %3d , last epoch diff, current epoch diff 0x%06x 0x%06x %d", - lastGlobalEpoch, nGet4, pEpochDiff[nGet4], epochDiff, pEpochDiff[nGet4]-epochDiff); - std::cout << buf << std::endl; - mess.printDataCout( critof001::msg_print_Hex | critof001::msg_print_Prefix | critof001::msg_print_Data ); - - } - pEpochDiff[nGet4] = epochDiff; - - } - } - /* + //if (fuCurrentEquipmentId == 0xabc0) + { + //------------------- TLAST ----------------------------// + if ((ulData & 0xFFFFFFFFFFFF) == 0xdeadbeeeeeef) {} + //------------------- EPOCH ----------------------------// + else if (msgType == 0x01) { + if (nGet4 == 0xFF) { + + procEpochUntilError++; + if (lastGlobalEpoch != 0xFFFFFF) { + if ((lastGlobalEpoch + 1) != epoch) { + snprintf(buf, sizeof(buf), + "Error global epoch, last epoch, current epoch, diff 0x%06x 0x%06x %d 0x%016lx %d", + lastGlobalEpoch, epoch, lastGlobalEpoch - epoch, ulData, procEpochUntilError); + + std::cout << buf << std::endl; + procEpochUntilError = 0; + } + } + else { + snprintf(buf, sizeof(buf), "Global epoch overflow, last epoch, current epoch 0x%06x 0x%06x", + lastGlobalEpoch, epoch); + + std::cout << buf << std::endl; + } + + + lastGlobalEpoch = epoch; + snprintf(buf, sizeof(buf), "Global epoch %d", epoch); + std::cout << Form("%5d/%5d ", uIdx, uNbMessages) << buf << std::endl; + } + else if (nGet4 <= 120) { + + if (lastGlobalEpoch > epoch) epochDiff = lastGlobalEpoch - epoch; + else + epochDiff = 0xFFFFFF + lastGlobalEpoch - epoch; + + if (epochDiff != pEpochDiff[nGet4]) { + snprintf( + buf, sizeof(buf), + "eTime %d - Error epoch drift Get4 %3d , last epoch diff, current epoch diff 0x%06x 0x%06x %d", + lastGlobalEpoch, nGet4, pEpochDiff[nGet4], epochDiff, pEpochDiff[nGet4] - epochDiff); + std::cout << buf << std::endl; + mess.printDataCout(critof001::msg_print_Hex | critof001::msg_print_Prefix | critof001::msg_print_Data); + } + pEpochDiff[nGet4] = epochDiff; + } + } + /* //------------------- CTRL ----------------------------// else if (msgType == 0x02) { @@ -269,12 +258,12 @@ Bool_t CbmCriGet4RawPrint::DoUnpack(const fles::Timeslice& ts, size_t /*componen pHitsCnt[nGet4]=pHitsCnt[nGet4]+1; } */ - /*snprintf(buf, sizeof(buf), + /*snprintf(buf, sizeof(buf), "Data: 0x%016lx", ulData); std::cout << buf << std::endl;*/ - } + } } // for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx ++) } // for( fuMsIndex = 0; fuMsIndex < uNbMsLoop; fuMsIndex ++ ) @@ -282,7 +271,7 @@ Bool_t CbmCriGet4RawPrint::DoUnpack(const fles::Timeslice& ts, size_t /*componen if (0 == fulCurrentTsIdx % 10000) LOG(info) << "Processed TS " << fulCurrentTsIdx; - /* + /* uint32_t nPulses = 4*10000; float effi; for(uint32_t i =0; i < NGET4 ; i++) @@ -307,9 +296,7 @@ Bool_t CbmCriGet4RawPrint::DoUnpack(const fles::Timeslice& ts, size_t /*componen return kTRUE; } -void CbmCriGet4RawPrint::Reset() -{ -} +void CbmCriGet4RawPrint::Reset() {} void CbmCriGet4RawPrint::Finish() {} diff --git a/macro/beamtime/mcbm2021/.gitignore b/macro/beamtime/mcbm2021/.gitignore index 4b257ff75e..425dde88f8 100644 --- a/macro/beamtime/mcbm2021/.gitignore +++ b/macro/beamtime/mcbm2021/.gitignore @@ -1,3 +1,4 @@ .root_hist .rootrc rootlogon.C +*.root diff --git a/macro/beamtime/mcbm2021/check_timing_any.C b/macro/beamtime/mcbm2021/check_timing_any.C new file mode 100644 index 0000000000..e3b2cef535 --- /dev/null +++ b/macro/beamtime/mcbm2021/check_timing_any.C @@ -0,0 +1,137 @@ +/* Copyright (C) 2020 Facility for Antiproton and Ion Research in Europe, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Pierre-Alain Loizeau [committer] */ + +void check_timing_any(TString fileName, UInt_t uRunId = 0, Int_t nEvents = 0, TString outDir = "data/") +{ + + // ======================================================================== + // Adjust this part according to your requirements + + // Verbosity level (0=quiet, 1=event level, 2=track level, 3=debug) + Int_t iVerbose = 1; + + // MC file + + TString srcDir = gSystem->Getenv("VMCWORKDIR"); + + // ----- Timer -------------------------------------------------------- + TStopwatch timer; + timer.Start(); + // ------------------------------------------------------------------------ + + // ----- Analysis run -------------------------------------------------- + FairRunOnline* fRun = new FairRunOnline(); + fRun->ActivateHttpServer(100, 8080); // refresh each 100 events + fRun->SetSink(new FairRootFileSink("SinkFile.root")); + FairFileSource* inputSource = new FairFileSource(fileName); + fRun->SetSource(inputSource); + + // Define output file for FairMonitor histograms + // TString monitorFile{outFile}; + // monitorFile.ReplaceAll("qa","qa.monitor"); + FairMonitor::GetMonitor()->EnableMonitor(kFALSE); + // ------------------------------------------------------------------------ + + CbmMcbmCheckTimingTask* timeChecker = new CbmMcbmCheckTimingTask(); + /// Default is using T0 as reference + /// With Pulser rejection + /* + timeChecker->SetReferenceDetector( ECbmModuleId::kT0, "T0", + -1000., 1000., 320., + 182, 190 ); +*/ + /// With pulser selection + /* + timeChecker->SetReferenceDetector( ECbmModuleId::kT0, "T0", + -1000., 1000., 320., + 190, 182 ); +*/ + /// Here swapping with TOF + + timeChecker->SetReferenceDetector(ECbmModuleId::kPsd, "Psd", -300000, 300000, 320 * 300); + timeChecker->RemoveCheckDetector(ECbmModuleId::kPsd); + //timeChecker->AddCheckDetector(ECbmModuleId::kT0, "T0"); + + /// Here swapping with MUCH + /* + timeChecker->SetReferenceDetector(ECbmModuleId::kMuch, "Much"); + timeChecker->RemoveCheckDetector(ECbmModuleId::kMuch); + timeChecker->AddCheckDetector(ECbmModuleId::kT0, "T0"); +*/ + + /// Remove detectors not present in 2021 + timeChecker->RemoveCheckDetector(ECbmModuleId::kT0); + timeChecker->RemoveCheckDetector(ECbmModuleId::kMuch); + + /// Remove detectors not yet in common unpacker + timeChecker->RemoveCheckDetector(ECbmModuleId::kSts); + timeChecker->RemoveCheckDetector(ECbmModuleId::kRich); + + /// Add detectors with wider range + timeChecker->RemoveCheckDetector(ECbmModuleId::kSts); + timeChecker->AddCheckDetector(ECbmModuleId::kSts, "Sts"); + timeChecker->RemoveCheckDetector(ECbmModuleId::kTrd); + timeChecker->AddCheckDetector(ECbmModuleId::kTrd, "Trd"); + timeChecker->RemoveCheckDetector(ECbmModuleId::kTof); + //timeChecker->AddCheckDetector(ECbmModuleId::kTof, "Tof", -150000, 150000, 320*150); + timeChecker->AddCheckDetector(ECbmModuleId::kTof, "Tof", -2000, 2000, 320 * 2); + + if (0 < uRunId) timeChecker->SetOutFilename(Form("%s/HistosTimeCheck_%03u.root", outDir.Data(), uRunId)); + fRun->AddTask(timeChecker); + + // ----- Parameter database -------------------------------------------- + // FairRuntimeDb* rtdb = fRun->GetRuntimeDb(); + // FairParRootFileIo* parIo1 = new FairParRootFileIo(); + // parIo1->open(parFile.Data(),"UPDATE"); + // rtdb->setFirstInput(parIo1); + // ------------------------------------------------------------------------ + + + // ----- Intialise and run -------------------------------------------- + fRun->Init(); + + // rtdb->setOutput(parIo1); + // rtdb->saveOutput(); + // rtdb->print(); + + cout << "Starting run" << endl; + if (0 == nEvents) { + fRun->Run(0, 0); // run until end of input file + } + else { + fRun->Run(0, nEvents); // process N Events + } + // ------------------------------------------------------------------------ + + + // ----- Finish ------------------------------------------------------- + timer.Stop(); + Double_t rtime = timer.RealTime(); + Double_t ctime = timer.CpuTime(); + cout << endl << endl; + cout << "Macro finished succesfully." << endl; + cout << "Real time " << rtime << " s, CPU time " << ctime << " s" << endl; + cout << endl; + // ------------------------------------------------------------------------ + + // Extract the maximal used memory an add is as Dart measurement + // This line is filtered by CTest and the value send to CDash + FairSystemInfo sysInfo; + Float_t maxMemory = sysInfo.GetMaxMemory(); + cout << "<DartMeasurement name=\"MaxMemory\" type=\"numeric/double\">"; + cout << maxMemory; + cout << "</DartMeasurement>" << endl; + + Float_t cpuUsage = ctime / rtime; + cout << "<DartMeasurement name=\"CpuLoad\" type=\"numeric/double\">"; + cout << cpuUsage; + cout << "</DartMeasurement>" << endl; + /* + FairMonitor* tempMon = FairMonitor::GetMonitor(); + tempMon->Print(); +*/ + // RemoveGeoManager(); + cout << " Test passed" << endl; + cout << " All ok " << endl; +} diff --git a/macro/beamtime/mcbm2021/mTofCriPar.par b/macro/beamtime/mcbm2021/mTofCriPar.par new file mode 100644 index 0000000000..db7993665d --- /dev/null +++ b/macro/beamtime/mcbm2021/mTofCriPar.par @@ -0,0 +1,35 @@ +#################################################################################################### +[CbmMcbm2018TofPar] +//---------------------------------------------------------------------------- +NrOfGdpbs: Int_t 4 +GdpbIdArray: Int_t \ +0xabc0 0xabc1 0xabc2 0xabc3 +//0x5b7b 0x55c4 0x18c5 0x5f64 0x1889 0x181c 0x1922 0x1925 0x1902 +NrOfFeesPerGdpb: Int_t 10 +NrOfGet4PerFee: Int_t 8 +NrOfChannelsPerGet4: Int_t 4 +NrOfGbtx: Int_t 8 +NrOfModule: Int_t 4 +NrOfRpc: Int_t \ + 5 5 5 5 5 5 5 5 +RpcType: Int_t \ + 0 0 0 0 2 2 0 0 +RpcSide: Int_t \ + 1 0 1 0 1 0 1 0 +ModuleId: Int_t \ + 0 0 1 1 0 0 2 2 +NbMsTot: Int_t 100 +NbMsOverlap: Int_t 1 +SizeMsInNs: Double_t 102400.0 +//SizeMsInNs: Double_t 1638400 +StarTriggerDeadtime: Double_t \ + 1000.0 1000.0 1000.0 1000.0 1000.0 +StarTriggerDelay: Double_t \ + 2000.0 2000.0 2000.0 2000.0 2000.0 +// 2000.0 2000.0 2000.0 2000.0 2000.0 +//-23000.0 -23000.0 -23000.0 -23000.0 -23000.0 +StarTriggerWinSize: Double_t \ + 2000.0 2000.0 2000.0 2000.0 2000.0 +TsDeadtimePeriod: Double_t 62.5 + +#################################################################################################### diff --git a/macro/run/run_unpack_tsa.C b/macro/run/run_unpack_tsa.C index 221ea7edce..de0cecd813 100644 --- a/macro/run/run_unpack_tsa.C +++ b/macro/run/run_unpack_tsa.C @@ -62,6 +62,7 @@ void run_unpack_tsa(std::string infile = "test.tsa", UInt_t runid = 0, const cha if (outpath.empty()) { outpath = infile.substr(0, filenamepos); } outfilename = outpath + filename; outfilename.replace(outfilename.find(".tsa"), 4, ".digi.root"); + std::cout << "-I- " << myName << ": Output file will be " << outfilename << std::endl; // ------------------------------------------------------------------------ @@ -150,6 +151,17 @@ void run_unpack_tsa(std::string infile = "test.tsa", UInt_t runid = 0, const cha } // ------------- + // ---- TOF ---- + auto tofconfig = std::make_shared<CbmTofUnpackConfig>("", runid); + // tofconfig->SetDebugState(); + tofconfig->SetDoWriteOutput(); + // tofconfig->SetDoWriteOptOutA("CbmTofErrors"); + std::string parfilesbasepathTof = Form("%s/macro/beamtime/mcbm2021/", srcDir.Data()); + tofconfig->SetParFilesBasePath(parfilesbasepathTof); + //tofconfig->SetSystemTimeOffset(-2221); // [ns] value to be updated + // ------------- + + // ------------------------------------------------------------------------ // In general, the following parts need not be touched @@ -170,6 +182,7 @@ void run_unpack_tsa(std::string infile = "test.tsa", UInt_t runid = 0, const cha if (stsconfig) unpack->SetUnpackConfig(stsconfig); if (trd1Dconfig) unpack->SetUnpackConfig(trd1Dconfig); if (trdfasp2dconfig) unpack->SetUnpackConfig(trdfasp2dconfig); + if (tofconfig) unpack->SetUnpackConfig(tofconfig); // ------------------------------------------------------------------------ @@ -213,7 +226,7 @@ void run_unpack_tsa(std::string infile = "test.tsa", UInt_t runid = 0, const cha /** * @brief Get the Trd Monitor. Extra function to keep default macro part more silent. - * @return std::shared_ptr<CbmTrdUnpackMonitor> + * @return std::shared_ptr<CbmTrdUnpackMonitor> */ std::shared_ptr<CbmTrdUnpackMonitor> GetTrdMonitor(std::string treefilename) { @@ -270,7 +283,7 @@ std::shared_ptr<CbmTrdUnpackMonitor> GetTrdMonitor(std::string treefilename) /** * @brief Get the Trd Spadic - * @return std::shared_ptr<CbmTrdSpadic> + * @return std::shared_ptr<CbmTrdSpadic> */ std::shared_ptr<CbmTrdSpadic> GetTrdSpadic(bool useAvgBaseline) { diff --git a/reco/detectors/sts/unpack/CbmStsUnpackAlgo.cxx b/reco/detectors/sts/unpack/CbmStsUnpackAlgo.cxx index 1479468a99..279e6f0dec 100644 --- a/reco/detectors/sts/unpack/CbmStsUnpackAlgo.cxx +++ b/reco/detectors/sts/unpack/CbmStsUnpackAlgo.cxx @@ -499,7 +499,6 @@ void CbmStsUnpackAlgo::processHitInfo(const stsxyter::Message& mess) // Get the time relative to the Timeslice time, I hope that the cast here works as expected. Otherwise Sts will also get into trouble with the size of UTC here auto tsreltime = static_cast<uint64_t>((ulHitTime - (fTsStartTime / stsxyter::kdClockCycleNs)) * stsxyter::kdClockCycleNs); - -fTsStartTime; double dTimeInNs = tsreltime - fSystemTimeOffset; if (uAsicIdx < fvdTimeOffsetNsAsics.size()) dTimeInNs -= fvdTimeOffsetNsAsics[uAsicIdx]; diff --git a/reco/detectors/tof/CMakeLists.txt b/reco/detectors/tof/CMakeLists.txt index 2426c496a8..998a6cd8e6 100644 --- a/reco/detectors/tof/CMakeLists.txt +++ b/reco/detectors/tof/CMakeLists.txt @@ -1,25 +1,30 @@ set(INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/unpack ${CBMDETECTORBASE_DIR}/tof ${CBMDATA_DIR} ${CBMDATA_DIR}/base ${CBMDATA_DIR}/tof + ${CBMDATA_DIR}/raw ${CBMDATA_DIR}/global - ${CBMBASE_DIR} + ${CBMBASE_DIR} ${CBMROOT_SOURCE_DIR}/reco/base ${CBMROOT_SOURCE_DIR}/core/eventdisplay + + ${CBMROOT_SOURCE_DIR}/fles/flestools # for Timeslice/Microslice printout formatting tools ) include_directories(${INCLUDE_DIRECTORIES}) set(SYSTEM_INCLUDE_DIRECTORIES - ${BASE_INCLUDE_DIRECTORIES} + ${BASE_INCLUDE_DIRECTORIES} + ${IPC_INCLUDE_DIRECTORY} # for fles infos for unpacker ) include_directories(SYSTEM ${SYSTEM_INCLUDE_DIRECTORIES}) @@ -37,14 +42,17 @@ set(SRCS CbmTofHitMaker.cxx CbmTofCosmicClusterizer.cxx CbmTofEventClusterizer.cxx - CbmTofFindTracks.cxx - CbmTofExtendTracks.cxx - CbmTofSimpClusterizer.cxx - CbmTofTrackFinderNN.cxx - CbmTofTestBeamClusterizer.cxx - CbmTofTrackletTools.cxx - CbmTofCalibrator.cxx - LKFMinuit.cxx + CbmTofFindTracks.cxx + CbmTofExtendTracks.cxx + CbmTofSimpClusterizer.cxx + CbmTofTrackFinderNN.cxx + CbmTofTestBeamClusterizer.cxx + CbmTofTrackletTools.cxx + CbmTofCalibrator.cxx + LKFMinuit.cxx + + unpack/CbmTofUnpackAlgo.cxx + unpack/CbmTofUnpackConfig.cxx ) set(LINKDEF CbmTofRecoLinkDef.h) diff --git a/reco/detectors/tof/CbmTofRecoLinkDef.h b/reco/detectors/tof/CbmTofRecoLinkDef.h index 1d7c5db420..d96636bbec 100644 --- a/reco/detectors/tof/CbmTofRecoLinkDef.h +++ b/reco/detectors/tof/CbmTofRecoLinkDef.h @@ -21,4 +21,7 @@ #pragma link C++ class CbmTofCalibrator + ; #pragma link C++ class LKFMinuit + ; +#pragma link C++ class CbmTofUnpackAlgo + ; +#pragma link C++ class CbmTofUnpackConfig + ; + #endif diff --git a/reco/detectors/tof/unpack/CbmTofUnpackAlgo.cxx b/reco/detectors/tof/unpack/CbmTofUnpackAlgo.cxx new file mode 100644 index 0000000000..5719ae8da4 --- /dev/null +++ b/reco/detectors/tof/unpack/CbmTofUnpackAlgo.cxx @@ -0,0 +1,403 @@ +/* Copyright (C) 2010 - 2021 Goethe-University Frankfurt + SPDX-License-Identifier: GPL-3.0-only + Authors: Pascal Raisig */ + +#include "CbmTofUnpackAlgo.h" + +#include "CbmFormatDecHexPrintout.h" +#include "CbmFormatMsHeaderPrintout.h" + +#include <FairParGenericSet.h> +#include <FairTask.h> +#include <Logger.h> + +#include <Rtypes.h> +#include <RtypesCore.h> + + +CbmTofUnpackAlgo::CbmTofUnpackAlgo() : CbmRecoUnpackAlgo("CbmTofUnpackAlgo") {} + +CbmTofUnpackAlgo::~CbmTofUnpackAlgo() {} + +// ---- GetParContainerRequest ---- +std::vector<std::pair<std::string, std::shared_ptr<FairParGenericSet>>>* + CbmTofUnpackAlgo::GetParContainerRequest(std::string /*geoTag*/, std::uint32_t /*runId*/) +{ + // Basepath for default Trd parameter sets (those connected to a geoTag) + std::string basepath = Form("%s", fParFilesBasePath.data()); + std::string temppath = ""; + + // // Get parameter container + temppath = basepath + "mTofCriPar.par"; + LOG(info) << fName << "::GetParContainerRequest - Trying to open file " << temppath; + fParContVec.emplace_back(std::make_pair(temppath, std::make_shared<CbmMcbm2018TofPar>())); + + return &fParContVec; +} + +// ---- init +Bool_t CbmTofUnpackAlgo::init() { return kTRUE; } + +// ---- initParSet(FairParGenericSet* parset) ---- +Bool_t CbmTofUnpackAlgo::initParSet(FairParGenericSet* parset) +{ + LOG(info) << fName << "::initParSet - for container " << parset->ClassName(); + if (parset->IsA() == CbmMcbm2018TofPar::Class()) return initParSet(static_cast<CbmMcbm2018TofPar*>(parset)); + + // If we do not know the derived ParSet class we return false + LOG(error) + << fName << "::initParSet - for container " << parset->ClassName() + << " failed, since CbmTofUnpackAlgo::initParSet() does not know the derived ParSet and what to do with it!"; + return kFALSE; +} + +// ---- initParSet(CbmTrdParSetAsic* parset) ---- +Bool_t CbmTofUnpackAlgo::initParSet(CbmMcbm2018TofPar* parset) +{ + fUnpackPar = parset; + + LOG(debug) << "InitParameters from " << parset; + + fuNrOfGdpbs = parset->GetNrOfGdpbs(); + LOG(debug) << "Nr. of Tof GDPBs: " << fuNrOfGdpbs; + + fuNrOfFeePerGdpb = parset->GetNrOfFeesPerGdpb(); + LOG(debug) << "Nr. of FEES per Tof GDPB: " << fuNrOfFeePerGdpb; + + fuNrOfGet4PerFee = parset->GetNrOfGet4PerFee(); + LOG(debug) << "Nr. of GET4 per Tof FEE: " << fuNrOfGet4PerFee; + + fuNrOfChannelsPerGet4 = parset->GetNrOfChannelsPerGet4(); + LOG(debug) << "Nr. of channels per GET4: " << fuNrOfChannelsPerGet4; + + fuNrOfChannelsPerFee = fuNrOfGet4PerFee * fuNrOfChannelsPerGet4; + LOG(debug) << "Nr. of channels per FEE: " << fuNrOfChannelsPerFee; + + fuNrOfGet4 = fuNrOfGdpbs * fuNrOfFeePerGdpb * fuNrOfGet4PerFee; + LOG(debug) << "Nr. of GET4s: " << fuNrOfGet4; + + fuNrOfGet4PerGdpb = fuNrOfFeePerGdpb * fuNrOfGet4PerFee; + LOG(debug) << "Nr. of GET4s per GDPB: " << fuNrOfGet4PerGdpb; + + fuNrOfChannelsPerGdpb = fuNrOfGet4PerGdpb * fuNrOfChannelsPerGet4; + LOG(debug) << "Nr. of channels per GDPB: " << fuNrOfChannelsPerGdpb; + + fGdpbIdIndexMap.clear(); + for (UInt_t i = 0; i < fuNrOfGdpbs; ++i) { + fGdpbIdIndexMap[parset->GetGdpbId(i)] = i; + LOG(debug) << "GDPB Id of TOF " << i << " : " << std::hex << parset->GetGdpbId(i) << std::dec; + } // for( UInt_t i = 0; i < fuNrOfGdpbs; ++i ) + + fuNrOfGbtx = parset->GetNrOfGbtx(); + LOG(debug) << "Nr. of GBTx: " << fuNrOfGbtx; + + fviRpcType.resize(fuNrOfGbtx); + fviModuleId.resize(fuNrOfGbtx); + fviNrOfRpc.resize(fuNrOfGbtx); + fviRpcSide.resize(fuNrOfGbtx); + for (UInt_t uGbtx = 0; uGbtx < fuNrOfGbtx; ++uGbtx) { + fviNrOfRpc[uGbtx] = parset->GetNrOfRpc(uGbtx); + fviRpcType[uGbtx] = parset->GetRpcType(uGbtx); + fviRpcSide[uGbtx] = parset->GetRpcSide(uGbtx); + fviModuleId[uGbtx] = parset->GetModuleId(uGbtx); + } // for( UInt_t uGbtx = 0; uGbtx < fuNrOfGbtx; ++uGbtx) + + UInt_t uNrOfChannels = fuNrOfGet4 * fuNrOfChannelsPerGet4; + LOG(debug) << "Nr. of possible Tof channels: " << uNrOfChannels; + + // CbmTofDetectorId* fTofId = new CbmTofDetectorId_v14a(); + fviRpcChUId = parset->GetRpcChUidMap(); + + TString sPrintout = ""; + for (UInt_t uCh = 0; uCh < uNrOfChannels; ++uCh) { + if (0 == uCh % 8) sPrintout += "\n"; + if (0 == uCh % fuNrOfChannelsPerGdpb) sPrintout += Form("\n Gdpb %u\n", uCh / fuNrOfChannelsPerGdpb); + sPrintout += Form(" 0x%08x", fviRpcChUId[uCh]); + } // for( UInt_t i = 0; i < uNrOfChannels; ++i) + LOG(debug) << sPrintout; + + LOG(info) << fName << "::initParSetTofMcbm2018 - Successfully initialized TOF settings"; + + return kTRUE; +} + +bool CbmTofUnpackAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp, UInt_t imslice) +{ + auto msDescriptor = ts->descriptor(icomp, imslice); + fuCurrentEquipmentId = msDescriptor.eq_id; + const uint8_t* msContent = reinterpret_cast<const uint8_t*>(ts->content(icomp, imslice)); + + fulCurrentTsIdx = ts->index(); + uint32_t uSize = msDescriptor.size; + fulCurrentMsIdx = msDescriptor.idx; + // Double_t dMsTime = (1e-9) * static_cast<double>(fulCurrentMsIdx); + LOG(debug) << "Microslice: " << fulCurrentMsIdx << " from EqId " << std::hex << fuCurrentEquipmentId << std::dec + << " has size: " << uSize; + + if (0 == fvbMaskedComponents.size()) fvbMaskedComponents.resize(ts->num_components(), false); + + fuCurrDpbId = static_cast<uint32_t>(fuCurrentEquipmentId & 0xFFFF); + // fuCurrDpbIdx = fDpbIdIndexMap[ fuCurrDpbId ]; + + /// Check if this sDPB ID was declared in parameter file and stop there if not + auto it = fGdpbIdIndexMap.find(fuCurrDpbId); + if (it == fGdpbIdIndexMap.end()) { + if (false == fvbMaskedComponents[icomp]) { + LOG(debug) << "---------------------------------------------------------------"; + LOG(debug) << FormatMsHeaderPrintout(msDescriptor); + LOG(warning) << fName << "::unpack => " + << "Could not find the gDPB index for FLIM id 0x" << std::hex << fuCurrDpbId << std::dec + << " in timeslice " << fulCurrentTsIdx << " in microslice " << imslice << " component " << icomp + << std::endl + << "If valid this index has to be added in the TOF parameter file in the DbpIdArray field"; + fvbMaskedComponents[icomp] = true; + } // if( false == fvbMaskedComponents[ uMsComp ] ) + else + return true; + + return false; + } // if( it == fGdpbIdIndexMap.end() ) + else + fuCurrDpbIdx = fGdpbIdIndexMap[fuCurrDpbId]; + + fuCurrentMsSysId = static_cast<unsigned int>(msDescriptor.sys_id); + + // If not integer number of message in input buffer, print warning/error + if (0 != (uSize % sizeof(critof001::Message))) + LOG(error) << fName << "::unpack => " + << "The input microslice buffer does NOT contain only complete gDPB messages!"; + + // Compute the number of complete messages in the input microslice buffer + uint32_t uNbMessages = (uSize - (uSize % sizeof(critof001::Message))) / sizeof(critof001::Message); + + // Prepare variables for the loop on contents + Int_t messageType = -111; + fbLastEpochGood = false; + fuProcEpochUntilError = 0; + + if (0 == imslice) { + /// Extract the time base only on MS 0, assuming that we get all TS of a component in order + ExtractTsStartEpoch(fTsStartTime); + } + + const uint64_t* pInBuff = reinterpret_cast<const uint64_t*>(msContent); // for epoch cycle + const critof001::Message* pMess = reinterpret_cast<const critof001::Message*>(pInBuff); + + for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx++) { + /// Due to buffer bug some messages are duplicated + if (0 < uIdx && pMess[uIdx] == pMess[uIdx - 1]) { + /// Ignore duplicate message + continue; + } + + /// Get message type + messageType = pMess[uIdx].getMessageType(); + + if (uNbMessages - 1 == uIdx) { + if (pMess[uIdx].isEndOfMs()) { + /// Tricking clang to avoid one liner + continue; + } + else { + LOG(warning) << fName << "::unpack => " + << "In timeslice " << fulCurrentTsIdx << " in microslice " << imslice << " component " << icomp + << " last message is not an EndOfMs: type " << messageType + << Form(" dump: 0x%16lX", pMess[uIdx].getData()); + } // else of if( pMess[uIdx].isEndOfMs() ) + } // if( uNbMessages - 1 == uIdx ) + /* + if( 0 == imslice ) + LOG(debug) << fName << "::unpack => " + << "Message type " << std::hex << std::setw(2) << static_cast<uint16_t>(messageType) << std::dec; +*/ + fuGet4Id = fUnpackPar->ElinkIdxToGet4Idx(pMess[uIdx].getGet4Idx()); + if (0x90 == fuCurrentMsSysId) fuGet4Id = pMess[uIdx].getGet4Idx(); + fuGet4Nr = (fuCurrDpbIdx * fuNrOfGet4PerGdpb) + fuGet4Id; + + if (fuNrOfGet4PerGdpb <= fuGet4Id && (critof001::kuChipIdMergedEpoch != fuGet4Id)) + LOG(warning) << fName << "::unpack => " + << "Message with Get4 ID too high: " << fuGet4Id << " VS " << fuNrOfGet4PerGdpb << " for FLIM " + << fuCurrDpbIdx << " set in parameters."; + + + if (0 == uIdx && critof001::MSG_EPOCH != messageType) { + LOG(warning) << fName << "::unpack => " + << "In timeslice " << fulCurrentTsIdx << " in microslice " << imslice << " component " << icomp + << " first message is not an epoch: type " << messageType + << Form(" dump: 0x%16lX", pMess[uIdx].getData()); + LOG(warning) << fName << "::unpack => " + << "Ignoring this microslice."; + return false; + } + + switch (messageType) { + case critof001::MSG_HIT: { + if (fbLastEpochGood) { + /// Epoch OK + ProcessHit(pMess[uIdx]); + } + break; + } // case critof001::MSG_HIT: + case critof001::MSG_EPOCH: { + if (critof001::kuChipIdMergedEpoch == fuGet4Id) { + ProcessEpoch(pMess[uIdx], uIdx); + } // if this epoch message is a merged one valid for all chips + else { + /// Should be checked in monitor task, here we just jump it + LOG(debug2) << fName << "::unpack => " + << "This unpacker does not support unmerged epoch messages!!!."; + continue; + } // if single chip epoch message + break; + } // case critof001::MSG_EPOCH: + case critof001::MSG_SLOWC: + case critof001::MSG_SYST: { + /// Ignored messages + /// TODO,FIXME: should be filled into fOptOutAVec as CbmErrorMessage + break; + } // case critof001::MSG_ERROR + default: + LOG(error) << fName << "::unpack => " + << "Message type " << std::hex << std::setw(2) << static_cast<uint16_t>(messageType) << std::dec + << " not included in Get4 unpacker."; + } // switch( mess.getMessageType() ) + } // for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx ++) + + return true; +} + +// ------------------------------------------------------------------------- +void CbmTofUnpackAlgo::ExtractTsStartEpoch(const uint64_t& ulTsStart) +{ + fulTsStartInEpoch = static_cast<uint64_t>(ulTsStart / critof001::kuEpochInNs) % critof001::kulEpochCycleEp; + + /// FIXME: seems there is an offset of +4 Epoch between data and header + /// from dt to PSD, the epoch seem to be right => placed in wrong MS! + if (fulTsStartInEpoch < 4) { fulTsStartInEpoch = critof001::kulEpochCycleEp + fulTsStartInEpoch - 4; } + else { + fulTsStartInEpoch -= 4; + } +} + +void CbmTofUnpackAlgo::ProcessEpoch(const critof001::Message& mess, uint32_t uMesgIdx) +{ + /// FIXME: seems there is an offset of +4 Epoch between data and header + /// from dt to PSD, the epoch seem to be right => placed in wrong MS! + ULong64_t ulEpochNr = mess.getGdpbEpEpochNb(); + //ULong64_t ulEpochNr = (mess.getGdpbEpEpochNb() + 4) % critof001::kulEpochCycleEp; + + if (0 == uMesgIdx) { + uint64_t ulMsStartInEpoch = + static_cast<uint64_t>(fulCurrentMsIdx / critof001::kuEpochInNs) % critof001::kulEpochCycleEp; + /// FIXME: seems there is an offset of +4 Epoch between data and header + /// from dt to PSD, the epoch seem to be right => placed in wrong MS! + if (ulMsStartInEpoch < 4) { ulMsStartInEpoch = critof001::kulEpochCycleEp + ulMsStartInEpoch - 4; } + else { + ulMsStartInEpoch -= 4; + } + + if (ulEpochNr != ulMsStartInEpoch) { + LOG(error) << fName << "::ProcessEpoch => Error first global epoch, " + << Form( + "from MS index 0x%06lx, current 0x%06llx, diff %lld, raw 0x%016lx, NoErr %d, current 0x%06lx %f", + ulMsStartInEpoch, ulEpochNr, ulEpochNr - ulMsStartInEpoch, mess.getData(), fuProcEpochUntilError, + static_cast<uint64_t>(fulCurrentMsIdx / critof001::kuEpochInNs), + fulCurrentMsIdx / critof001::kuEpochInNs); + LOG(error) << fName << "::ProcessEpoch => Ignoring data until next valid epoch"; + + fbLastEpochGood = false; + ulEpochNr = ulMsStartInEpoch; + fuProcEpochUntilError = 0; + } // if( ulEpochNr != ulMsStartInEpoch ) + else { + fbLastEpochGood = true; + fuProcEpochUntilError++; + } // else of if( ulEpochNr != ulMsStartInEpoch ) + } // if( 0 < uMesgIdx ) + else if (((fulCurrentEpoch + 1) % critof001::kulEpochCycleEp) != ulEpochNr) { + LOG(error) << fName << "::ProcessEpoch => Error global epoch, " + << Form("last 0x%06llx, current 0x%06llx, diff %lld, raw 0x%016lx, NoErr %d", fulCurrentEpoch, ulEpochNr, + ulEpochNr - fulCurrentEpoch, mess.getData(), fuProcEpochUntilError); + LOG(error) << fName << "::ProcessEpoch => Ignoring data until next valid epoch"; + + ulEpochNr = (fulCurrentEpoch + 1) % critof001::kulEpochCycleEp; + fbLastEpochGood = false; + fuProcEpochUntilError = 0; + } // if( ( (fulCurrentEpoch + 1) % critof001::kuEpochCounterSz ) != ulEpochNr ) + else { + fbLastEpochGood = true; + fuProcEpochUntilError++; + } + + fulCurrentEpoch = ulEpochNr; + if (fulTsStartInEpoch <= ulEpochNr) { fulEpochIndexInTs = ulEpochNr - fulTsStartInEpoch; } + else { + fulEpochIndexInTs = ulEpochNr + critof001::kulEpochCycleEp - fulTsStartInEpoch; + } + if (10e9 < critof001::kuEpochInNs * fulEpochIndexInTs) + LOG(debug) << fName << "::ProcessEpoch => " + << Form("Raw Epoch: 0x%06llx, Epoch offset 0x%06lx, Epoch in Ts: 0x%07lx, time %f ns (%f * %lu)", + ulEpochNr, fulTsStartInEpoch, fulEpochIndexInTs, critof001::kuEpochInNs * fulEpochIndexInTs, + critof001::kuEpochInNs, fulEpochIndexInTs); +} + +void CbmTofUnpackAlgo::ProcessHit(const critof001::Message& mess) +{ + UInt_t uChannel = mess.getGdpbHitChanId(); + UInt_t uTot = mess.getGdpbHit32Tot(); + + UInt_t uChannelNr = fuGet4Id * fuNrOfChannelsPerGet4 + uChannel; + UInt_t uChannelNrInFee = (fuGet4Id % fuNrOfGet4PerFee) * fuNrOfChannelsPerGet4 + uChannel; + UInt_t uFeeNr = (fuGet4Id / fuNrOfGet4PerFee); + UInt_t uFeeNrInSys = fuCurrDpbIdx * fuNrOfFeePerGdpb + uFeeNr; + // UInt_t uRemappedChannelNr = uFeeNr * fuNrOfChannelsPerFee + fUnpackPar->Get4ChanToPadiChan(uChannelNrInFee); + + UInt_t uRemappedChannelNrInSys = fuCurrDpbIdx * fuNrOfChannelsPerGdpb + uFeeNr * fuNrOfChannelsPerFee + + fUnpackPar->Get4ChanToPadiChan(uChannelNrInFee); + /// Diamond FEE have straight connection from Get4 to eLink and from PADI to GET4 + if (0x90 == fuCurrentMsSysId) { + // uRemappedChannelNr = uChannelNr; + uRemappedChannelNrInSys = fuCurrDpbIdx * fUnpackPar->GetNrOfChannelsPerGdpb() + uChannelNr; + } // if(0x90 == fuCurrentMsSysId) + + Double_t dHitTime = mess.getMsgFullTimeD(fulEpochIndexInTs); + Double_t dHitTot = uTot; // in bins + + if (fviRpcChUId.size() < uRemappedChannelNrInSys) { + LOG(fatal) << fName << "::unpack => " + << "Invalid mapping index " << uRemappedChannelNrInSys << " VS " << fviRpcChUId.size() << ", from FLIM " + << fuCurrDpbIdx << ", Get4 " << fuGet4Id << ", Ch " << uChannel << ", ChNr " << uChannelNr << ", ChNrIF " + << uChannelNrInFee << ", FiS " << uFeeNrInSys; + return; + } // if( fviRpcChUId.size() < uRemappedChannelNrInSys ) + + UInt_t uChanUId = fviRpcChUId[uRemappedChannelNrInSys]; + + if (0 == uChanUId) { + if (0 < fuMapWarnToPrint--) + LOG(warning) << fName << "::unpack => " + << "Unused data item at " << uRemappedChannelNrInSys << ", from FLIM " << fuCurrDpbIdx << ", Get4 " + << fuGet4Id << ", Ch " << uChannel << ", ChNr " << uChannelNr << ", ChNrIF " << uChannelNrInFee + << ", FiS " << uFeeNrInSys; + return; // Hit not mapped to digi + } + + /// Apply offset to T0 only to TOF digis + if (0x90 != fuCurrentMsSysId) { + /// Tricking clang to avoid one liner + dHitTime -= fdTimeOffsetNs; + } + + /// FIXME: seems there is an offset of +4 Epoch between data and header + /// from dt to PSD, the epoch are probably the one off, not the MS time! + dHitTime -= 4.0 * critof001::kuEpochInNs; + + LOG(debug) << Form("Insert 0x%08x digi with time ", uChanUId) << dHitTime << Form(", Tot %4.0f", dHitTot) + << " at epoch " << fulEpochIndexInTs; + + /// Create output object and store it + std::unique_ptr<CbmTofDigi> digi(new CbmTofDigi(uChanUId, dHitTime, dHitTot)); + if (digi) fOutputVec.emplace_back(*std::move(digi)); +} + +ClassImp(CbmTofUnpackAlgo) diff --git a/reco/detectors/tof/unpack/CbmTofUnpackAlgo.h b/reco/detectors/tof/unpack/CbmTofUnpackAlgo.h new file mode 100644 index 0000000000..e773bd76a4 --- /dev/null +++ b/reco/detectors/tof/unpack/CbmTofUnpackAlgo.h @@ -0,0 +1,191 @@ +/* Copyright (C) 2010 - 2021 Goethe-University Frankfurt + SPDX-License-Identifier: GPL-3.0-only + Authors: Pascal Raisig */ + +/** + * @file CbmTofUnpackAlgo.h + * @author Pascal Raisig (praisig@ikf.uni-frankfurt.de) + * @brief Baseclass for the TrdR unpacker algorithms + * @version 0.1 + * @date 2021-04-21 + * + * @copyright Copyright (c) 2021 + * + * This is the base class for the algorithmic part of the tsa data unpacking + * processes of the CbmTrd. + * The actual translation from tsa to digi happens in the derived classes. + * + * +*/ + +#ifndef CbmTofUnpackAlgo_H +#define CbmTofUnpackAlgo_H + +#include "CbmErrorMessage.h" +#include "CbmMcbm2018TofPar.h" +#include "CbmRecoUnpackAlgo.tmpl" +#include "CbmTofDigi.h" + +#include "Timeslice.hpp" // timeslice + +#include <Rtypes.h> // for types +#include <RtypesCore.h> + +#include <cstddef> +#include <cstdint> +#include <memory> +#include <utility> + +#include "CriGet4Mess001.h" + +class CbmTofUnpackAlgo : public CbmRecoUnpackAlgo<CbmTofDigi, CbmErrorMessage> { +public: + /** @brief Create the Cbm Trd Unpack AlgoBase object */ + CbmTofUnpackAlgo(); + + /** @brief Destroy the Cbm Trd Unpack Task object */ + virtual ~CbmTofUnpackAlgo(); + + /** @brief Copy constructor - not implemented **/ + CbmTofUnpackAlgo(const CbmTofUnpackAlgo&) = delete; + + /** @brief Assignment operator - not implemented **/ + CbmTofUnpackAlgo& operator=(const CbmTofUnpackAlgo&) = delete; + + /** + * @brief Get the requested parameter containers. To be defined in the derived classes! + * Return the required parameter containers together with the paths to the ascii + * files to. + * + * @param[in] std::string geoTag as used in CbmSetup + * @param[in] std::uint32_t runId for runwise defined parameters + * @return fParContVec + */ + virtual std::vector<std::pair<std::string, std::shared_ptr<FairParGenericSet>>>* + GetParContainerRequest(std::string geoTag, std::uint32_t runId); + +protected: + /** @brief Finish function for this algorithm base clase */ + void finish() + { + finishDerived(); + // Finish the monitor if we have one + // if (fMonitor) fMonitor->Finish(); + } + + /** @brief Function that allows special calls during Finish in the derived algos */ + virtual void finishDerived() { return; } + + /** + * @brief Initialisation at begin of run. Special inits of the derived algos. + * + * @retval Bool_t initOk + */ + Bool_t init(); + + /** + * @brief Handles the distribution of the hidden derived classes to their explicit functions. + * + * @param parset + * @return Bool_t initOk + */ + Bool_t initParSet(FairParGenericSet* parset); + + /** + * @brief Handles the distribution of the hidden derived classes to their explicit functions. + * + * @param parset + * @return Bool_t initOk + */ + Bool_t initParSet(CbmMcbm2018TofPar* parset); + + /** + * @brief Set the Derived Ts Parameters + * + * In this function parameters required by the explicit algo connected to the timeslice can be set. + * + * @param itimeslice + * @return true + * @return false + */ + bool setDerivedTsParameters(size_t itimeslice) { return true; } + + /** + * @brief Unpack a given microslice. To be implemented in the derived unpacker algos. + * + * @param ts timeslice pointer + * @param icomp index to the component to be unpacked + * @param imslice index of the microslice to be unpacked + * @return true + * @return false + * + * @remark The content of the µslice can only be accessed via the timeslice. Hence, we need to pass the pointer to the full timeslice + */ + bool unpack(const fles::Timeslice* ts, std::uint16_t icomp, UInt_t imslice); + +private: + /// Buffers processing + void ProcessEpSupprBuffer(); + + /// Message processing methods + void ExtractTsStartEpoch(const uint64_t& ulTsStart); + void ProcessEpoch(const critof001::Message& mess, uint32_t uMesgIdx); + void ProcessEndOfMsEpoch(); + void ProcessHit(const critof001::Message& mess); + + inline Int_t GetArrayIndex(Int_t gdpbId, Int_t get4Id) { return gdpbId * fuNrOfGet4PerGdpb + get4Id; } + + + /// Settings from parameter file + CbmMcbm2018TofPar* fUnpackPar = nullptr; //! For static/inline mapping functions + + /// Readout chain dimensions and mapping + UInt_t fuNrOfGdpbs = 0; //! Total number of GDPBs in the system + std::map<UInt_t, UInt_t> fGdpbIdIndexMap = {}; //! gDPB ID to index map + UInt_t fuNrOfFeePerGdpb = 0; //! Number of FEBs per GDPB + UInt_t fuNrOfGet4PerFee = 0; //! Number of GET4s per FEE + UInt_t fuNrOfChannelsPerGet4 = 0; //! Number of channels in each GET4 + UInt_t fuNrOfChannelsPerFee = 0; //! Number of channels in each FEE + UInt_t fuNrOfGet4 = 0; //! Total number of Get4 chips in the system + UInt_t fuNrOfGet4PerGdpb = 0; //! Number of GET4s per GDPB + UInt_t fuNrOfChannelsPerGdpb = 0; //! Number of channels per GDPB + + /// Detector Mapping + UInt_t fuNrOfGbtx = 0; + UInt_t fuNrOfModules = 0; + std::vector<Int_t> fviNrOfRpc = {}; + std::vector<Int_t> fviRpcType = {}; + std::vector<Int_t> fviRpcSide = {}; + std::vector<Int_t> fviModuleId = {}; + std::vector<Int_t> fviRpcChUId = {}; + + /// User settings: Data correction parameters + Double_t fdTimeOffsetNs; + + /// Running indices + UInt_t fuMapWarnToPrint = 100; + ULong64_t fulCurrentTsIdx = 0; //! Idx of the current TS + ULong64_t fulCurrentMsIdx = 0; //! Idx of the current MS in TS (0 to fuTotalMsNb) + size_t fuCurrentMsSysId = 0; //! SysId of the current MS in TS (0 to fuTotalMsNb) + UInt_t fuCurrentEquipmentId = 0; //! Current equipment ID, tells from which DPB the current MS is originating + UInt_t fuCurrDpbId = 0; //! Temp holder until Current equipment ID is properly filled in MS + UInt_t fuCurrDpbIdx = 0; //! Index of the DPB from which the MS currently unpacked is coming + UInt_t fuGet4Id = + 0; //! running number (0 to fuNrOfGet4PerGdpb) of the Get4 chip of a unique GDPB for current message + UInt_t fuGet4Nr = 0; //! running number (0 to fuNrOfGet4) of the Get4 chip in the system for current message + /// Data format control: Current time references for each GDPB: merged epoch marker, epoch cycle, full epoch [fuNrOfGdpbs] + ULong64_t fulCurrentEpoch = 0; //! Current epoch index + + /// Control flags + std::vector<bool> fvbMaskedComponents = {}; + bool fbLastEpochGood = false; + + /// Book-keeping members + uint32_t fuProcEpochUntilError = 0; + uint64_t fulTsStartInEpoch = 0; + uint64_t fulEpochIndexInTs = 0; + + ClassDef(CbmTofUnpackAlgo, 1) +}; + +#endif // CbmTofUnpackAlgo_H diff --git a/reco/detectors/tof/unpack/CbmTofUnpackConfig.cxx b/reco/detectors/tof/unpack/CbmTofUnpackConfig.cxx new file mode 100644 index 0000000000..b61bf318a1 --- /dev/null +++ b/reco/detectors/tof/unpack/CbmTofUnpackConfig.cxx @@ -0,0 +1,67 @@ +/* Copyright (C) 2010 - 2021 Goethe-University Frankfurt + SPDX-License-Identifier: GPL-3.0-only + Authors: Pascal Raisig */ + +#include "CbmTofUnpackConfig.h" + +#include "CbmTofUnpackAlgo.h" + +#include <Logger.h> + +#include <Rtypes.h> +#include <RtypesCore.h> + +#include <memory> +#include <vector> + +CbmTofUnpackConfig::CbmTofUnpackConfig(std::string detGeoSetupTag, UInt_t runid) + : CbmRecoUnpackConfig("CbmTofUnpackConfig") + , fGeoSetupTag(detGeoSetupTag) + , fRunId(runid) +{ +} + +CbmTofUnpackConfig::~CbmTofUnpackConfig() {} + +// ---- Init ---- +void CbmTofUnpackConfig::InitUnpacker() +{ + LOG(info) << fName << "::Init -"; + + auto initOk = kTRUE; + + // First choose the derived unpacking algorithm to be used and pass the raw to digi method + auto algo = chooseAlgo(); + + if (fDoLog) LOG(info) << fName << "::Init - SetParFilesBasePath"; + algo->SetParFilesBasePath(fParFilesBasePath); + + // Initialise the parameter containers required by the unpacker algo. Includes loading the corresponding ascii files + auto reqparvec = algo->GetParContainerRequest(fGeoSetupTag, fRunId); + initOk &= initParContainers(reqparvec); + + // Now we have all information required to initialise the algorithm + algo->Init(); + + // Pass the algo to its member in the base class + fAlgo = algo; +} + +// ---- chooseAlgo ---- +std::shared_ptr<CbmTofUnpackAlgo> CbmTofUnpackConfig::chooseAlgo() +{ + if (fDoLog) LOG(info) << fName << "::Init - chooseAlgo"; + + // Default unpacker selection + // Unpacker algo from mcbm 2021 on and hopefully default for a long time. + auto algo = std::make_shared<CbmTofUnpackAlgo>(); + LOG(info) << fName << "::chooseAlgo() - selected algo = " << algo->Class_Name(); + return algo; + + LOG(error) << fName + << "::Init - chooseAlgo() - no algorithm created something went wrong. We can not work like this!"; + return nullptr; +} + + +ClassImp(CbmTofUnpackConfig) diff --git a/reco/detectors/tof/unpack/CbmTofUnpackConfig.h b/reco/detectors/tof/unpack/CbmTofUnpackConfig.h new file mode 100644 index 0000000000..bc92d0731f --- /dev/null +++ b/reco/detectors/tof/unpack/CbmTofUnpackConfig.h @@ -0,0 +1,90 @@ +/* Copyright (C) 2010 - 2021 Goethe-University Frankfurt + SPDX-License-Identifier: GPL-3.0-only + Authors: Pascal Raisig */ + +/** + * @file CbmTofUnpackConfig.h + * @author Pascal Raisig (praisig@ikf.uni-frankfurt.de) + * @brief Configuration class for an unpacker algorithm + * @version 0.1 + * @date 2021-04-21 + * + * @copyright Copyright (c) 2021 + * + * This is the common configuration class for unpacking algorithms + * +*/ + +#ifndef CbmTofUnpackConfig_H +#define CbmTofUnpackConfig_H + +#include "CbmErrorMessage.h" +#include "CbmRecoUnpackConfig.tmpl" +#include "CbmTofDigi.h" +#include "CbmTofUnpackAlgo.h" + +#include <FairLogger.h> +#include <Logger.h> + +#include <Rtypes.h> +#include <RtypesCore.h> + +#include <cstddef> +#include <cstdint> +#include <memory> +#include <vector> + +class CbmTofUnpackConfig : public CbmRecoUnpackConfig<CbmTofUnpackAlgo, CbmTofDigi, CbmErrorMessage> { + +public: + /** + * @brief Create the Cbm Tof Unpack Task object + * + * @param geoSetupTag Geometry setup tag for the given detector as used by CbmSetup objects + * @param runid set if unpacker is rerun on a special run with special parameters + *@remark We use the string instead of CbmSetup here, to not having to link against sim/steer... + */ + CbmTofUnpackConfig(std::string detGeoSetupTag, UInt_t runid = 0); + + /** + * @brief Destroy the Cbm Tof Unpack Task object + * + */ + virtual ~CbmTofUnpackConfig(); + + /** @brief Copy constructor - not implemented **/ + CbmTofUnpackConfig(const CbmTofUnpackConfig&) = delete; + + /** @brief Assignment operator - not implemented **/ + CbmTofUnpackConfig& operator=(const CbmTofUnpackConfig&) = delete; + + // Getters + + + /** + * @brief Prepare the unpacker to be ready to run. + * In this function all initialization steps of the unpacker algorithms happen. + */ + void InitUnpacker(); + + // Setters + +protected: + /** + * @brief Choose the derived unpacker algorithm to be used for the DAQ output to Digi translation. If algo was already set manually by the user this algorithm is used. + * + * @return Bool_t initOk + */ + virtual std::shared_ptr<CbmTofUnpackAlgo> chooseAlgo(); + + /** @brief Geometry setup tag for the given detector as used by CbmSetup objects */ + std::string fGeoSetupTag = ""; + + /** @brief RunId of the current run, if not known 0 is a valid runtime case. Used runId based parameter loading. */ + UInt_t fRunId = 0; + +private: + ClassDef(CbmTofUnpackConfig, 1) +}; + +#endif // CbmTofUnpackConfig_H diff --git a/reco/steer/CMakeLists.txt b/reco/steer/CMakeLists.txt index 236f0c4d2e..14a50d7cf1 100644 --- a/reco/steer/CMakeLists.txt +++ b/reco/steer/CMakeLists.txt @@ -39,13 +39,13 @@ ${CBMROOT_SOURCE_DIR}/core/data/base ${CBMROOT_SOURCE_DIR}/core/data/psd ${CBMROOT_SOURCE_DIR}/core/data/rich ${CBMROOT_SOURCE_DIR}/core/data/sts -# ${CBMROOT_SOURCE_DIR}/core/data/tof +${CBMROOT_SOURCE_DIR}/core/data/tof ${CBMROOT_SOURCE_DIR}/core/data/trd ${CBMROOT_SOURCE_DIR}/core/detectors/psd ${CBMROOT_SOURCE_DIR}/core/detectors/rich ${CBMROOT_SOURCE_DIR}/core/detectors/sts -# ${CBMROOT_SOURCE_DIR}/core/detectors/tof +${CBMROOT_SOURCE_DIR}/core/detectors/tof ${CBMROOT_SOURCE_DIR}/core/detectors/trd diff --git a/reco/steer/CbmRecoUnpack.cxx b/reco/steer/CbmRecoUnpack.cxx index 68b1e08887..a75a6aa76d 100644 --- a/reco/steer/CbmRecoUnpack.cxx +++ b/reco/steer/CbmRecoUnpack.cxx @@ -40,7 +40,7 @@ void CbmRecoUnpack::Finish() if (fPsdConfig) fPsdConfig->GetUnpacker()->Finish(); if (fRichConfig) fRichConfig->GetUnpacker()->Finish(); if (fStsConfig) fStsConfig->GetUnpacker()->Finish(); - // if (fTofConfig) fTofConfig->GetUnpacker()->Finish(); + if (fTofConfig) fTofConfig->GetUnpacker()->Finish(); if (fTrdConfig) fTrdConfig->GetUnpacker()->Finish(); if (fTrdConfig2D) fTrdConfig2D->GetUnpacker()->Finish(); } @@ -79,6 +79,8 @@ Bool_t CbmRecoUnpack::Init() if (fTrdConfig2D) fTrdConfig2D->Init(ioman); } // This is an ugly work around, because the TRD and TRD2D want to access the same vector and there is no function to retrieve a writeable vector<obj> from the FairRootManager, especially before the branches are created, as far as I am aware. The second option workaround is in in Init() to look for the fasp config and create a separate branch for fasp created CbmTrdDigis PR 072021 + // --- Tof + if (fTofConfig) fTofConfig->Init(ioman); return kTRUE; } @@ -102,6 +104,8 @@ void CbmRecoUnpack::Reset() if (fTrdConfig) fTrdConfig->Reset(); // ---- Trd2D ---- if (fTrdConfig2D) fTrdConfig2D->Reset(); + // ---- Tof ---- + if (fTofConfig) fTofConfig->Reset(); } // ---------------------------------------------------------------------------- @@ -153,6 +157,12 @@ void CbmRecoUnpack::Unpack(unique_ptr<Timeslice> ts) unpack(×lice, component, fTrdConfig2D, fTrdConfig2D->GetOptOutAVec(), fTrdConfig2D->GetOptOutBVec())); break; } + case fkFlesTof: { + if (fTofConfig) + fCbmTsEventHeader->SetNDigisTof( + unpack(×lice, component, fTofConfig, fTofConfig->GetOptOutAVec(), fTofConfig->GetOptOutBVec())); + break; + } default: { if (fDoDebugPrints) LOG(error) << "Unpack: Unknown system ID " << systemId << " for component " << component; diff --git a/reco/steer/CbmRecoUnpack.h b/reco/steer/CbmRecoUnpack.h index 062618127f..7f9441ac31 100644 --- a/reco/steer/CbmRecoUnpack.h +++ b/reco/steer/CbmRecoUnpack.h @@ -11,6 +11,7 @@ #include "CbmPsdUnpackConfig.h" #include "CbmRichUnpackConfig.h" #include "CbmStsUnpackConfig.h" +#include "CbmTofUnpackConfig.h" #include "CbmTrdUnpackConfig.h" #include "CbmTrdUnpackConfigFasp2D.h" #include "CbmTsEventHeader.h" @@ -65,8 +66,8 @@ public: /** * @brief Set the Debug Printout Flag - * - * @param value + * + * @param value */ void SetDebugPrintout(bool value = true) { fDoDebugPrints = value; } @@ -88,6 +89,9 @@ public: /** @brief Set the Trd2D Unpack Config @param config */ void SetUnpackConfig(std::shared_ptr<CbmTrdUnpackConfigFasp2D> config) { fTrdConfig2D = config; } + /** @brief Set the Tof Unpack Config @param config */ + void SetUnpackConfig(std::shared_ptr<CbmTofUnpackConfig> config) { fTofConfig = config; } + /** @brief Trigger the unpacking procedure **/ void Unpack(std::unique_ptr<fles::Timeslice> ts); @@ -134,7 +138,7 @@ private: /** * @brief Template for the unpacking call of a given algorithm. - * + * * @tparam TAlgo Algorithm to be called * @tparam TOutput Output element types * @tparam TOptoutputs Optional output element types @@ -195,17 +199,17 @@ private: } // ---------------------------------------------------------------------------- - /** @brief Configuration of the Trd unpacker. Provides the configured algorithm */ + /** @brief Configuration of the Psd unpacker. Provides the configured algorithm */ std::shared_ptr<CbmPsdUnpackConfig> fPsdConfig = nullptr; //! - /** @brief Configuration of the Trd unpacker. Provides the configured algorithm */ + /** @brief Configuration of the Rich unpacker. Provides the configured algorithm */ std::shared_ptr<CbmRichUnpackConfig> fRichConfig = nullptr; //! - /** @brief Configuration of the Trd unpacker. Provides the configured algorithm */ + /** @brief Configuration of the Sts unpacker. Provides the configured algorithm */ std::shared_ptr<CbmStsUnpackConfig> fStsConfig = nullptr; //! - // /** @brief Configuration of the Trd unpacker. Provides the configured algorithm */ - // std::shared_ptr<CbmTofUnpackConfig> fTofConfig = nullptr; //! + /** @brief Configuration of the Tof unpacker. Provides the configured algorithm */ + std::shared_ptr<CbmTofUnpackConfig> fTofConfig = nullptr; //! /** @brief Configuration of the Trd unpacker. Provides the configured algorithm */ std::shared_ptr<CbmTrdUnpackConfig> fTrdConfig = nullptr; //! -- GitLab