From 2a1c17cf4f14779e12b295d06f67c7d1df1342e3 Mon Sep 17 00:00:00 2001 From: Alexandru Bercuci <abercuci@niham.nipne.ro> Date: Mon, 7 Mar 2022 13:12:00 +0200 Subject: [PATCH] rename CbmTrdUnpackAlgoFasp2D to CbmTrdUnpackFaspAlgo and same for Config class to align to the naming convention of Cbm and also decouple FEE from read-out design --- MQ/mcbm/CbmDeviceUnpack.cxx | 6 +- MQ/mcbm/CbmDeviceUnpack.h | 6 +- reco/detectors/trd/CMakeLists.txt | 4 +- reco/detectors/trd/CbmTrdRecoLinkDef.h | 4 +- .../trd/unpack/CbmTrdUnpackFaspAlgo.cxx | 410 ++++++++++++++++++ .../trd/unpack/CbmTrdUnpackFaspAlgo.h | 191 ++++++++ .../trd/unpack/CbmTrdUnpackFaspConfig.cxx | 50 +++ .../trd/unpack/CbmTrdUnpackFaspConfig.h | 88 ++++ reco/steer/CbmRecoUnpack.h | 6 +- 9 files changed, 752 insertions(+), 13 deletions(-) create mode 100644 reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.cxx create mode 100644 reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.h create mode 100644 reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.cxx create mode 100644 reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.h diff --git a/MQ/mcbm/CbmDeviceUnpack.cxx b/MQ/mcbm/CbmDeviceUnpack.cxx index af97142bd5..7d0f5d5e67 100644 --- a/MQ/mcbm/CbmDeviceUnpack.cxx +++ b/MQ/mcbm/CbmDeviceUnpack.cxx @@ -20,7 +20,7 @@ #include "CbmStsUnpackConfig.h" #include "CbmTofUnpackConfig.h" #include "CbmTrdUnpackConfig.h" -#include "CbmTrdUnpackConfigFasp2D.h" +#include "CbmTrdUnpackFaspConfig.h" #include "StorableTimeslice.hpp" #include "TimesliceMetaData.h" @@ -211,9 +211,9 @@ Bool_t CbmDeviceUnpack::InitContainers() } // if ("" != trdsetuptag) // ------------- // ---- TRDFASP2D ---- - std::shared_ptr<CbmTrdUnpackConfigFasp2D> trdfasp2dconfig = nullptr; + std::shared_ptr<CbmTrdUnpackFaspConfig> trdfasp2dconfig = nullptr; if ("" != trdsetuptag) { - trdfasp2dconfig = std::make_shared<CbmTrdUnpackConfigFasp2D>(trdsetuptag.Data(), 3); + trdfasp2dconfig = std::make_shared<CbmTrdUnpackFaspConfig>(trdsetuptag.Data(), 3); if (trdfasp2dconfig) { // trdfasp2dconfig->SetDebugState(); trdfasp2dconfig->SetDoWriteOutput(); diff --git a/MQ/mcbm/CbmDeviceUnpack.h b/MQ/mcbm/CbmDeviceUnpack.h index 24a17c916b..3b585a3ef5 100644 --- a/MQ/mcbm/CbmDeviceUnpack.h +++ b/MQ/mcbm/CbmDeviceUnpack.h @@ -32,7 +32,7 @@ class CbmPsdUnpackConfig; class CbmRichUnpackConfig; class CbmStsUnpackConfig; class CbmTofUnpackConfig; -class CbmTrdUnpackConfigFasp2D; +class CbmTrdUnpackFaspConfig; class CbmTrdUnpackConfig; class TimesliceMetaData; @@ -59,7 +59,7 @@ protected: void SetUnpackConfig(std::shared_ptr<CbmTrdUnpackConfig> config) { fTrd1DConfig = config; } /** @brief Set the Trd2D Unpack Config @param config */ - void SetUnpackConfig(std::shared_ptr<CbmTrdUnpackConfigFasp2D> config) { fTrd2DConfig = config; } + void SetUnpackConfig(std::shared_ptr<CbmTrdUnpackFaspConfig> config) { fTrd2DConfig = config; } /** @brief Set the Rich Unpack Config @param config */ void SetUnpackConfig(std::shared_ptr<CbmRichUnpackConfig> config) { fRichConfig = config; } @@ -128,7 +128,7 @@ private: /// Configuration of the unpackers. Provides the configured algorithm std::shared_ptr<CbmStsUnpackConfig> fStsConfig = nullptr; - std::shared_ptr<CbmTrdUnpackConfigFasp2D> fTrd2DConfig = nullptr; + std::shared_ptr<CbmTrdUnpackFaspConfig> fTrd2DConfig = nullptr; std::shared_ptr<CbmTrdUnpackConfig> fTrd1DConfig = nullptr; std::shared_ptr<CbmTofUnpackConfig> fTofConfig = nullptr; std::shared_ptr<CbmRichUnpackConfig> fRichConfig = nullptr; diff --git a/reco/detectors/trd/CMakeLists.txt b/reco/detectors/trd/CMakeLists.txt index b822da9fc2..e9a9fc0322 100644 --- a/reco/detectors/trd/CMakeLists.txt +++ b/reco/detectors/trd/CMakeLists.txt @@ -61,8 +61,8 @@ unpack/CbmTrdUnpackAlgoR.cxx unpack/CbmTrdUnpackAlgoLegacy2020R.cxx unpack/CbmTrdUnpackMonitor.cxx -unpack/CbmTrdUnpackAlgoFasp2D.cxx -unpack/CbmTrdUnpackConfigFasp2D.cxx +unpack/CbmTrdUnpackFaspAlgo.cxx +unpack/CbmTrdUnpackFaspConfig.cxx qa/CbmTrdClusterizerFastQa.cxx qa/CbmTrdHitDensityQa.cxx diff --git a/reco/detectors/trd/CbmTrdRecoLinkDef.h b/reco/detectors/trd/CbmTrdRecoLinkDef.h index 31652af862..1744870f32 100644 --- a/reco/detectors/trd/CbmTrdRecoLinkDef.h +++ b/reco/detectors/trd/CbmTrdRecoLinkDef.h @@ -35,8 +35,8 @@ #pragma link C++ class CbmTrdUnpackConfig + ; #pragma link C++ class CbmTrdUnpackMonitor + ; -#pragma link C++ class CbmTrdUnpackAlgoFasp2D + ; -#pragma link C++ class CbmTrdUnpackConfigFasp2D + ; +#pragma link C++ class CbmTrdUnpackFaspAlgo + ; +#pragma link C++ class CbmTrdUnpackFaspConfig + ; #pragma link C++ class CbmTrdElectronsTrainAnn + ; #pragma link C++ class CbmTrdSetTracksPidWkn + ; diff --git a/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.cxx b/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.cxx new file mode 100644 index 0000000000..33fe4a095d --- /dev/null +++ b/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.cxx @@ -0,0 +1,410 @@ +/* Copyright (C) 2021 Goethe-University Frankfurt, Frankfurt + SPDX-License-Identifier: GPL-3.0-only + Authors: Pascal Raisig [committer], Alexandru Bercuci */ + + +#include "CbmTrdUnpackFaspAlgo.h" + +#include "CbmTrdDigi.h" +#include "CbmTrdParFasp.h" +#include "CbmTrdParModDigi.h" +#include "CbmTrdParSetDigi.h" +#include "CbmTrdParSetGain.h" +#include "CbmTrdParSetGas.h" +#include "CbmTrdParSpadic.h" + +#include <FairParAsciiFileIo.h> +#include <FairParGenericSet.h> +#include <FairParamList.h> +#include <FairRuntimeDb.h> +#include <FairTask.h> +#include <Logger.h> + +#include <Rtypes.h> +#include <RtypesCore.h> + +#include <boost/format.hpp> + +#define VERBOSE 0 + +using namespace std; + +CbmTrdUnpackFaspAlgo::CbmTrdUnpackFaspAlgo() : CbmRecoUnpackAlgo("CbmTrdUnpackFaspAlgo"), fModuleId(), fAsicPar() +{ + memset(fTime, 0, NCRI * sizeof(ULong64_t)); +} + +//_________________________________________________________________________________ +CbmTrdUnpackFaspAlgo::~CbmTrdUnpackFaspAlgo() {} + +//_________________________________________________________________________________ +Bool_t CbmTrdUnpackFaspAlgo::initParSet(FairParGenericSet* parset) +{ + FairParamList parList; + Int_t nModules(0); + if (strcmp(parset->ClassName(), "CbmTrdParSetAsic") == 0) { + CbmTrdParSetAsic* setPar = static_cast<CbmTrdParSetAsic*>(parset); + for (auto did : fModuleId) { + const CbmTrdParSetAsic* setDet = static_cast<const CbmTrdParSetAsic*>(setPar->GetModuleSet(did)); + if (!setDet) continue; + if (setDet->GetAsicType() != Int_t(CbmTrdDigi::eCbmTrdAsicType::kFASP)) continue; + nModules++; + std::vector<Int_t> a; + setDet->GetAsicAddresses(&a); + for (auto add : a) { + CbmTrdParAsic* asic = (CbmTrdParAsic*) setDet->GetModulePar(add); + if (asic->IsA() == CbmTrdParSpadic::Class()) continue; + fAsicPar.addParam(asic); + if (VERBOSE) asic->Print(); + } + } + // setPar->printParams(); + LOG(info) << GetName() << "::initParSet - for container " << parset->ClassName() << " modules " << nModules + << " asics " << fAsicPar.GetNrOfModules(); + } + else if (strcmp(parset->ClassName(), "CbmTrdParSetDigi") == 0) { + fDigiSet = static_cast<CbmTrdParSetDigi*>(parset); + map<Int_t, CbmTrdParMod*> digiPar = fDigiSet->GetModuleMap(); + for (auto digi : digiPar) + fModuleId.emplace_back(digi.first); + // setPar->printParams(); + LOG(info) << GetName() << "::initParSet - for container " << parset->ClassName() << " modules " << fModuleId.size(); + } + else if (strcmp(parset->ClassName(), "CbmTrdParSetGas") == 0) { + CbmTrdParSetGas* setPar = static_cast<CbmTrdParSetGas*>(parset); + setPar->printParams(); + nModules = setPar->GetNrOfModules(); + } + else if (strcmp(parset->ClassName(), "CbmTrdParSetGain") == 0) { + CbmTrdParSetGain* setPar = static_cast<CbmTrdParSetGain*>(parset); + setPar->printParams(); + nModules = setPar->GetNrOfModules(); + } + else { + LOG(error) << "Parameter set " << parset->ClassName() << " not known. Skip."; + return kFALSE; + } + return kTRUE; +} + +//_________________________________________________________________________________ +std::vector<std::pair<std::string, std::shared_ptr<FairParGenericSet>>>* +CbmTrdUnpackFaspAlgo::GetParContainerRequest(std::string geoTag, std::uint32_t runId) +{ + LOG(info) << GetName() << "::GetParContainerRequest - for container " << geoTag.data() << " run " << runId << " " + << fParFilesBasePath.data(); + + // Basepath for default Trd parameter sets (those connected to a geoTag) + std::string basepath = Form("%s/trd_%s", fParFilesBasePath.data(), geoTag.data()); + std::string temppath = ""; + + // Digest the runId information in case of runId = 0 we use the default fall back + std::string runpath = ""; + if (runId != 0) { runpath = ".run" + std::to_string(runId); } + + temppath = basepath + runpath + ".digi" + ".par"; + fParContVec.emplace_back(std::make_pair(temppath, std::make_shared<CbmTrdParSetDigi>())); + temppath = basepath + runpath + ".asic" + ".par"; + fParContVec.emplace_back(std::make_pair(temppath, std::make_shared<CbmTrdParSetAsic>())); + // temppath = basepath + runpath + ".gas" + ".par"; + // fParContVec.emplace_back(std::make_pair(temppath, std::make_shared<CbmTrdParSetGas>())); + // temppath = basepath + runpath + ".gain" + ".par"; + // fParContVec.emplace_back(std::make_pair(temppath, std::make_shared<CbmTrdParSetGain>())); + + return &fParContVec; +} + +//_________________________________________________________________________________ +void CbmTrdUnpackFaspAlgo::SetAsicMapping(const std::map<uint32_t, uint8_t[NFASPMOD]>& asicMap) +{ + if (!fFaspMap) fFaspMap = new std::map<uint32_t, uint8_t[NFASPMOD]>(asicMap); + else { + delete fFaspMap; + fFaspMap = new std::map<uint32_t, uint8_t[NFASPMOD]>(asicMap); + } +} + +//_________________________________________________________________________________ +void CbmTrdUnpackFaspAlgo::PrintAsicMapping() +{ + if (!fFaspMap) { + LOG(info) << GetName() << "No asic mapping loaded."; + return; + } + LOG(info) << GetName() << "Fasp Asic mapping on modules:"; + for (auto imod : (*fFaspMap)) { + printf("Mod [%6d] : ", imod.first); + for (int ifasp(0); ifasp < NFASPMOD; ifasp++) { + int jfasp = imod.second[ifasp]; + printf("%2d ", (jfasp == 0xff ? -1 : jfasp)); + } + printf("\n"); + } +} + +//_________________________________________________________________________________ +CbmTrdUnpackFaspAlgo::CbmTrdFaspMessageType CbmTrdUnpackFaspAlgo::mess_type(uint32_t wd) +{ + if ((wd >> kMessCh) & 0x1) return kData; + return kEpoch; +} + +//_________________________________________________________________________________ +void CbmTrdUnpackFaspAlgo::mess_readDW(uint32_t w, CbmTrdFaspContent* mess) +{ + uint32_t wd(w), shift(0); + mess->ch = wd & 0xf; + shift += Int_t(kMessCh); + mess->type = (wd >> shift) & 0x1; + shift += Int_t(kMessType); + mess->tlab = (wd >> shift) & 0x7f; + shift += Int_t(kMessTlab); + mess->data = (wd >> shift) & 0x3fff; + shift += Int_t(kMessData); + mess->fasp = (wd >> shift) & 0x3f; + + printf("DBG :: "); + mess_prt(mess); +} + +//_________________________________________________________________________________ +void CbmTrdUnpackFaspAlgo::mess_readEW(uint32_t w, CbmTrdFaspContent* mess) +{ + uint32_t wd(w), shift(0); + mess->ch = wd & 0xf; + shift += Int_t(kMessCh); + mess->type = (wd >> shift) & 0x1; + shift += Int_t(kMessType); + mess->epoch = (wd >> shift) & 0x1fffff; + shift += Int_t(kMessEpoch); + mess->cri = (wd >> shift) & 0x3f; + printf("DBG :: "); + mess_prt(mess); +} + +//_________________________________________________________________________________ +void CbmTrdUnpackFaspAlgo::mess_prt(CbmTrdFaspContent* mess) +{ + if (mess->type == kData) + cout << boost::format(" DATA : fasp_id=%02d ch_id=%02d tclk=%03d data=%4d\n") + % static_cast<unsigned int>(mess->fasp) % static_cast<unsigned int>(mess->ch) + % static_cast<unsigned int>(mess->tlab) % static_cast<unsigned int>(mess->data); + else + cout << boost::format(" EPOCH: cri_id=%02d ch_id=%02d epoch=%05d\n") % static_cast<unsigned int>(mess->cri) + % static_cast<unsigned int>(mess->ch) % static_cast<unsigned int>(mess->epoch); +} + +//_________________________________________________________________________________ +bool CbmTrdUnpackFaspAlgo::pushDigis(std::vector<CbmTrdUnpackFaspAlgo::CbmTrdFaspContent*> messes) +{ + UChar_t lFasp(0xff); + UShort_t lchR, lchT; + Double_t r, t; + Int_t dt, dtime, ch, pad, row; + ULong64_t tlab; + CbmTrdParFasp* faspPar(nullptr); + const CbmTrdParFaspChannel* chCalib(nullptr); + CbmTrdParModDigi* digiPar(nullptr); + vector<CbmTrdDigi*> digis; + for (auto imess : messes) { + if (lFasp == 0xff) { + lFasp = messes[0]->fasp; + // link data to the position on the padplane + if (!(faspPar = (CbmTrdParFasp*) fAsicPar.GetAsicPar(imess->cri * 1000 + lFasp))) { + LOG(error) << GetName() << "::pushDigis - Par for FASP " << (int) lFasp << " in module " << imess->cri + << " missing. Skip."; + return false; + } + if (!(digiPar = (CbmTrdParModDigi*) fDigiSet->GetModulePar(imess->cri))) { + LOG(error) << GetName() << "::pushDigis - DIGI par for module " << imess->cri << " missing. Skip."; + return false; + } + if (VERBOSE) faspPar->Print(); + pad = faspPar->GetChannelAddress(imess->ch); + chCalib = faspPar->GetChannel(imess->ch); + ch = 2 * pad + chCalib->HasPairingR(); + row = digiPar->GetPadRow(pad); + if (VERBOSE) + printf("fasp[%2d] ch[%4d / %2d] pad[%4d] row[%2d] col[%2d] tilt[%d]\n", lFasp, ch, imess->ch, pad, row, + digiPar->GetPadColumn(pad), chCalib->HasPairingT()); + } + + if (VERBOSE) mess_prt(imess); + + lchR = 0; + lchT = 0; + chCalib = faspPar->GetChannel(imess->ch); + if (chCalib->HasPairingR()) lchR = imess->data; + else + lchT = imess->data; + pad = faspPar->GetChannelAddress(imess->ch); + + bool use(false); + for (auto id : digis) { + if (id->GetAddressChannel() != pad) continue; + dtime = id->GetTimeDAQ() - imess->tlab; + if (TMath::Abs(dtime) < 5) { + r = id->GetCharge(t, dt); + if (lchR && !int(r)) { + id->SetCharge(t, lchR, -dtime); + use = true; + break; + } + else if (lchT && !int(t)) { + tlab = id->GetTimeDAQ(); + id->SetCharge(lchT, r, +dtime); + id->SetTimeDAQ(ULong64_t(tlab - dtime)); + use = true; + break; + } + } + } + + if (!use) { + CbmTrdDigi* digi = new CbmTrdDigi(pad, lchT, lchR, imess->tlab); + digi->SetAddressModule(imess->cri); + digis.push_back(digi); + } + delete imess; + } + + // push finalized digits to the next level + for (vector<CbmTrdDigi*>::iterator id = digis.begin(); id != digis.end(); id++) { + (*id)->SetTimeDAQ(fTime[0] + (*id)->GetTimeDAQ()); + fOutputVec.emplace_back(*std::move(*id)); + if (VERBOSE) cout << (*id)->ToString(); + } + + digis.clear(); + messes.clear(); + + return true; +} + +// ---- unpack ---- +bool CbmTrdUnpackFaspAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp, UInt_t imslice) +{ + if (VERBOSE) printf("CbmTrdUnpackFaspAlgo::unpack 0x%04x %d\n", icomp, imslice); + //LOG(info) << "Component " << icomp << " connected to config CbmTrdUnpackConfig2D. Slice "<<imslice; + + uint32_t mod_id = 5; + bool unpackOk = true; + //Double_t fdMsSizeInNs = 1.28e6; + + auto msdesc = ts->descriptor(icomp, imslice); + // Cast required to silence a warning on macos (there a uint64_t is a llu) + if (VERBOSE) printf("time start %lu\n", static_cast<size_t>(msdesc.idx)); + // define time wrt start of time slice in TRD/FASP clks [80 MHz] + fTime[0] = ULong64_t((msdesc.idx - fTsStartTime - fSystemTimeOffset) / 12.5); + + // Get the µslice size in bytes to calculate the number of completed words + auto mssize = msdesc.size; + + // Get the number of complete words in the input MS buffer. + std::uint32_t nwords = mssize / 4; //fBytesPerWord; + + const auto mspointer = ts->content(icomp, imslice); + + // We have 32 bit spadic frames in this readout version + const auto mscontent = reinterpret_cast<const size_t*>(mspointer); + + const uint32_t* wd = reinterpret_cast<const uint32_t*>(mscontent); + + + UChar_t lFaspOld(0xff); + vector<CbmTrdFaspContent*> vDigi; + CbmTrdFaspContent* mess(nullptr); + for (uint64_t j = 0; j < nwords; j++, wd++) { + // // Select the appropriate conversion type of the word according to the message type + // switch(mess_type(*wd)){ + // case CbmTrdFaspMessageType::kData: + // mess_readDW(*wd, &mess); + // break; + // case CbmTrdFaspMessageType::kEpoch: + // mess_readEW(*wd, &mess); + // break; + // } + uint32_t w = *wd; + uint8_t ch_id = w & 0xf; + uint8_t isaux = (w >> 4) & 0x1; + uint8_t slice = (w >> 5) & 0x7f; + uint16_t data = (w >> 12) & 0x3fff; + uint32_t epoch = (w >> 5) & 0x1fffff; + uint8_t fasp_id = (w >> 26) & 0x3f; + // std::cout<<"fasp_id="<<static_cast<unsigned int>(fasp_id)<<" ch_id="<<static_cast<unsigned int>(ch_id)<<" isaux="<<static_cast<unsigned int>(isaux)<<std::endl; + if (isaux) { + if (!ch_id) { + if (VERBOSE) + cout << boost::format(" EE : fasp_id=%02d ch_id=%02d epoch=%03d\n") % static_cast<unsigned int>(fasp_id) + % static_cast<unsigned int>(ch_id) % static_cast<unsigned int>(epoch); + + if (vDigi.size()) { pushDigis(vDigi); } + vDigi.clear(); + lFaspOld = 0xff; + + fTime[fasp_id] += 128; + } + else if (ch_id == 1) { + if (VERBOSE) cout << boost::format(" PAUSE: fasp_id=%02d\n") % static_cast<unsigned int>(fasp_id); + } + } + else { + if (fFaspMap) fasp_id = ((*fFaspMap)[mod_id])[fasp_id]; + + if (lFaspOld != fasp_id) { + // push + if (vDigi.size()) { pushDigis(vDigi); } + vDigi.clear(); + lFaspOld = fasp_id; + } + if (data & 0x1) { + LOG(warn) << GetName() << "::unpack - Data corrupted : detect end bit set."; + continue; + } + if (VERBOSE) + cout << boost::format(" DD : fasp_id=%02d ch_id=%02d slice=%03d data=%4d\n") + % static_cast<unsigned int>(fasp_id) % static_cast<unsigned int>(ch_id) + % static_cast<unsigned int>(slice) % static_cast<unsigned int>(data >> 1); + if (data & 0x2000) { + LOG(debug) << GetName() << "::unpack - Self-triggered data."; + data &= 0x1fff; + } + mess = new CbmTrdFaspContent; + mess->ch = ch_id; + mess->type = 1; + mess->tlab = slice; + mess->data = data >> 1; + mess->fasp = lFaspOld; + mess->cri = mod_id; + vDigi.push_back(mess); + } + //prt_wd(*wd); + } + return unpackOk; +} + +//_____________________________________________________________ +void CbmTrdUnpackFaspAlgo::prt_wd(uint32_t w) +{ + // out<<w<<std::endl; + uint8_t ch_id = w & 0xf; + uint8_t isaux = (w >> 4) & 0x1; + uint8_t slice = (w >> 5) & 0x7f; + uint16_t data = (w >> 12) & 0x3fff; + uint32_t epoch = (w >> 5) & 0x1fffff; + uint8_t fasp_id = (w >> 26) & 0x3f; + // out<<"fasp_id="<<static_cast<unsigned int>(fasp_id)<<" ch_id="<<static_cast<unsigned int>(ch_id)<<" isaux="<<static_cast<unsigned int>(isaux)<<std::endl; + if (isaux) { + if (!ch_id) { cout << boost::format("EE: %08d\n") % epoch; } + else if (ch_id == 1) { + cout << boost::format(" PAUSE: fasp_id=%02d\n") % static_cast<unsigned int>(fasp_id); + } + } + else { + cout << boost::format(" DATA: w=%08x fasp_id=%02d ch_id=%02d slice=%03d data=%04d\n") % w + % static_cast<unsigned int>(fasp_id) % static_cast<unsigned int>(ch_id) % static_cast<unsigned int>(slice) + % static_cast<unsigned int>(data >> 1); + } +} + +ClassImp(CbmTrdUnpackFaspAlgo) diff --git a/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.h b/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.h new file mode 100644 index 0000000000..64e9fd1261 --- /dev/null +++ b/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.h @@ -0,0 +1,191 @@ +/* Copyright (C) 2021 Goethe-University Frankfurt, Frankfurt + SPDX-License-Identifier: GPL-3.0-only + Authors: Pascal Raisig [committer], Alexandru Bercuci */ + +/** + * @file CbmTrdUnpackFaspAlgo.h + * @author Alexandru Bercuci + * @author Pascal Raisig (praisig@ikf.uni-frankfurt.de) + * @brief Trd FASP unpacking algorithm + * @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 CbmTrdUnpackFaspAlgo_H +#define CbmTrdUnpackFaspAlgo_H + +#include "CbmRecoUnpackAlgo.tmpl" +#include "CbmTrdDigi.h" +#include "CbmTrdParFasp.h" +#include "CbmTrdParSetAsic.h" + +#include "Timeslice.hpp" // timeslice + +#include <Rtypes.h> // for types +#include <RtypesCore.h> + +#include <cstddef> +#include <cstdint> +#include <memory> +#include <utility> + +#define NCRI 40 // no of CRI in the system (1/TRD-2D_FASP module) +#define NCOLS 8 // no of cols / FASP + +class CbmTrdParSetDigi; +class CbmTrdUnpackFaspAlgo : public CbmRecoUnpackAlgo<CbmTrdDigi> { +public: + /** @brief Bytes per FASP frame stored in the microslices (32 bits words) + * - DATA WORD - + * ffff.ffdd dddd.dddd dddd.tttt ttta.cccc + * f - FASP id + * d - ADC signal + * t - time label inside epoch + * a - word type (1) + * c - channel id + * - EPOCH WORD - + * ffff.fftt tttt.tttt tttt.tttt ttta.cccc + * f - FASP id + * t - epoch index + * a - word type (0) + * c - channel id + */ + enum CbmTrdFaspMessage + { + kMessCh = 4, + kMessType = 1, + kMessTlab = 7, + kMessData = 14, + kMessFasp = 6, + kMessEpoch = 21 + }; + enum CbmTrdFaspMessageType + { + kEpoch = 0, + kData + }; + + /** @brief Create the Cbm Trd Unpack AlgoBase object */ + CbmTrdUnpackFaspAlgo(); + + /** @brief Destroy the Cbm Trd Unpack Task object */ + virtual ~CbmTrdUnpackFaspAlgo(); + + /** @brief Copy constructor - not implemented **/ + CbmTrdUnpackFaspAlgo(const CbmTrdUnpackFaspAlgo&) = delete; + + /** @brief Assignment operator - not implemented **/ + CbmTrdUnpackFaspAlgo& operator=(const CbmTrdUnpackFaspAlgo&) = delete; + + + /** @brief Data structure for unpacking the FASP word */ + struct CbmTrdFaspContent { + uint8_t ch; + uint8_t type; + uint8_t tlab; + uint16_t data; + uint32_t epoch; + uint8_t fasp; + uint8_t cri; + }; + + /** + * @brief Get the requested parameter containers. + * 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); + + /** + * @brief Introduce fasp index mapping + */ + void SetAsicMapping(const std::map<uint32_t, uint8_t[NFASPMOD]>& map); + void PrintAsicMapping(); + +protected: + /** @brief Get message type from the FASP word */ + CbmTrdFaspMessageType mess_type(uint32_t wd); + /** @brief Convert the FASP word into a DATA message */ + void mess_readDW(uint32_t wd, CbmTrdFaspContent* mess); + /** @brief Convert the FASP word into a EPOCH message */ + void mess_readEW(uint32_t wd, CbmTrdFaspContent* mess); + /** @brief Print FASP message */ + void mess_prt(CbmTrdFaspContent* mess); + bool pushDigis(std::vector<CbmTrdUnpackFaspAlgo::CbmTrdFaspContent*> digis); + ULong64_t fTime[NCRI]; + + /** @brief Finish function for this algorithm base clase */ + void finish() { return; } + + /** + * @brief Additional initialisation function for all BaseR derived algorithms. + * + * @return Bool_t initOk + */ + virtual Bool_t init() { return kTRUE; } + + // Initialise par set, the base function handles the casting to distribute the pointers to their explicit functions + + /** + * @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 Unpack a given microslice. + * + * @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); + + // Constants + /** @brief Bytes per FASP frame stored in the microslices (32 bits words) + * - DATA WORD - + * ffff.ffdd dddd.dddd dddd.tttt ttta.cccc + * f - FASP id + * d - ADC signal + * t - time label inside epoch + * a - word type (1) + * c - channel id + * - EPOCH WORD - + * ffff.fftt tttt.tttt tttt.tttt ttta.cccc + * f - FASP id + * t - epoch index + * a - word type (0) + * c - channel id + */ + static const std::uint8_t fBytesPerWord = 4; + +private: + void prt_wd(uint32_t w); + std::map<uint32_t, uint8_t[NFASPMOD]>* fFaspMap = nullptr; + std::vector<Int_t> fModuleId; + CbmTrdParSetAsic fAsicPar; + CbmTrdParSetDigi* fDigiSet = nullptr; + + ClassDef(CbmTrdUnpackFaspAlgo, 2) // unpack FASP read-out detectors +}; + +#endif // CbmTrdUnpackFaspAlgo_H diff --git a/reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.cxx b/reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.cxx new file mode 100644 index 0000000000..6d071530e3 --- /dev/null +++ b/reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.cxx @@ -0,0 +1,50 @@ +/* Copyright (C) 2021 Goethe-University Frankfurt, Frankfurt + SPDX-License-Identifier: GPL-3.0-only + Authors: Pascal Raisig [committer], Alexandru Bercuci*/ + +#include "CbmTrdUnpackFaspConfig.h" + +CbmTrdUnpackFaspConfig::CbmTrdUnpackFaspConfig(std::string detGeoSetupTag, UInt_t runid) + : CbmRecoUnpackConfig("CbmTrdUnpackFaspConfig", detGeoSetupTag, runid) + , fFaspMap() +{ +} + +CbmTrdUnpackFaspConfig::~CbmTrdUnpackFaspConfig() {} + +// ---- Init ---- + +// ---- chooseAlgo ---- +std::shared_ptr<CbmTrdUnpackFaspAlgo> CbmTrdUnpackFaspConfig::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<CbmTrdUnpackFaspAlgo>(); + 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; +} + +//_____________________________________________________________________ +void CbmTrdUnpackFaspConfig::InitAlgo() +{ + if (fDoLog) LOG(info) << fName << "::InitAlgo - SetFaspMapping"; + fAlgo->SetAsicMapping(fFaspMap); + /*if (fDoLog) */ fAlgo->PrintAsicMapping(); + + // Now we have all information required to initialise the algorithm + fAlgo->Init(); +} + +//_____________________________________________________________________ +void CbmTrdUnpackFaspConfig::SetFaspMapping(int modAddress, uint8_t faspMap[NFASPMOD]) +{ + memcpy(fFaspMap[modAddress], faspMap, NFASPMOD * sizeof(uint8_t)); +} + +ClassImp(CbmTrdUnpackFaspConfig) diff --git a/reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.h b/reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.h new file mode 100644 index 0000000000..013a5d6571 --- /dev/null +++ b/reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.h @@ -0,0 +1,88 @@ +/* Copyright (C) 2021 Goethe-University Frankfurt, Frankfurt + SPDX-License-Identifier: GPL-3.0-only + Authors: Pascal Raisig [committer], Alexandru Bercuci*/ + +/** + * @file CbmTrdUnpackFaspConfig.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 CbmTrdUnpackFaspConfig_H +#define CbmTrdUnpackFaspConfig_H + + +#include "CbmRecoUnpackConfig.tmpl" +#include "CbmTrdDigi.h" +#include "CbmTrdParFasp.h" +#include "CbmTrdUnpackFaspAlgo.h" + +#include <FairLogger.h> +#include <Logger.h> + +#include <Rtypes.h> +#include <RtypesCore.h> + +#include <cstddef> +#include <cstdint> +#include <map> +#include <memory> +#include <vector> + +class CbmTrdUnpackFaspConfig : public CbmRecoUnpackConfig<CbmTrdUnpackFaspAlgo, CbmTrdDigi> { + +public: + /** + * @brief Create the Cbm Trd 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... + */ + CbmTrdUnpackFaspConfig(std::string detGeoSetupTag, UInt_t runid = 0); + + /** + * @brief Destroy the Cbm Trd Unpack Task object + * + */ + virtual ~CbmTrdUnpackFaspConfig(); + + /** @brief Copy constructor - not implemented **/ + CbmTrdUnpackFaspConfig(const CbmTrdUnpackFaspConfig&) = delete; + + /** @brief Assignment operator - not implemented **/ + CbmTrdUnpackFaspConfig& operator=(const CbmTrdUnpackFaspConfig&) = delete; + + /** + * @brief Initialize the algorithm, include all calibration for Trd FASP. + */ + void InitAlgo(); + + /** @brief define fasp mapping for each module + * @param modAddress module address according to geometry + * @param faspMap mapped ids of FASP ASICs for module + */ + void SetFaspMapping(int modAddress, uint8_t faspMap[NFASPMOD]); + +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<CbmTrdUnpackFaspAlgo> chooseAlgo(); + +private: + std::map<uint32_t, uint8_t[NFASPMOD]> fFaspMap; ///> DAQ packing of FASP id + + ClassDef(CbmTrdUnpackFaspConfig, 4) +}; + +#endif // CbmTrdUnpackFaspConfig_H diff --git a/reco/steer/CbmRecoUnpack.h b/reco/steer/CbmRecoUnpack.h index 0ae07e4257..0e9840c314 100644 --- a/reco/steer/CbmRecoUnpack.h +++ b/reco/steer/CbmRecoUnpack.h @@ -17,7 +17,7 @@ #include "CbmStsUnpackConfig.h" #include "CbmTofUnpackConfig.h" #include "CbmTrdUnpackConfig.h" -#include "CbmTrdUnpackConfigFasp2D.h" +#include "CbmTrdUnpackFaspConfig.h" #include "CbmTsEventHeader.h" #include <MicrosliceDescriptor.hpp> @@ -121,7 +121,7 @@ public: void SetUnpackConfig(std::shared_ptr<CbmTrdUnpackConfig> config) { fTrd1DConfig = config; } /** @brief Set the Trd2D Unpack Config @param config */ - void SetUnpackConfig(std::shared_ptr<CbmTrdUnpackConfigFasp2D> config) { fTrd2DConfig = config; } + void SetUnpackConfig(std::shared_ptr<CbmTrdUnpackFaspConfig> config) { fTrd2DConfig = config; } /** @brief Trigger the unpacking procedure **/ void Unpack(std::unique_ptr<fles::Timeslice> ts); @@ -351,7 +351,7 @@ private: std::shared_ptr<CbmTrdUnpackConfig> fTrd1DConfig = nullptr; //! /** @brief Configuration of the Trd unpacker. Provides the configured algorithm */ - std::shared_ptr<CbmTrdUnpackConfigFasp2D> fTrd2DConfig = nullptr; //! + std::shared_ptr<CbmTrdUnpackFaspConfig> fTrd2DConfig = nullptr; //! /** @brief Pointer to the Timeslice start time used to write it to the output tree @remark since we hand this to the FairRootManager it also wants to delete it and we do not have to take care of deletion */ CbmTsEventHeader* fCbmTsEventHeader = nullptr; -- GitLab