diff --git a/macro/run/run_unpack_tsa.C b/macro/run/run_unpack_tsa.C index 32e4e157333fad26cfc3f64afe911417edcb48d6..aa0f262f347da5d07333826df6faefa3ca1c0bd3 100644 --- a/macro/run/run_unpack_tsa.C +++ b/macro/run/run_unpack_tsa.C @@ -81,6 +81,15 @@ void run_unpack_tsa(std::string infile = "test.tsa", UInt_t runid = 0, const cha psdconfig->SetParFilesBasePath(parfilesbasepathPsd); // ------------- + // ---- RICH ---- + auto richconfig = std::make_shared<CbmRichUnpackConfig>("", runid); + // psdconfig->SetDebugState(); + richconfig->SetDoWriteOutput(); + // psdconfig->SetDoWriteOptOutA("CbmPsdDsp"); + std::string parfilesbasepathRich = Form("%s/macro/beamtime/mcbm2021/", srcDir.Data()); + richconfig->SetParFilesBasePath(parfilesbasepathRich); + // ------------- + // ---- TRD ---- TString trdsetuptag = ""; cbmsetup->GetGeoTag(ECbmModuleId::kTrd, trdsetuptag); @@ -113,8 +122,9 @@ void run_unpack_tsa(std::string infile = "test.tsa", UInt_t runid = 0, const cha // ----- CbmSourceTsArchive ------------------------------------------- auto source = new CbmSourceTsArchive(infile.data()); auto unpack = source->GetRecoUnpack(); - unpack->SetUnpackConfig(trdconfig); unpack->SetUnpackConfig(psdconfig); + unpack->SetUnpackConfig(richconfig); + unpack->SetUnpackConfig(trdconfig); // ------------------------------------------------------------------------ diff --git a/reco/detectors/psd/unpack/CbmPsdUnpackAlgo.cxx b/reco/detectors/psd/unpack/CbmPsdUnpackAlgo.cxx index 6655db4a17a36a3bca4505a7ca170a76fcd42704..4dd7d2607dc7a6e4c7f3fbdb9985010728aada60 100644 --- a/reco/detectors/psd/unpack/CbmPsdUnpackAlgo.cxx +++ b/reco/detectors/psd/unpack/CbmPsdUnpackAlgo.cxx @@ -11,6 +11,7 @@ #include <Rtypes.h> #include <RtypesCore.h> +#include <cstdint> #include <numeric> #include "../../core/detectors/psd/PronyFitter.h" @@ -143,10 +144,9 @@ bool CbmPsdUnpackAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp, UI const uint8_t* msContent = reinterpret_cast<const uint8_t*>(ts->content(icomp, imslice)); uint32_t uSize = msDescriptor.size; - auto msidx = msDescriptor.idx; + auto mstime = msDescriptor.idx; - auto mstime = static_cast<double>(msidx); - LOG(debug4) << "Microslice: " << msidx << " from EqId " << std::hex << eqid << std::dec << " has size: " << uSize; + LOG(debug4) << "Microslice: " << mstime << " from EqId " << std::hex << eqid << std::dec << " has size: " << uSize; if (0 == fvbMaskedComponents.size()) fvbMaskedComponents.resize(ts->num_components(), kFALSE); @@ -203,7 +203,7 @@ bool CbmPsdUnpackAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp, UI while (PsdReader.GetTotalGbtWordsRead() < uNbMessages) { int ReadResult = PsdReader.ReadMs(); if (fair::Logger::Logging(fair::Severity::debug)) { - printf("\nMicroslice idx: %lu\n", msidx); + printf("\nMicroslice idx: %lu\n", mstime); PsdReader.PrintOut(); /*PsdReader.PrintSaveBuff();*/ } if (ReadResult == 0) { @@ -228,10 +228,8 @@ bool CbmPsdUnpackAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp, UI } UInt_t uChanUId = fviPsdChUId[uHitChannel]; //unique ID - auto dTime = static_cast<double>(PsdReader.VectPackHdr.at(hit_iter).uAdcTime * 12.5); - dTime -= fdTimeOffsetNs; // Subtract system-side offset - dTime += msidx; // Add the microslice start time - dTime -= fTsStartTime; // Get the time relative to the TS start time + auto dTime = dMsRelativeTime + (double) PsdReader.VectPackHdr.at(hit_iter).uAdcTime * 12.5 - fdTimeOffsetNs; + Double_t dEdep = (double) PsdReader.VectHitHdr.at(hit_iter).uSignalCharge / getMipCalibration(uHitChannel); /// Energy deposition from FPGA [MeV] @@ -291,7 +289,7 @@ bool CbmPsdUnpackAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp, UI uFitWfm = Pfitter.GetFitWfm(); } - CbmPsdDsp dsp = CbmPsdDsp(uChanUId, dTime, dEdep, uZL, dAccum, dAdcTime, + CbmPsdDsp dsp = CbmPsdDsp(uChanUId, dTime, fTsStartTime, dEdep, uZL, dAccum, dAdcTime, dEdepWfm, dAmpl, uMinimum, uTimeMax, uWfm, @@ -300,6 +298,8 @@ bool CbmPsdUnpackAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp, UI // Create the actual digi and move it to the output vector makeDigi(dsp); + if (dTime < prev_hit_time) printf("negative time btw hits! %f after %f \n", dTime, prev_hit_time); + prev_hit_time = dTime; } // for (uint64_t hit_iter = 0; hit_iter < PsdReader.VectHitHdr.size(); hit_iter++) { diff --git a/reco/detectors/rich/CMakeLists.txt b/reco/detectors/rich/CMakeLists.txt index b45f03e2a2005e85dfd173fb0dd9012cda9eb93f..684f371057b99cebde6c29ed16ffcc4aa98f6d7e 100644 --- a/reco/detectors/rich/CMakeLists.txt +++ b/reco/detectors/rich/CMakeLists.txt @@ -132,7 +132,7 @@ set(LINKDEF CbmRichRecoLinkDef.h) Set(LIBRARY_NAME CbmRichReco) Set(DEPENDENCIES KF L1 CbmRichBase CbmRecoBase CbmBase CbmData Base MLP boost_regex Gdml - fles_ipc # for unpacker + # fles_ipc # for unpacker ) GENERATE_LIBRARY() diff --git a/reco/detectors/rich/unpack/CbmRichUnpackAlgo.cxx b/reco/detectors/rich/unpack/CbmRichUnpackAlgo.cxx index 55b597878ad802837ebd95089053ea02cf72b1d5..ca31db39bdaa8d509ab0df71d20dbd13c04e67b2 100644 --- a/reco/detectors/rich/unpack/CbmRichUnpackAlgo.cxx +++ b/reco/detectors/rich/unpack/CbmRichUnpackAlgo.cxx @@ -16,5 +16,239 @@ CbmRichUnpackAlgo::CbmRichUnpackAlgo() : CbmRecoUnpackAlgo(fgkFlesSubsystemIdTrd CbmRichUnpackAlgo::~CbmRichUnpackAlgo() {} +// ---- GetParContainerRequest ---- +std::vector<std::pair<std::string, std::shared_ptr<FairParGenericSet>>>* + CbmRichUnpackAlgo::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 + "mRichPar.par"; + LOG(info) << "HelloWorld " << temppath; + fParContVec.emplace_back(std::make_pair(temppath, std::make_shared<CbmMcbm2018RichPar>())); + + return &fParContVec; +} + +// ---- calculateTime +double CbmRichUnpackAlgo::calculateTime(uint32_t epoch, uint32_t coarse, uint32_t fine) +{ + return ((double) epoch) * 2048. * 5. + ((double) coarse) * 5. - ((double) fine) * 0.005; +} + +// ---- getLogHeader +std::string CbmRichUnpackAlgo::getLogHeader(CbmMcbm2018RichMicrosliceReader& reader) +{ + std::stringstream stream; + stream << "[" << fNrProcessedTs << "-" << reader.GetWordCounter() << "/" << reader.GetSize() / 4 << " " + << reader.GetWordAsHexString(reader.GetCurWord()) << "] "; + return stream.str(); +} + +// ---- init +Bool_t CbmRichUnpackAlgo::init() { return kTRUE; } + +// ---- initParSet(FairParGenericSet* parset) ---- +Bool_t CbmRichUnpackAlgo::initParSet(FairParGenericSet* parset) +{ + LOG(info) << fName << "::initParSet - for container " << parset->ClassName(); + if (parset->IsA() == CbmMcbm2018RichPar::Class()) return initParSet(static_cast<CbmMcbm2018RichPar*>(parset)); + + // If we do not know the derived ParSet class we return false + LOG(error) << fName << "::initParSet - for container " << parset->ClassName() << " failed, since" << fName + << "::initParSet() does not know the derived ParSet and what to do with it!"; + return kFALSE; +} + +// ---- initParSet(CbmTrdParSetAsic* parset) ---- +Bool_t CbmRichUnpackAlgo::initParSet(CbmMcbm2018RichPar* parset) +{ + LOG(debug) << fName << "::initParSetAsic - "; + fUnpackPar = *parset; + + LOG(info) << fName << "::initParSetRichMcbm2018 - Successfully initialized Spadic hardware address map"; + + return kTRUE; +} + +// ---- isLog ---- +bool CbmRichUnpackAlgo::isLog() +{ + //if (fTsCounter == 25215) return true; + return false; +} + +// ---- unpack +bool CbmRichUnpackAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp, UInt_t imslice) +{ + + const fles::MicrosliceView mv = ts->get_microslice(icomp, imslice); + const fles::MicrosliceDescriptor& msDesc = mv.desc(); + + CbmMcbm2018RichMicrosliceReader reader; + reader.SetData(mv.content(), msDesc.size); + + // There are a lot of MS with 8 bytes size + // Does one need these MS? + if (reader.GetSize() <= 8) return true; + + while (true) { + processTrbPacket(reader); + // -4*2 for 2 last words which contain microslice index + if (reader.GetOffset() >= reader.GetSize() - 8) break; + // -4*3 for 0xffffffff padding and 2 last words which contain microslice index + if (reader.IsNextPadding() && reader.GetOffset() >= reader.GetSize() - 12) break; + } + + uint32_t msIndexWord1 = reader.NextWord(); + if (isLog()) LOG(DEBUG4) << getLogHeader(reader) << "Microslice Index 1:" << reader.GetWordAsHexString(msIndexWord1); + + uint32_t msIndexWord2 = reader.NextWord(); + if (isLog()) LOG(DEBUG4) << getLogHeader(reader) << "Microslice Index 2:" << reader.GetWordAsHexString(msIndexWord2); + + + return true; +} + +void CbmRichUnpackAlgo::processTrbPacket(CbmMcbm2018RichMicrosliceReader& reader) +{ + processMbs(reader, false); // Current MBS + processMbs(reader, true); // Previous MBS + + uint32_t trbNum = reader.NextWord(); // TRB trigger number + if (isLog()) LOG(debug4) << getLogHeader(reader) << "TRB Num:" << reader.GetWordAsHexString(trbNum); + + processHubBlock(reader); +} + +void CbmRichUnpackAlgo::processMbs(CbmMcbm2018RichMicrosliceReader& reader, bool isPrev) +{ + uint32_t word = reader.NextWord(); + uint32_t mbsNum = word & 0xffffff; //24 bits + uint32_t nofCtsCh = (word >> 24) & 0xff; // 8 bits + if (isLog()) + LOG(debug4) << getLogHeader(reader) << "MBS mbsNum:0x" << std::hex << mbsNum << std::dec + << " nofCtsCh:" << nofCtsCh; + + for (uint32_t i = 0; i < nofCtsCh; i++) { + uint32_t wordEpoch = reader.NextWord(); + uint32_t epoch = CbmMcbm2018RichTdcWordReader::ProcessEpoch(wordEpoch); + if (isLog()) LOG(debug4) << getLogHeader(reader) << "MBS ch:" << i << " epoch:" << epoch; + + uint32_t wordTime = reader.NextWord(); + CbmMcbm2018RichTdcTimeData td; + CbmMcbm2018RichTdcWordReader::ProcessTimeData(wordTime, td); + if (isLog()) LOG(debug4) << getLogHeader(reader) << "MBS ch:" << i << " " << td.ToString(); + + double fullTime = calculateTime(epoch, td.fCoarse, td.fFine); + + if (isPrev && td.fChannel == 0) fMbsPrevTimeCh0 = fullTime; + if (isPrev && td.fChannel == 1) fMbsPrevTimeCh1 = fullTime; + } + + double mbsCorr = fMbsPrevTimeCh1 - fMbsPrevTimeCh0; + if (isLog()) + LOG(debug4) << getLogHeader(reader) << "MBS Prev ch1:" << std::setprecision(15) << fMbsPrevTimeCh1 + << " ch0:" << fMbsPrevTimeCh0 << " corr:" << mbsCorr; +} + +// ---- processTimeDataWord ---- +void CbmRichUnpackAlgo::processTimeDataWord(CbmMcbm2018RichMicrosliceReader& reader, int iTdc, uint32_t epoch, + uint32_t tdcWord, uint32_t subSubEventId, std::vector<double>& raisingTime) +{ + CbmMcbm2018RichTdcTimeData td; + CbmMcbm2018RichTdcWordReader::ProcessTimeData(tdcWord, td); + double fullTime = calculateTime(epoch, td.fCoarse, td.fFine); + + + if (td.fChannel == 0) { + if (td.IsRisingEdge()) { + fPrevLastCh0ReTime[subSubEventId] = fLastCh0ReTime[subSubEventId]; + fLastCh0ReTime[subSubEventId] = fullTime; + if (isLog()) + LOG(debug4) << getLogHeader(reader) << "SubSubEv[" << iTdc << "] " << td.ToString() + << " CH0 Last:" << std::setprecision(15) << fLastCh0ReTime[subSubEventId] + << " PrevLast:" << fPrevLastCh0ReTime[subSubEventId] + << " diff:" << fLastCh0ReTime[subSubEventId] - fPrevLastCh0ReTime[subSubEventId]; + } + } + else { + double dT = fullTime - fPrevLastCh0ReTime[subSubEventId]; + double mbsCorr = fMbsPrevTimeCh1 - fMbsPrevTimeCh0; + double fullTimeCorr = dT - mbsCorr; + if (isLog()) + LOG(debug4) << getLogHeader(reader) << "SubSubEv[" << iTdc << "] " << td.ToString() + << " time:" << std::setprecision(15) << fullTime << " fullTimeCorr:" << fullTimeCorr; + + if (td.fChannel < 1 || td.fChannel >= raisingTime.size()) { + LOG(error) << "ERROR: channel number is out of limit. Channel:" << td.fChannel; + } + + if (td.IsRisingEdge()) { + // always store the latest raising edge. It means that in case RRFF situation only middle RF will be matched. + raisingTime[td.fChannel] = fullTimeCorr; + } + else { + if (raisingTime[td.fChannel] == -1.) { + //No raising channel was found before. Skip this falling edge time. + if (isLog()) + LOG(debug4) << getLogHeader(reader) << "SubSubEv[" << iTdc << "] " + << "No raising channel was found before. Skip this falling edge time."; + } + else { + // Matching was found, calculate ToT, if tot is in a good range -> create digi + double ToT = fullTimeCorr - raisingTime[td.fChannel]; + if (isLog()) + LOG(debug4) << getLogHeader(reader) << "SubSubEv[" << iTdc << "] " + << "ToT:" << ToT; + if (ToT >= fToTMin && ToT <= fToTMax) { + // if (fbMonitorMode) { + // TH1D* h = GetTotH1(subSubEventId, td.fChannel); + // if (h != nullptr) h->Fill(ToT); + + // TH2D* h2 = GetTotH2(subSubEventId); + // if (h2 != nullptr) h2->Fill(td.fChannel, ToT); + // } + writeOutputDigi(subSubEventId, td.fChannel, raisingTime[td.fChannel], ToT); + } + // pair was created, set raising edge to -1. + raisingTime[td.fChannel] = -1.; + } + } + } +} + +void CbmRichUnpackAlgo::writeOutputDigi(Int_t fpgaID, Int_t channel, Double_t time, Double_t tot) +{ + Double_t ToTcorr = fbDoToTCorr ? fUnpackPar.GetToTshift(fpgaID, channel) : 0.; + Int_t pixelUID = this->getPixelUID(fpgaID, channel); + //check ordering + // Double_t finalTime = time + (Double_t) msRefTS - fSystemTimeoffset; + Double_t finalTime = time - fSystemTimeoffset - fTsStartTime; + + Double_t lastTime = 0.; + + if (fOutputVec.size() < 1) { fOutputVec.emplace_back(pixelUID, finalTime, tot - ToTcorr); } + else { + lastTime = fOutputVec[fOutputVec.size() - 1].GetTime(); + if (fOutputVec[0].GetTime() > finalTime) { + fOutputVec.emplace(fOutputVec.begin(), pixelUID, finalTime, tot - ToTcorr); + } + else if (lastTime > finalTime) { + for (int i = fOutputVec.size() - 1; i >= 0; i--) { + lastTime = fOutputVec[i].GetTime(); + if (lastTime <= finalTime) { + fOutputVec.emplace(fOutputVec.begin() + i + 1, pixelUID, finalTime, tot - ToTcorr); + break; + } + } + } + else { + fOutputVec.emplace_back(pixelUID, finalTime, tot - ToTcorr); + } + } +} ClassImp(CbmRichUnpackAlgo) diff --git a/reco/detectors/rich/unpack/CbmRichUnpackAlgo.h b/reco/detectors/rich/unpack/CbmRichUnpackAlgo.h index effe35cae3ddcae5a10084d722f501157aa6aa3e..ac52e93e9de36d6134e229817e37178aabc9b579 100644 --- a/reco/detectors/rich/unpack/CbmRichUnpackAlgo.h +++ b/reco/detectors/rich/unpack/CbmRichUnpackAlgo.h @@ -21,6 +21,8 @@ #ifndef CbmRichUnpackAlgo_H #define CbmRichUnpackAlgo_H +// #include "CbmMcbm2018RichPar.h" +#include "../../core/detectors/rich/CbmMcbm2018RichPar.h" #include "CbmRecoUnpackAlgo.tmpl" #include "CbmRichDigi.h" @@ -34,8 +36,165 @@ #include <memory> #include <utility> + class CbmRichUnpackAlgo : public CbmRecoUnpackAlgo<CbmRichDigi> { public: + enum class CbmMcbm2018RichErrorType + { + mtsError, + tdcHeader, + tdcTrailer, + ctsHeader, + ctsTrailer, + subEventError + }; + + enum class CbmMcbm2018RichTdcWordType + { + TimeData, + Header, + Epoch, + Trailer, + Debug, + Error + }; + + class CbmMcbm2018RichTdcTimeData { + public: + uint32_t fCoarse = 0; // 11 bits + uint32_t fEdge = 0; // 1 bit + uint32_t fFine = 0; // 10 bits + uint32_t fChannel = 0; // 7 bits + + std::string ToString() + { + std::stringstream stream; + stream << "channel:" << fChannel << " coarse:" << fCoarse << " fine:" << fFine + << " edge:" << ((fEdge == 1) ? "R" : "F"); + return stream.str(); + } + + bool IsRisingEdge() { return (fEdge == 1); } + }; + + class CbmMcbm2018RichTdcWordReader { + public: + static CbmMcbm2018RichTdcWordType GetTdcWordType(uint32_t tdcWord) + { + uint32_t tdcTimeDataMarker = (tdcWord >> 31) & 0x1; // 1 bit + uint32_t tdcMarker = (tdcWord >> 29) & 0x7; // 3 bits + + if (tdcTimeDataMarker == 0x1) { + // TODO: I also include tdcMarker == 0x5, some tdc time data words have this marker. Is it correct? + if (tdcMarker == 0x4 || tdcMarker == 0x5) { return CbmMcbm2018RichTdcWordType::TimeData; } + else { + return CbmMcbm2018RichTdcWordType::Error; + } + } + + if (tdcMarker == 0x0) return CbmMcbm2018RichTdcWordType::Trailer; + if (tdcMarker == 0x1) return CbmMcbm2018RichTdcWordType::Header; + if (tdcMarker == 0x2) return CbmMcbm2018RichTdcWordType::Debug; + if (tdcMarker == 0x3) return CbmMcbm2018RichTdcWordType::Epoch; + + return CbmMcbm2018RichTdcWordType::Error; + } + + static void ProcessTimeData(uint32_t tdcWord, CbmMcbm2018RichTdcTimeData& outData) + { + outData.fCoarse = static_cast<uint32_t>(tdcWord & 0x7ff); // 11 bits + outData.fEdge = static_cast<uint32_t>((tdcWord >> 11) & 0x1); // 1 bit + outData.fFine = static_cast<uint32_t>((tdcWord >> 12) & 0x3ff); // 10 bits + outData.fChannel = static_cast<uint32_t>((tdcWord >> 22) & 0x7f); // 7 bits + } + + static uint32_t ProcessEpoch(uint32_t tdcWord) { return static_cast<uint32_t>(tdcWord & 0xfffffff); } + + static uint16_t ProcessHeader(uint32_t tdcWord) + { + // for the moment just extract error bits + return static_cast<uint16_t>(tdcWord & 0xff); //8 bits + } + + static uint16_t ProcessTrailer(uint32_t tdcWord) + { + // for the moment just extract error bits + return static_cast<uint16_t>(tdcWord & 0xffff); + } + + static void ProcessDebug(uint32_t tdcWord) + { + LOG(debug4) << "ProcessDebug is not implemented. tdcWord:0x" << std::hex << tdcWord << std::dec; + // for the moment do nothing + } + }; + + class CbmMcbm2018RichMicrosliceReader { + private: + const uint8_t* fData = nullptr; + size_t fSize = 0; + size_t fOffset = 0; // offset in bytes + size_t fWordCounter = 0; + uint32_t fCurWord; + + public: + void SetData(const uint8_t* data, size_t size) + { + fData = data; + fSize = size; + fOffset = 0; + fWordCounter = 0; + fCurWord = 0; + } + + const uint8_t* GetData() { return fData; } + + size_t GetSize() { return fSize; } + + size_t GetOffset() { return fOffset; } + + size_t GetWordCounter() { return fWordCounter; } + + uint32_t GetCurWord() { return fCurWord; } + + std::string GetWordAsHexString(uint32_t word) + { + std::stringstream stream; + stream << "0x" << std::setfill('0') << std::setw(sizeof(uint32_t) * 2) << std::hex << word; + return stream.str(); + } + + uint32_t NextWord() + { + //mRichSupport::SwapBytes(4, fData + fOffset); + //Int_t* dataPtr = (Int_t*) (fData + fOffset); + uint32_t i = ((uint32_t*) (fData + fOffset))[0]; + //swap bytes + i = (i >> 24) | ((i << 8) & 0x00FF0000) | ((i >> 8) & 0x0000FF00) | (i << 24); + //i = ((i&0xFF)<<24) | (((i>>8)&0xFF)<<16) | (((i>>16)&0xFF)<<8) | (((i>>24)&0xFF)<<0); + + fOffset += 4; + fWordCounter++; + fCurWord = i; + //return (Int_t)(dataPtr[0]); + return i; + } + + bool IsNextPadding() + { + uint32_t nextWord = ((uint32_t*) (fData + fOffset))[0]; + if (nextWord == 0xffffffff) return true; + return false; + } + + bool IsLastSubSubEvent(uint32_t subSubEventSize) + { + uint32_t i = ((uint32_t*) (fData + fOffset + 4 * subSubEventSize))[0]; + i = (i >> 24) | ((i << 8) & 0x00ff0000) | ((i >> 8) & 0x0000ff00) | (i << 24); + if (i == 0x00015555) return true; + return false; + } + }; /** @brief Create the Cbm Trd Unpack AlgoBase object */ CbmRichUnpackAlgo(); @@ -58,12 +217,11 @@ public: * @return fParContVec */ virtual std::vector<std::pair<std::string, std::shared_ptr<FairParGenericSet>>>* - GetParContainerRequest(std::string geoTag, std::uint32_t runId) - { - return {}; - }; + GetParContainerRequest(std::string geoTag, std::uint32_t runId); protected: + double calculateTime(uint32_t epoch, uint32_t coarse, uint32_t fine); + /** @brief Finish function for this algorithm base clase */ void finish() { @@ -75,12 +233,29 @@ protected: /** @brief Function that allows special calls during Finish in the derived algos */ virtual void finishDerived() { return; } + std::string getLogHeader(CbmMcbm2018RichMicrosliceReader& reader); + + Int_t getPixelUID(Int_t fpgaID, Int_t ch) const + { + // First 16 bits are used for the FPGA ID, then + // 8 bits unused and then 8 bits are used for the channel + return ((fpgaID << 16) | (ch & 0x00FF)); + } + /** * @brief Intialisation at begin of run. Special inits of the derived algos. * * @retval Bool_t initOk */ - Bool_t init() { return kTRUE; } + 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. @@ -88,7 +263,27 @@ protected: * @param parset * @return Bool_t initOk */ - Bool_t initParSet(FairParGenericSet* parset) { return kTRUE; } + Bool_t initParSet(CbmMcbm2018RichPar* parset); + + bool isLog(); + + void processTrbPacket(CbmMcbm2018RichMicrosliceReader& reader); + + void processMbs(CbmMcbm2018RichMicrosliceReader& reader, bool isPrev); + + void processHubBlock(CbmMcbm2018RichMicrosliceReader& reader); + + void processCtsSubSubEvent(CbmMcbm2018RichMicrosliceReader& reader, uint32_t subSubEventSize, uint32_t subSubEventId); + + void processSubSubEvent(CbmMcbm2018RichMicrosliceReader& reader, int nofTimeWords, uint32_t subSubEventId); + + void processTimeDataWord(CbmMcbm2018RichMicrosliceReader& reader, int iTdc, uint32_t epoch, uint32_t tdcWord, + uint32_t subSubEventId, std::vector<double>& raisingTime); + + /** + * Write a gidi object into the output collection + */ + void writeOutputDigi(Int_t fpgaID, Int_t channel, Double_t time, Double_t tot); /** * @brief Set the Derived Ts Parameters @@ -112,11 +307,25 @@ protected: * * @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) { return true; } + bool unpack(const fles::Timeslice* ts, std::uint16_t icomp, UInt_t imslice); /** @brief Fles Subsystem Identifier for the TRD R data */ static constexpr int fgkFlesSubsystemIdTrdR = static_cast<int>(fles::SubsystemIdentifier::RICH); + /** @brief Parameters for the unpacking */ + CbmMcbm2018RichPar fUnpackPar; + + double fMbsPrevTimeCh0 = 0.; + double fMbsPrevTimeCh1 = 0.; + + double fToTMin = -20.; + double fToTMax = 100.; + + std::map<uint32_t, double> fLastCh0ReTime; //key:TDC ID, value:Full time of last rising edge from ch 0 + std::map<uint32_t, double> fPrevLastCh0ReTime; // key:TDC ID, value:Full time of previous last rising edge from ch 0 + + Bool_t fbDoToTCorr = true; // kTRUE activates ToT correction from Parameterfile + private: ClassDef(CbmRichUnpackAlgo, 2) }; diff --git a/reco/detectors/rich/unpack/CbmRichUnpackConfig.cxx b/reco/detectors/rich/unpack/CbmRichUnpackConfig.cxx index 279e552fa8f6ee32882684a076668053800a1ef3..de94c27a96ab9d1cd81ac651651f8aa46adc135c 100644 --- a/reco/detectors/rich/unpack/CbmRichUnpackConfig.cxx +++ b/reco/detectors/rich/unpack/CbmRichUnpackConfig.cxx @@ -33,6 +33,9 @@ void CbmRichUnpackConfig::InitUnpacker() // 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); diff --git a/reco/steer/CbmRecoUnpack.cxx b/reco/steer/CbmRecoUnpack.cxx index b59fba60fb08f9984686fbf612151f1aac24ad39..d8dc446850c51fbe6ffa8f8ef4e2de94fc6af6be 100644 --- a/reco/steer/CbmRecoUnpack.cxx +++ b/reco/steer/CbmRecoUnpack.cxx @@ -129,6 +129,12 @@ void CbmRecoUnpack::Unpack(unique_ptr<Timeslice> ts) unpack(×lice, component, fPsdConfig, fPsdConfig->GetOptOutAVec(), fPsdConfig->GetOptOutBVec())); break; } + case fkFlesRich: { + if (fRichConfig) + fCbmTsEventHeader->SetNDigisRich( + unpack(×lice, component, fRichConfig, fRichConfig->GetOptOutAVec(), fRichConfig->GetOptOutBVec())); + break; + } case fkFlesTrd: { if (fTrdConfig) fCbmTsEventHeader->SetNDigisTrd(