From c17ac7da40f3b3be50cee1f3ab7ea3e97bd8e99a Mon Sep 17 00:00:00 2001
From: Bartosz Sobol <bartosz.sobol@doctoral.uj.edu.pl>
Date: Wed, 22 Jan 2025 23:46:41 +0100
Subject: [PATCH 01/21] prep for PASTA unpacker

---
 algo/CMakeLists.txt                    |  4 ++++
 algo/base/AuxDigiData.h                |  2 ++
 algo/base/DigiData.h                   |  2 ++
 algo/data/CMakeLists.txt               |  2 ++
 algo/detectors/pasta/ReadoutConfig.cxx |  5 +++++
 algo/detectors/pasta/ReadoutConfig.h   | 14 +++++++++++++
 algo/detectors/pasta/Unpack.cxx        | 12 +++++++++++
 algo/detectors/pasta/Unpack.h          | 29 ++++++++++++++++++++++++++
 algo/detectors/pasta/UnpackMS.cxx      |  5 +++++
 algo/detectors/pasta/UnpackMS.h        | 17 +++++++++++++++
 algo/global/Reco.cxx                   | 11 +++++++---
 algo/global/Reco.h                     |  8 +++++++
 algo/global/RecoResults.h              |  1 +
 algo/global/StorableRecoResults.h      |  5 +++++
 core/data/CMakeLists.txt               |  8 +++++--
 core/data/base/CbmDigiData.h           |  6 ++++++
 core/data/pasta/CbmPastaDigi.cxx       |  5 +++++
 core/data/pasta/CbmPastaDigi.h         | 16 ++++++++++++++
 core/data/pasta/CbmPastaDigiData.h     | 14 +++++++++++++
 reco/app/cbmreco/main.cxx              |  1 +
 20 files changed, 162 insertions(+), 5 deletions(-)
 create mode 100644 algo/detectors/pasta/ReadoutConfig.cxx
 create mode 100644 algo/detectors/pasta/ReadoutConfig.h
 create mode 100644 algo/detectors/pasta/Unpack.cxx
 create mode 100644 algo/detectors/pasta/Unpack.h
 create mode 100644 algo/detectors/pasta/UnpackMS.cxx
 create mode 100644 algo/detectors/pasta/UnpackMS.h
 create mode 100644 core/data/pasta/CbmPastaDigi.cxx
 create mode 100644 core/data/pasta/CbmPastaDigi.h
 create mode 100644 core/data/pasta/CbmPastaDigiData.h

diff --git a/algo/CMakeLists.txt b/algo/CMakeLists.txt
index a70b0872c9..f0d829c4b0 100644
--- a/algo/CMakeLists.txt
+++ b/algo/CMakeLists.txt
@@ -143,6 +143,9 @@ set(SRCS
   detectors/rich/ReadoutConfig.cxx
   detectors/rich/Unpack.cxx
   detectors/rich/UnpackMS.cxx
+  detectors/pasta/Unpack.cxx
+  detectors/pasta/UnpackMS.cxx
+  detectors/pasta/ReadoutConfig.cxx
   global/ParFiles.cxx
   global/StorableRecoResults.cxx
   global/Reco.cxx
@@ -337,6 +340,7 @@ install(DIRECTORY base/gpu TYPE INCLUDE FILES_MATCHING PATTERN "*.h")
 install(DIRECTORY data/sts TYPE INCLUDE FILES_MATCHING PATTERN "*.h")
 install(DIRECTORY detectors/bmon TYPE INCLUDE FILES_MATCHING PATTERN "*.h")
 install(DIRECTORY detectors/much TYPE INCLUDE FILES_MATCHING PATTERN "*.h")
+install(DIRECTORY detectors/pasta TYPE INCLUDE FILES_MATCHING PATTERN "*.h")
 install(DIRECTORY detectors/sts TYPE INCLUDE FILES_MATCHING PATTERN "*.h")
 install(DIRECTORY detectors/tof TYPE INCLUDE FILES_MATCHING PATTERN "*.h")
 install(DIRECTORY detectors/trd TYPE INCLUDE FILES_MATCHING PATTERN "*.h")
diff --git a/algo/base/AuxDigiData.h b/algo/base/AuxDigiData.h
index e464da7e28..0f67256afc 100644
--- a/algo/base/AuxDigiData.h
+++ b/algo/base/AuxDigiData.h
@@ -13,6 +13,7 @@
 #include "bmon/UnpackMS.h"
 #include "much/UnpackMS.h"
 #include "rich/UnpackMS.h"
+#include "pasta/UnpackMS.h"
 #include "sts/UnpackMS.h"
 #include "tof/UnpackMS.h"
 #include "trd/UnpackMS.h"
@@ -28,6 +29,7 @@ namespace cbm::algo
     UnpackAux<bmon::UnpackAuxData> fBmon;
     UnpackAux<much::UnpackAuxData> fMuch;
     UnpackAux<rich::UnpackAuxData> fRich;
+    UnpackAux<pasta::UnpackAuxData> fPasta;
     UnpackAux<sts::UnpackAuxData> fSts;
     UnpackAux<tof::UnpackAuxData> fTof;
     UnpackAux<trd::UnpackAuxData> fTrd;
diff --git a/algo/base/DigiData.h b/algo/base/DigiData.h
index 09b82d9334..14f8ec848d 100644
--- a/algo/base/DigiData.h
+++ b/algo/base/DigiData.h
@@ -12,6 +12,7 @@
 #include "CbmMuchDigi.h"
 #include "CbmPsdDigi.h"
 #include "CbmRichDigi.h"
+#include "CbmPastaDigi.h"
 #include "CbmStsDigi.h"
 #include "CbmTofDigi.h"
 #include "CbmTrdDigi.h"
@@ -39,6 +40,7 @@ namespace cbm::algo
     PODVector<CbmRichDigi> fRich;  ///< Unpacked RICH digis
     PODVector<CbmPsdDigi> fPsd;    ///< Unpacked PSD digis
     PODVector<CbmFsdDigi> fFsd;    ///< Unpacked FSD digis
+    PODVector<CbmPastaDigi> fPasta;///< Unpacked PASTA digis
 
     DigiData();
     ~DigiData();
diff --git a/algo/data/CMakeLists.txt b/algo/data/CMakeLists.txt
index 717ba53896..e65eaba58e 100644
--- a/algo/data/CMakeLists.txt
+++ b/algo/data/CMakeLists.txt
@@ -32,6 +32,7 @@ set(SRCS
   ${OFFLINE_DATA_DIR}/fsd/CbmFsdDigi.cxx
   ${OFFLINE_DATA_DIR}/fsd/CbmFsdAddress.cxx
 
+  ${OFFLINE_DATA_DIR}/pasta/CbmPastaDigi.cxx
 
   ${OFFLINE_DATA_DIR}/raw/CriGet4Mess001.cxx
   ${OFFLINE_DATA_DIR}/raw/StsXyterMessage.cxx
@@ -50,6 +51,7 @@ target_include_directories(OnlineData
   PUBLIC ${OFFLINE_DATA_DIR}/tof
   PUBLIC ${OFFLINE_DATA_DIR}/psd
   PUBLIC ${OFFLINE_DATA_DIR}/fsd
+  PUBLIC ${OFFLINE_DATA_DIR}/pasta
   PUBLIC ${OFFLINE_DATA_DIR}/global
   PUBLIC ${OFFLINE_DATA_DIR}/raw
 )
diff --git a/algo/detectors/pasta/ReadoutConfig.cxx b/algo/detectors/pasta/ReadoutConfig.cxx
new file mode 100644
index 0000000000..16c05d2484
--- /dev/null
+++ b/algo/detectors/pasta/ReadoutConfig.cxx
@@ -0,0 +1,5 @@
+/* Copyright (C) 2025 Jagiellonian University, Krakow
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Bartosz Sobol [committer] */
+
+#include "ReadoutConfig.h"
diff --git a/algo/detectors/pasta/ReadoutConfig.h b/algo/detectors/pasta/ReadoutConfig.h
new file mode 100644
index 0000000000..aca3b205e7
--- /dev/null
+++ b/algo/detectors/pasta/ReadoutConfig.h
@@ -0,0 +1,14 @@
+/* Copyright (C) 2025 Jagiellonian University, Krakow
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Bartosz Sobol [committer] */
+
+#pragma once
+
+namespace cbm::algo::pasta {
+
+class ReadoutConfig {
+
+};
+
+
+}
diff --git a/algo/detectors/pasta/Unpack.cxx b/algo/detectors/pasta/Unpack.cxx
new file mode 100644
index 0000000000..8d3a6d0456
--- /dev/null
+++ b/algo/detectors/pasta/Unpack.cxx
@@ -0,0 +1,12 @@
+/* Copyright (C) 2025 Jagiellonian University, Krakow
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Bartosz Sobol [committer] */
+
+#include "Unpack.h"
+
+namespace cbm {
+namespace algo {
+namespace pasta {
+} // pasta
+} // algo
+} // cbm
\ No newline at end of file
diff --git a/algo/detectors/pasta/Unpack.h b/algo/detectors/pasta/Unpack.h
new file mode 100644
index 0000000000..137f7aa985
--- /dev/null
+++ b/algo/detectors/pasta/Unpack.h
@@ -0,0 +1,29 @@
+/* Copyright (C) 2025 Jagiellonian University, Krakow
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Bartosz Sobol [committer] */
+
+#pragma once
+#include <CommonUnpacker.h>
+#include <Timeslice.hpp>
+
+#include "CbmRichDigi.h"
+#include "ReadoutConfig.h"
+#include "UnpackMS.h"
+
+namespace cbm::algo::pasta {
+    namespace detail {
+        using UnpackBase = CommonUnpacker<CbmRichDigi, UnpackMonitorData, UnpackAuxData>;
+    }
+
+    class Unpack : public detail::UnpackBase {
+    public:
+        using Result_t = detail::UnpackBase::Result_t;
+
+        Unpack(const ReadoutConfig &readout);
+
+        Result_t operator()(const fles::Timeslice &) const;
+
+    private:
+        ReadoutConfig fReadout;
+    };
+} // cbm::algo::pasta
diff --git a/algo/detectors/pasta/UnpackMS.cxx b/algo/detectors/pasta/UnpackMS.cxx
new file mode 100644
index 0000000000..2cfb45b65d
--- /dev/null
+++ b/algo/detectors/pasta/UnpackMS.cxx
@@ -0,0 +1,5 @@
+/* Copyright (C) 2025 Jagiellonian University, Krakow
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Bartosz Sobol [committer], Pascal Raisig, Dominik Smith */
+
+#include "UnpackMS.h"
diff --git a/algo/detectors/pasta/UnpackMS.h b/algo/detectors/pasta/UnpackMS.h
new file mode 100644
index 0000000000..ce169a69ed
--- /dev/null
+++ b/algo/detectors/pasta/UnpackMS.h
@@ -0,0 +1,17 @@
+/* Copyright (C) 2025 Jagiellonian University, Krakow
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Bartosz Sobol [committer], Pascal Raisig, Dominik Smith */
+
+#pragma once
+
+namespace cbm::algo::pasta {
+
+   class UnpackAuxData {};
+
+class UnpackMS {
+
+};
+
+}
+
+
diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx
index 0f192df1b6..1085ecd758 100644
--- a/algo/global/Reco.cxx
+++ b/algo/global/Reco.cxx
@@ -27,6 +27,7 @@
 #include "qa/QaManager.h"
 #include "qa/hitfind/BmonHitfindQa.h"
 #include "rich/Unpack.h"
+#include "pasta/Unpack.h"
 #include "sts/ChannelMaskSet.h"
 #include "sts/HitfinderChain.h"
 #include "sts/Unpack.h"
@@ -140,8 +141,10 @@ void Reco::Init(const Options& opts)
   }
 
   if (Opts().Has(Subsystem::RICH) && Opts().Has(Step::Unpack)) {
-    rich::ReadoutConfig cfg{};
-    fRichUnpack = std::make_unique<rich::Unpack>(cfg);
+    rich::ReadoutConfig richCfg{};
+    fRichUnpack = std::make_unique<rich::Unpack>(richCfg);
+    pasta::ReadoutConfig pastaCfg{};
+    fPastaUnpack = std::make_unique<pasta::Unpack>(pastaCfg);
   }
 
   if (Opts().Has(Subsystem::STS) && Opts().Has(Step::Unpack)) {
@@ -320,6 +323,7 @@ RecoResults Reco::Run(const fles::Timeslice& ts)
       std::tie(digis.fBmon, auxDigis.fBmon)   = RunUnpacker(fBmonUnpack, ts);
       std::tie(digis.fMuch, auxDigis.fMuch)   = RunUnpacker(fMuchUnpack, ts);
       std::tie(digis.fRich, auxDigis.fRich)   = RunUnpacker(fRichUnpack, ts);
+      std::tie(digis.fPasta, auxDigis.fPasta) = RunUnpacker(fPastaUnpack, ts);
       std::tie(digis.fSts, auxDigis.fSts)     = RunUnpacker(fStsUnpack, ts);
       std::tie(digis.fTof, auxDigis.fTof)     = RunUnpacker(fTofUnpack, ts);
       std::tie(digis.fTrd, auxDigis.fTrd)     = RunUnpacker(fTrdUnpack, ts);
@@ -332,7 +336,7 @@ RecoResults Reco::Run(const fles::Timeslice& ts)
       L_(info) << "TS contains Digis: STS=" << digis.fSts.size() << " MUCH=" << digis.fMuch.size()
                << " TOF=" << digis.fTof.size() << " BMON=" << digis.fBmon.size() << " TRD=" << digis.fTrd.size()
                << " TRD2D=" << digis.fTrd2d.size() << " RICH=" << digis.fRich.size() << " PSD=" << digis.fPsd.size()
-               << " FSD=" << digis.fFsd.size();
+               << " FSD=" << digis.fFsd.size() << " PASTA=" << digis.fPasta.size();
       // --- Raw digi QAs
       if (fSender != nullptr && Opts().Has(Subsystem::STS)) {
         fStsDigiQa->RegisterDigiData(&digis.fSts);
@@ -444,6 +448,7 @@ RecoResults Reco::Run(const fles::Timeslice& ts)
       results.trdDigis   = std::move(digis.fTrd);
       results.tofDigis   = std::move(digis.fTof);
       results.richDigis  = std::move(digis.fRich);
+      results.pastaDigis = std::move(digis.fPasta);
     }
     if (Opts().HasOutput(RecoData::Track)) {
       results.tracks             = std::move(recoData.tracks);
diff --git a/algo/global/Reco.h b/algo/global/Reco.h
index 35cb5c3462..3ccb4b5ea1 100644
--- a/algo/global/Reco.h
+++ b/algo/global/Reco.h
@@ -46,6 +46,11 @@ namespace cbm::algo
     class Unpack;
   }
 
+  namespace pasta
+  {
+    class Unpack;
+  }
+
   namespace sts
   {
     class Unpack;
@@ -166,6 +171,9 @@ namespace cbm::algo
     // RICH
     std::unique_ptr<rich::Unpack> fRichUnpack;
 
+    // PASTA
+    std::unique_ptr<pasta::Unpack> fPastaUnpack;
+
     // STS
     std::unique_ptr<sts::Unpack> fStsUnpack;
     std::unique_ptr<sts::DigiQa> fStsDigiQa;  ///< Raw STS-digis QA
diff --git a/algo/global/RecoResults.h b/algo/global/RecoResults.h
index 3bcee8be6a..ee0bd49c78 100644
--- a/algo/global/RecoResults.h
+++ b/algo/global/RecoResults.h
@@ -36,6 +36,7 @@ namespace cbm::algo
     PODVector<CbmTrdDigi> trdDigis;
     PODVector<CbmTofDigi> tofDigis;
     PODVector<CbmRichDigi> richDigis;
+    PODVector<CbmPastaDigi> pastaDigis;
 
     std::vector<DigiEvent> events;
 
diff --git a/algo/global/StorableRecoResults.h b/algo/global/StorableRecoResults.h
index 5560b7d1ad..ae911f774f 100644
--- a/algo/global/StorableRecoResults.h
+++ b/algo/global/StorableRecoResults.h
@@ -70,6 +70,9 @@ namespace cbm::algo
     std::vector<CbmRichDigi>& RichDigis() { return fRichDigis; }
     const std::vector<CbmRichDigi>& RichDigis() const { return fRichDigis; }
 
+    std::vector<CbmPastaDigi>& PastaDigis() { return fPastaDigis; }
+    const std::vector<CbmPastaDigi>& PastaDigis() const { return fPastaDigis; }
+
     std::vector<CbmDigiEvent>& DigiEvents() { return fDigiEvents; }
     const std::vector<CbmDigiEvent>& DigiEvents() const { return fDigiEvents; }
 
@@ -106,6 +109,7 @@ namespace cbm::algo
     std::vector<CbmTrdDigi> fTrdDigis;
     std::vector<CbmTofDigi> fTofDigis;
     std::vector<CbmRichDigi> fRichDigis;
+    std::vector<CbmPastaDigi> fPastaDigis;
 
     // Event builder/filter output
     std::vector<CbmDigiEvent> fDigiEvents;
@@ -142,6 +146,7 @@ namespace cbm::algo
       ar& fTrdDigis;
       ar& fTofDigis;
       ar& fRichDigis;
+      ar& fPastaDigis;
 
       ar& fDigiEvents;
 
diff --git a/core/data/CMakeLists.txt b/core/data/CMakeLists.txt
index b5b59dd078..3cc9465592 100644
--- a/core/data/CMakeLists.txt
+++ b/core/data/CMakeLists.txt
@@ -15,6 +15,7 @@ set(INCLUDE_DIRECTORIES
   ${CMAKE_CURRENT_SOURCE_DIR}/rich
   ${CMAKE_CURRENT_SOURCE_DIR}/psd
   ${CMAKE_CURRENT_SOURCE_DIR}/fsd
+  ${CMAKE_CURRENT_SOURCE_DIR}/pasta
   ${CMAKE_CURRENT_SOURCE_DIR}/global
   )
 
@@ -66,6 +67,8 @@ set(SRCS
   rich/CbmRichTrbDigi.cxx
   rich/CbmRichDigi.cxx
 
+  pasta/CbmPastaDigi.cxx
+
   much/CbmMuchPixelHit.cxx
   much/CbmMuchPoint.cxx
   much/CbmMuchCluster.cxx
@@ -134,8 +137,8 @@ SET_SOURCE_FILES_PROPERTIES(tof/etof/star_rhicf.c PROPERTIES COMPILE_FLAGS -Wno-
 
 
 list(APPEND HEADERS base/CbmDigiData.h global/CbmDigiEvent.h global/CbmDigiTimeslice.h
-bmon/CbmBmonDigiData.h sts/CbmStsDigiData.h much/CbmMuchDigiData.h rich/CbmRichDigiData.h trd/CbmTrdDigiData.h
-tof/CbmTofDigiData.h psd/CbmPsdDigiData.h fsd/CbmFsdDigiData.h trd/CbmTrdFexMessageSpadic.h)
+bmon/CbmBmonDigiData.h sts/CbmStsDigiData.h much/CbmMuchDigiData.h rich/CbmRichDigiData.h pasta/CbmPastaDigiData.h
+trd/CbmTrdDigiData.h tof/CbmTofDigiData.h psd/CbmPsdDigiData.h fsd/CbmFsdDigiData.h trd/CbmTrdFexMessageSpadic.h)
 
 set(LIBRARY_NAME CbmData)
 set(LINKDEF ${LIBRARY_NAME}LinkDef.h)
@@ -166,6 +169,7 @@ Install(FILES
         psd/CbmPsdDigiData.h
         fsd/CbmFsdDigiData.h
         rich/CbmRichDigiData.h rich/CbmRichRingLight.h
+        pasta/CbmPastaDigiData.h
         sts/CbmStsDigiData.h
         trd/CbmTrdDigiData.h
         tof/CbmTofDigiData.h
diff --git a/core/data/base/CbmDigiData.h b/core/data/base/CbmDigiData.h
index c864e8ba6f..49f4ac8ff8 100644
--- a/core/data/base/CbmDigiData.h
+++ b/core/data/base/CbmDigiData.h
@@ -14,6 +14,7 @@
 #include "CbmStsDigiData.h"
 #include "CbmTofDigiData.h"
 #include "CbmTrdDigiData.h"
+#include "CbmPastaDigiData.h"
 
 #include <boost/serialization/access.hpp>
 #include <boost/serialization/base_object.hpp>
@@ -41,6 +42,7 @@ class CbmDigiData {
   CbmTofDigiData fTof;    ///< TOF data
   CbmPsdDigiData fPsd;    ///< PSD data
   CbmFsdDigiData fFsd;    ///< FSD data
+  CbmFsdDigiData fPasta;  ///< PASTA data
 
   friend class boost::serialization::access;
   /** @brief BOOST serializer**/
@@ -57,6 +59,7 @@ class CbmDigiData {
     ar& fPsd;
     ar& fFsd;
     ar& fRich;
+    ar& fPasta;
   }
 
   // --- ROOT serializer
@@ -76,6 +79,7 @@ class CbmDigiData {
     fPsd.Clear();
     fFsd.Clear();
     fRich.Clear();
+    fPasta.Clear();
   }
 
   /** @brief Size of detector data **/
@@ -92,6 +96,7 @@ class CbmDigiData {
       case ECbmModuleId::kRich: return fRich.Size(); break;
       case ECbmModuleId::kFsd: return fFsd.Size(); break;
       default: return 0; break;
+      //TODO add PASTA
     }
   }
 
@@ -108,6 +113,7 @@ class CbmDigiData {
     size += fPsd.Size() * sizeof(CbmPsdDigi);
     size += fFsd.Size() * sizeof(CbmFsdDigi);
     size += fRich.Size() * sizeof(CbmRichDigi);
+    size += fPasta.Size() * sizeof(CbmPastaDigi);
     return size;
   }
 };
diff --git a/core/data/pasta/CbmPastaDigi.cxx b/core/data/pasta/CbmPastaDigi.cxx
new file mode 100644
index 0000000000..445f9a6df6
--- /dev/null
+++ b/core/data/pasta/CbmPastaDigi.cxx
@@ -0,0 +1,5 @@
+/* Copyright (C) 2025 Jagiellonian University, Krakow
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Bartosz Sobol [committer] */
+
+#include "CbmPastaDigi.h"
diff --git a/core/data/pasta/CbmPastaDigi.h b/core/data/pasta/CbmPastaDigi.h
new file mode 100644
index 0000000000..70382bf795
--- /dev/null
+++ b/core/data/pasta/CbmPastaDigi.h
@@ -0,0 +1,16 @@
+/* Copyright (C) 2025 Jagiellonian University, Krakow
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Bartosz Sobol [committer] */
+
+#ifndef CBMPASTADIGI_H
+#define CBMPASTADIGI_H
+
+
+
+class CbmPastaDigi {
+
+};
+
+
+
+#endif //CBMPASTADIGI_H
diff --git a/core/data/pasta/CbmPastaDigiData.h b/core/data/pasta/CbmPastaDigiData.h
new file mode 100644
index 0000000000..e44c9e1e74
--- /dev/null
+++ b/core/data/pasta/CbmPastaDigiData.h
@@ -0,0 +1,14 @@
+/* Copyright (C) 2025 Jagiellonian University, Krakow
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Bartosz Sobol [committer] */
+
+#ifndef CBMPASTADIGIDATA_H
+#define CBMPASTADIGIDATA_H
+
+#include "CbmPastaDigi.h"
+
+class CbmPastaDigiData{
+
+};
+
+#endif //CBMPASTADIGIDATA_H
diff --git a/reco/app/cbmreco/main.cxx b/reco/app/cbmreco/main.cxx
index 6dd23efc44..2317119d53 100644
--- a/reco/app/cbmreco/main.cxx
+++ b/reco/app/cbmreco/main.cxx
@@ -43,6 +43,7 @@ std::shared_ptr<StorableRecoResults> makeStorableRecoResults(const fles::Timesli
   storable->TrdDigis()   = ToStdVector(results.trdDigis);
   storable->TofDigis()   = ToStdVector(results.tofDigis);
   storable->RichDigis()  = ToStdVector(results.richDigis);
+  storable->PastaDigis()  = ToStdVector(results.pastaDigis);
 
   storable->StsClusters() = results.stsClusters;
   storable->StsHits()     = results.stsHits;
-- 
GitLab


From 09858f2cb5163de68e2aa7aac3091d4c0264e215 Mon Sep 17 00:00:00 2001
From: Bartosz Sobol <bartosz.sobol@doctoral.uj.edu.pl>
Date: Fri, 24 Jan 2025 00:05:07 +0100
Subject: [PATCH 02/21] PASTA unpacker WIP

---
 algo/base/DigiData.cxx                 | 11 +++++++--
 algo/detectors/pasta/ReadoutConfig.cxx | 13 ++++++++++
 algo/detectors/pasta/ReadoutConfig.h   | 27 +++++++++++++++++---
 algo/detectors/pasta/Unpack.cxx        | 27 +++++++++++++++-----
 algo/detectors/pasta/Unpack.h          | 34 ++++++++++++++------------
 core/data/CbmDefs.h                    |  3 ++-
 core/data/base/CbmDigiData.h           |  4 +--
 core/data/pasta/CbmPastaDigi.h         |  2 ++
 core/data/pasta/CbmPastaDigiData.h     | 25 +++++++++++++++++--
 9 files changed, 113 insertions(+), 33 deletions(-)

diff --git a/algo/base/DigiData.cxx b/algo/base/DigiData.cxx
index 79fd5a4836..d075119cc5 100644
--- a/algo/base/DigiData.cxx
+++ b/algo/base/DigiData.cxx
@@ -21,6 +21,7 @@ DigiData::DigiData(const CbmDigiData& storable)
   , fRich(ToPODVector(storable.fRich.fDigis))
   , fPsd(ToPODVector(storable.fPsd.fDigis))
   , fFsd(ToPODVector(storable.fFsd.fDigis))
+  , fPasta(ToPODVector(storable.fPasta.fDigis))
 {
 }
 
@@ -36,6 +37,7 @@ size_t DigiData::Size(ECbmModuleId system) const
     case ECbmModuleId::kRich: return fRich.size();
     case ECbmModuleId::kPsd: return fPsd.size();
     case ECbmModuleId::kFsd: return fFsd.size();
+    case ECbmModuleId::kPasta: return fPasta.size();
     default: throw std::runtime_error("DigiData: Invalid system Id " + ::ToString(system));
   }
 }
@@ -43,14 +45,15 @@ size_t DigiData::Size(ECbmModuleId system) const
 size_t DigiData::TotalSize() const
 {
   return fSts.size() + fMuch.size() + fTof.size() + fBmon.size() + fTrd.size() + fTrd2d.size() + fRich.size()
-         + fPsd.size() + fFsd.size();
+         + fPsd.size() + fFsd.size() + fPasta.size();
 }
 
 size_t DigiData::TotalSizeBytes() const
 {
   return sizeof(CbmStsDigi) * fSts.size() + sizeof(CbmMuchDigi) * fMuch.size() + sizeof(CbmTofDigi) * fTof.size()
          + sizeof(CbmBmonDigi) * fBmon.size() + sizeof(CbmTrdDigi) * fTrd.size() + sizeof(CbmTrdDigi) * fTrd2d.size()
-         + sizeof(CbmRichDigi) * fRich.size() + sizeof(CbmPsdDigi) * fPsd.size() + sizeof(CbmFsdDigi) * fFsd.size();
+         + sizeof(CbmRichDigi) * fRich.size() + sizeof(CbmPsdDigi) * fPsd.size() + sizeof(CbmFsdDigi) * fFsd.size()
+         + sizeof(CbmPastaDigi) * fPasta.size();
 }
 
 CbmDigiData DigiData::ToStorable() const
@@ -92,6 +95,10 @@ CbmDigiData DigiData::ToStorable() const
       {
         .fDigis = ToStdVector(fFsd),
       },
+    .fPasta =
+      {
+        .fDigis = ToStdVector(fPasta),
+      },
   };
 }
 
diff --git a/algo/detectors/pasta/ReadoutConfig.cxx b/algo/detectors/pasta/ReadoutConfig.cxx
index 16c05d2484..b03a0246ba 100644
--- a/algo/detectors/pasta/ReadoutConfig.cxx
+++ b/algo/detectors/pasta/ReadoutConfig.cxx
@@ -3,3 +3,16 @@
    Authors: Bartosz Sobol [committer] */
 
 #include "ReadoutConfig.h"
+
+namespace cbm::algo::pasta
+{
+
+  ReadoutConfig::ReadoutConfig() {}
+
+  const ReadoutConfig::EquipmentIdsArray_t& ReadoutConfig::GetEquipmentIds() const { return fgEquipmentIds; }
+
+  const ReadoutConfig::TrbAddressArray_t& ReadoutConfig::GetTrbAddresses() const { return fgTRBAddresses; }
+
+  uint8_t ReadoutConfig::GetSystemVersion() const { return fgSystemVersion; }
+
+}  // namespace cbm::algo::pasta
\ No newline at end of file
diff --git a/algo/detectors/pasta/ReadoutConfig.h b/algo/detectors/pasta/ReadoutConfig.h
index aca3b205e7..7f688a7e70 100644
--- a/algo/detectors/pasta/ReadoutConfig.h
+++ b/algo/detectors/pasta/ReadoutConfig.h
@@ -4,11 +4,30 @@
 
 #pragma once
 
-namespace cbm::algo::pasta {
+#include <array>
+#include <cstdint>
 
-class ReadoutConfig {
+namespace cbm::algo::pasta
+{
 
-};
+  class ReadoutConfig {
 
+   public:
+    using TrbAddressArray_t   = std::array<uint32_t, 1>;
+    using EquipmentIdsArray_t = std::array<uint16_t, 1>;
 
-}
+    ReadoutConfig();
+
+    const EquipmentIdsArray_t& GetEquipmentIds() const;
+
+    const TrbAddressArray_t& GetTrbAddresses() const;
+
+    uint8_t GetSystemVersion() const;
+
+   private:
+    constexpr static TrbAddressArray_t fgTRBAddresses   = {0x9995};
+    constexpr static EquipmentIdsArray_t fgEquipmentIds = {0x3001};
+    constexpr static uint8_t fgSystemVersion            = 0x03;
+  };
+
+}  // namespace cbm::algo::pasta
diff --git a/algo/detectors/pasta/Unpack.cxx b/algo/detectors/pasta/Unpack.cxx
index 8d3a6d0456..67c83962d4 100644
--- a/algo/detectors/pasta/Unpack.cxx
+++ b/algo/detectors/pasta/Unpack.cxx
@@ -4,9 +4,24 @@
 
 #include "Unpack.h"
 
-namespace cbm {
-namespace algo {
-namespace pasta {
-} // pasta
-} // algo
-} // cbm
\ No newline at end of file
+#include "AlgoFairloggerCompat.h"
+
+
+namespace cbm::algo::pasta
+{
+  Unpack::Unpack(const ReadoutConfig& readout) : fReadout(readout)
+  {
+    const UnpackPar unpackPar{fReadout.GetTrbAddresses()};
+
+    for (const auto eqId : fReadout.GetEquipmentIds()) {
+      fAlgos.emplace({eqId, fReadout.GetSystemVersion()}, std::make_unique<UnpackMS>(unpackPar));
+
+      L_(info) << "--- Configured equipment " << eqId << " of PASTA@RICH.";
+    }
+
+    L_(info) << "--- Configured " << fAlgos.size() << " unpacker algorithms for PASTA@RICH.";
+  }
+
+  Unpack::Result_t Unpack::operator()(const fles::Timeslice& ts) const { return DoUnpack(fles::Subsystem::RICH, ts); }
+
+}  // namespace cbm::algo::pasta
\ No newline at end of file
diff --git a/algo/detectors/pasta/Unpack.h b/algo/detectors/pasta/Unpack.h
index 137f7aa985..e3f5f626be 100644
--- a/algo/detectors/pasta/Unpack.h
+++ b/algo/detectors/pasta/Unpack.h
@@ -3,27 +3,29 @@
    Authors: Bartosz Sobol [committer] */
 
 #pragma once
-#include <CommonUnpacker.h>
-#include <Timeslice.hpp>
 
-#include "CbmRichDigi.h"
+#include "CommonUnpacker.h"
 #include "ReadoutConfig.h"
 #include "UnpackMS.h"
 
-namespace cbm::algo::pasta {
-    namespace detail {
-        using UnpackBase = CommonUnpacker<CbmRichDigi, UnpackMonitorData, UnpackAuxData>;
-    }
+namespace cbm::algo::pasta
+{
 
-    class Unpack : public detail::UnpackBase {
-    public:
-        using Result_t = detail::UnpackBase::Result_t;
+  namespace detail
+  {
+    using UnpackBase = CommonUnpacker<CbmPastaDigi, UnpackMonitorData, UnpackAuxData>;
+  }
 
-        Unpack(const ReadoutConfig &readout);
+  class Unpack : public detail::UnpackBase {
+   public:
+    using Result_t = detail::UnpackBase::Result_t;
 
-        Result_t operator()(const fles::Timeslice &) const;
+    Unpack(const ReadoutConfig& readout);
 
-    private:
-        ReadoutConfig fReadout;
-    };
-} // cbm::algo::pasta
+    Result_t operator()(const fles::Timeslice&) const;
+
+   private:
+    ReadoutConfig fReadout;
+  };
+
+}  // namespace cbm::algo::pasta
diff --git a/core/data/CbmDefs.h b/core/data/CbmDefs.h
index 3b89430788..4e0471d999 100644
--- a/core/data/CbmDefs.h
+++ b/core/data/CbmDefs.h
@@ -60,7 +60,8 @@ enum class ECbmModuleId
   kPlatform   = 21,  ///< RICH rail platform
   kCave       = 22,  ///< Cave
   kLastModule = 23,  ///< For loops over all modules
-  kNotExist   = -1   ///< If not found
+  kNotExist   = -1,  ///< If not found
+  kPasta      = 100  ///< PANDA Straws //TODO
 };
 
 // operator ++ for ECbmModuleId for convenient usage in loops
diff --git a/core/data/base/CbmDigiData.h b/core/data/base/CbmDigiData.h
index 49f4ac8ff8..9f5a67caa6 100644
--- a/core/data/base/CbmDigiData.h
+++ b/core/data/base/CbmDigiData.h
@@ -42,7 +42,7 @@ class CbmDigiData {
   CbmTofDigiData fTof;    ///< TOF data
   CbmPsdDigiData fPsd;    ///< PSD data
   CbmFsdDigiData fFsd;    ///< FSD data
-  CbmFsdDigiData fPasta;  ///< PASTA data
+  CbmPastaDigiData fPasta;  ///< PASTA data
 
   friend class boost::serialization::access;
   /** @brief BOOST serializer**/
@@ -95,8 +95,8 @@ class CbmDigiData {
       case ECbmModuleId::kPsd: return fPsd.Size(); break;
       case ECbmModuleId::kRich: return fRich.Size(); break;
       case ECbmModuleId::kFsd: return fFsd.Size(); break;
+      case ECbmModuleId::kPasta: return fPasta.Size(); break;
       default: return 0; break;
-      //TODO add PASTA
     }
   }
 
diff --git a/core/data/pasta/CbmPastaDigi.h b/core/data/pasta/CbmPastaDigi.h
index 70382bf795..75369f53d5 100644
--- a/core/data/pasta/CbmPastaDigi.h
+++ b/core/data/pasta/CbmPastaDigi.h
@@ -8,6 +8,8 @@
 
 
 class CbmPastaDigi {
+public:
+
 
 };
 
diff --git a/core/data/pasta/CbmPastaDigiData.h b/core/data/pasta/CbmPastaDigiData.h
index e44c9e1e74..a64de1d0b1 100644
--- a/core/data/pasta/CbmPastaDigiData.h
+++ b/core/data/pasta/CbmPastaDigiData.h
@@ -7,8 +7,29 @@
 
 #include "CbmPastaDigi.h"
 
-class CbmPastaDigiData{
+#ifndef NO_ROOT
+#include <Rtypes.h>  // for ClassDef
+#endif
 
+#include <boost/serialization/vector.hpp>
+
+class CbmPastaDigiData {
+ public:
+  std::vector<CbmPastaDigi> fDigis{};
+
+  template<class Archive>
+  void serialize(Archive& ar, const unsigned int /*version*/)
+  {
+    ar & fDigis;
+  }
+
+  void Clear() { fDigis.clear(); }
+
+  size_t Size() const { return fDigis.size(); }
+
+#ifndef NO_ROOT
+  ClassDefNV(CbmPastaDigiData, 1);
+#endif
 };
 
-#endif //CBMPASTADIGIDATA_H
+#endif  //CBMPASTADIGIDATA_H
-- 
GitLab


From 2d5a4bb3d548cdf8926215bc9cdf404b2f80f087 Mon Sep 17 00:00:00 2001
From: Bartosz Sobol <bartosz.sobol@doctoral.uj.edu.pl>
Date: Fri, 24 Jan 2025 13:02:09 +0100
Subject: [PATCH 03/21] [PASTA] added pasta/UnpackMS as slightly modified copy
 of rich/UnpackMS

---
 algo/detectors/pasta/ReadoutConfig.h |   5 +-
 algo/detectors/pasta/Unpack.cxx      |   2 +-
 algo/detectors/pasta/UnpackMS.cxx    | 452 ++++++++++++++++++++++++++-
 algo/detectors/pasta/UnpackMS.h      | 267 +++++++++++++++-
 core/data/pasta/CbmPastaDigi.h       |  24 +-
 5 files changed, 734 insertions(+), 16 deletions(-)

diff --git a/algo/detectors/pasta/ReadoutConfig.h b/algo/detectors/pasta/ReadoutConfig.h
index 7f688a7e70..e942c3ea6b 100644
--- a/algo/detectors/pasta/ReadoutConfig.h
+++ b/algo/detectors/pasta/ReadoutConfig.h
@@ -13,7 +13,7 @@ namespace cbm::algo::pasta
   class ReadoutConfig {
 
    public:
-    using TrbAddressArray_t   = std::array<uint32_t, 1>;
+    using TrbAddressArray_t   = std::array<uint32_t, 8>;
     using EquipmentIdsArray_t = std::array<uint16_t, 1>;
 
     ReadoutConfig();
@@ -25,7 +25,8 @@ namespace cbm::algo::pasta
     uint8_t GetSystemVersion() const;
 
    private:
-    constexpr static TrbAddressArray_t fgTRBAddresses   = {0x9995};
+    constexpr static TrbAddressArray_t fgTRBAddresses   = {0x9992, 0x9993, 0x9994, 0x9995,
+                                                           0x9996, 0x9997, 0x9998, 0x9999};
     constexpr static EquipmentIdsArray_t fgEquipmentIds = {0x3001};
     constexpr static uint8_t fgSystemVersion            = 0x03;
   };
diff --git a/algo/detectors/pasta/Unpack.cxx b/algo/detectors/pasta/Unpack.cxx
index 67c83962d4..c63a81c064 100644
--- a/algo/detectors/pasta/Unpack.cxx
+++ b/algo/detectors/pasta/Unpack.cxx
@@ -14,7 +14,7 @@ namespace cbm::algo::pasta
     const UnpackPar unpackPar{fReadout.GetTrbAddresses()};
 
     for (const auto eqId : fReadout.GetEquipmentIds()) {
-      fAlgos.emplace({eqId, fReadout.GetSystemVersion()}, std::make_unique<UnpackMS>(unpackPar));
+      fAlgos.emplace(UnpackKey{eqId, fReadout.GetSystemVersion()}, std::make_unique<UnpackMS>(unpackPar));
 
       L_(info) << "--- Configured equipment " << eqId << " of PASTA@RICH.";
     }
diff --git a/algo/detectors/pasta/UnpackMS.cxx b/algo/detectors/pasta/UnpackMS.cxx
index 2cfb45b65d..2da9fd07a4 100644
--- a/algo/detectors/pasta/UnpackMS.cxx
+++ b/algo/detectors/pasta/UnpackMS.cxx
@@ -1,5 +1,455 @@
-/* Copyright (C) 2025 Jagiellonian University, Krakow
+/* Copyright (C) 2021-2025 Jagiellonian University, Krakow; Goethe-University Frankfurt, Frankfurt
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Bartosz Sobol [committer], Pascal Raisig, Dominik Smith */
 
 #include "UnpackMS.h"
+
+#include "AlgoFairloggerCompat.h"
+
+#include <cstdint>
+
+namespace cbm::algo::pasta
+{
+  UnpackMS::UnpackMS(const UnpackPar& pars) : fParams(pars) {}
+
+  UnpackMS::~UnpackMS() = default;
+
+  // ----   Algorithm execution   ---------------------------------------------
+  UnpackMS::Result_t UnpackMS::operator()(const uint8_t* msContent, const fles::MicrosliceDescriptor& msDescr,
+                                          const uint64_t tTimeslice) const
+  {
+    MSContext ctx;
+
+    // Clear CbmTime of MS. Used to get time offset of subtriggers to MS start
+    ctx.cbmTimeMS = 0;
+    ctx.digis.reserve(msDescr.size / sizeof(u32));
+
+    pasta::MicrosliceReader reader;
+    reader.SetData(msContent, msDescr.size);
+
+    const auto mstime = msDescr.idx;
+    ctx.refTime       = mstime - tTimeslice;
+
+    // There are a lot of MS  with 8 bytes size
+    // Does one need these MS?
+    if (reader.GetSize() <= 8) return {};
+
+    while (true) {
+      ProcessTrbPacket(reader, ctx);
+      ProcessHubBlock(reader, ctx);
+
+      // -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;
+    }
+    [[maybe_unused]] uint32_t msIndexWord1 = reader.NextWord();
+    [[maybe_unused]] uint32_t msIndexWord2 = reader.NextWord();
+
+    return std::make_tuple(std::move(ctx.digis), std::move(ctx.monitor), UnpackAuxData());
+  }
+
+
+  void UnpackMS::ProcessTrbPacket(pasta::MicrosliceReader& reader, MSContext& ctx) const
+  {
+    //process CBM time
+    const uint32_t word_MSB = reader.NextWord();  // CBM 63:32
+    const uint32_t word_LSB = reader.NextWord();  // CBM 31: 0
+    ctx.cbmTimePacket       = (uint64_t) word_MSB << 32 | word_LSB;
+    if (ctx.cbmTimeMS == 0) ctx.cbmTimeMS = ctx.cbmTimePacket;
+
+    //discard unused words
+    for (auto l = 0; l < 10; ++l) {
+      reader.NextWord();
+    }
+
+    //process remaining words
+    for (auto l = 0; l < 14; ++l) {
+      const uint32_t wordEpoch = reader.NextWord();
+      const uint32_t epoch     = ProcessEpoch(wordEpoch);
+      const uint32_t wordTime  = reader.NextWord();
+      const TdcTimeData td     = ProcessTimeData(wordTime);
+      const double fullTime    = CalculateTime(epoch, td.fCoarse, td.fFine);
+
+      if (l == 0) ctx.prevLastCh0ReTime[12] = fullTime;
+      if (l == 1) ctx.mbsCorr = fullTime - ctx.prevLastCh0ReTime[12];  // = MbsPrevTimeCh1 - MbsPrevTimeCh0
+      if (l > 1) ctx.prevLastCh0ReTime[l - 2] = fullTime;
+    }
+
+    [[maybe_unused]] const uint32_t trbNum = reader.NextWord();  // TRB trigger number
+  }
+
+
+  void UnpackMS::ProcessHubBlock(pasta::MicrosliceReader& reader, MSContext& ctx) const
+  {
+    uint32_t word = reader.NextWord();
+
+    [[maybe_unused]] const uint32_t hubId = word & 0xffff;          // 16 bits
+    const uint32_t hubSize                = (word >> 16) & 0xffff;  // 16 bits
+
+    bool isLast            = false;  // if true then it is CTS sub-sub-event
+    size_t totalSize       = 0;
+    ctx.currentSubSubEvent = 0;
+
+    uint32_t subSubEventId = 0, subSubEventSize = 0;
+
+    //loop over events in hub block
+    while (totalSize < hubSize) {
+      word            = reader.NextWord();
+      subSubEventId   = word & 0xffff;                              // 16 bits
+      subSubEventSize = (word >> 16) & 0xffff;                      // 16 bits
+      isLast          = reader.IsLastSubSubEvent(subSubEventSize);  // if true then it is CTS sub-sub-event
+      totalSize += (1 + subSubEventSize);
+
+      if (!isLast) {                                 // all except last are DiRICH events
+        if (((subSubEventId >> 12) & 0xF) != 0x7) {  // catch invalid ids
+          ctx.monitor.fNumErrInvalidHubId++;
+        }
+        if (totalSize == hubSize) {
+          ctx.monitor.fNumErrInvalidHubSize++;
+        }
+        ProcessSubSubEvent(reader, subSubEventSize, subSubEventId, ctx);
+        ctx.currentSubSubEvent++;
+      }
+    }
+
+    //last event ist expected to be CTS
+    if (totalSize != hubSize || !isLast) {
+      ctx.monitor.fNumErrInvalidHubSize++;
+    }
+    subSubEventSize = ProcessCtsHeader(reader, subSubEventSize, subSubEventId);
+    ProcessSubSubEvent(reader, subSubEventSize, subSubEventId, ctx);
+
+    // read last words
+    int lastWordsCounter = 0;
+    while (true) {
+      lastWordsCounter++;
+      word = reader.NextWord();
+      if (word == 0x600dda7a) {
+        if (reader.IsNextPadding()) word = reader.NextWord();
+        break;
+      }
+      if (lastWordsCounter >= 7) {
+        ctx.monitor.fNumErrExcessLastWords++;
+      }
+    }
+  }
+
+  int UnpackMS::ProcessCtsHeader(pasta::MicrosliceReader& reader, uint32_t subSubEventSize,
+                                 uint32_t /*subSubEventId*/) const
+  {
+    const uint32_t word = reader.NextWord();
+
+    [[maybe_unused]] const uint32_t ctsState = word & 0xffff;  // 16 bits
+
+    const uint32_t nofInputs    = (word >> 16) & 0xf;   // 4 bits
+    const uint32_t nofTrigCh    = (word >> 20) & 0x1f;  // 5 bits
+    const uint32_t inclLastIdle = (word >> 25) & 0x1;   // 1 bit
+    const uint32_t inclTrigInfo = (word >> 26) & 0x1;   // 1 bit
+    const uint32_t inclTime     = (word >> 27) & 0x1;   // 1 bit
+    const uint32_t ETM          = (word >> 28) & 0x3;   // 2 bits
+
+    uint32_t ctsInfoSize = 2 * nofInputs + 2 * nofTrigCh + 2 * inclLastIdle + 3 * inclTrigInfo + inclTime;  // in words
+    switch (ETM) {
+      case 0: break;
+      case 1: ctsInfoSize += 1; break;
+      case 2: ctsInfoSize += 4; break;
+      case 3: break;
+    }
+    for (uint32_t i = 0; i < ctsInfoSize; i++) {
+      reader.NextWord();  // do nothing?
+    }
+    const int nofTimeWords = subSubEventSize - ctsInfoSize - 1;
+    return nofTimeWords;
+  }
+
+  void UnpackMS::ProcessSubSubEvent(pasta::MicrosliceReader& reader, int nofTimeWords, uint32_t subSubEventId,
+                                    MSContext& ctx) const
+  {
+    bool wasHeader  = false;
+    bool wasEpoch   = false;
+    bool wasTime    = false;
+    bool wasTrailer = false;
+
+    uint32_t epoch = 0;  // store last epoch obtained in sub-sub-event
+
+    // Store last raising edge time for each channel or -1. if no time
+    // this array is used to match raising and falling edges
+    std::vector<double> raisingTime(33, -1.);
+
+    // check if DiRICH (SubSubEvId) is masked and skip to end if so
+    if (CheckMaskedDiRICH(subSubEventId)) {
+      for (int i = 0; i < nofTimeWords; i++) {
+        reader.NextWord();
+      }
+      return;
+    }
+
+    // Skip SubSubEvent for CTS and not PASTA addresses
+    if (std::find(fParams.fTRBAddresses.cbegin(), fParams.fTRBAddresses.cend(), subSubEventId)
+        == fParams.fTRBAddresses.end()) {
+      ctx.monitor.fNumCtsAndUnmappedDirich++;
+      ctx.monitor.fNumSkippedSubsubevent++;
+      for (int i = 0; i < nofTimeWords; i++) {
+        reader.NextWord();
+      }
+      return;
+    }
+
+    // Catch Subsubevents where some of the 3 "mandatory words" is missing
+    // but this lack was properly accounted/detected by the TRBnet/CTS
+    // => Otherwise the final readout of the Trailer word offsets the next
+    //    subsubevent
+    if (nofTimeWords < 3) {
+      ctx.monitor.fNumSkippedSubsubevent++;
+      for (int i = 0; i < nofTimeWords; i++) {
+        reader.NextWord();
+      }
+      return;
+    }
+
+    // First word is expected to be of type "header"
+    if (GetTdcWordType(reader.NextWord()) != TdcWordType::Header) {
+      L_(debug) << "DiRICH 0x" << std::hex << subSubEventId << std::dec
+                << ": 1st message is not a TDC Header, skipping subsubevent";
+      ctx.monitor.fNumErrInvalidFirstMessage++;
+      ctx.monitor.fNumSkippedSubsubevent++;
+      for (int i = 1; i < nofTimeWords; i++) {
+        reader.NextWord();
+      }
+      return;
+    }
+    else {
+      wasHeader = true;
+    }
+
+    // Second word is expected to be of type "epoch"
+    uint32_t word = reader.NextWord();
+    if (GetTdcWordType(word) != TdcWordType::Epoch) {
+      L_(debug) << "DiRICH 0x" << std::hex << subSubEventId << std::dec
+                << ": 2nd message is not an epoch, skipping subsubevent";
+      ctx.monitor.fNumErrInvalidSecondMessage++;
+      ctx.monitor.fNumSkippedSubsubevent++;
+      // Currently skip the subsubevent
+      // TODO: Check if possible to only skip to next Epoch and continue from there
+      for (int i = 2; i < nofTimeWords; i++) {
+        reader.NextWord();
+      }
+      return;
+    }
+    else {
+      epoch    = ProcessEpoch(word);
+      wasEpoch = true;
+    }
+
+    // Loop over words
+    for (int i = 2; i < nofTimeWords - 1; i++) {
+      word = reader.NextWord();
+      switch (GetTdcWordType(word)) {
+        case TdcWordType::TimeData: {
+          if (!wasHeader || !wasEpoch || wasTrailer) {
+            L_(debug) << "DiRICH 0x" << std::hex << subSubEventId << std::dec
+                      << ": illegal position of TDC Time (before header/epoch or after trailer)";
+            ctx.monitor.fNumErrWildTdcTime++;
+            ctx.monitor.fNumSkippedSubsubevent++;
+            // Currently skip the subsubevent
+            // TODO: Check if possible to only skip to next Epoch and continue from there
+            for (; i < nofTimeWords - 1; i++) {
+              reader.NextWord();
+            }
+            return;
+          }
+          wasTime = true;
+          ProcessTimeDataWord(epoch, word, subSubEventId, raisingTime, ctx);
+          break;
+        }
+        case TdcWordType::Epoch: {
+          if (!wasHeader || wasTrailer) {
+            L_(debug) << "DiRICH 0x" << std::hex << subSubEventId << std::dec
+                      << ": illegal position of TDC Epoch (before header or after trailer)";
+            ctx.monitor.fNumErrWildEpoch++;
+            ctx.monitor.fNumSkippedSubsubevent++;
+            for (; i < nofTimeWords - 1; i++) {
+              reader.NextWord();
+            }
+            return;
+          }
+          wasEpoch = true;
+          epoch    = ProcessEpoch(word);
+          break;
+        }
+        case TdcWordType::Header: {
+          if (wasEpoch || wasTime || wasTrailer) {
+            L_(debug) << "DiRICH 0x" << std::hex << subSubEventId << std::dec
+                      << ": illegal position of TDC Header (after time/epoch/trailer)";
+            ctx.monitor.fNumErrWildHeaderMessage++;
+            ctx.monitor.fNumSkippedSubsubevent++;
+            for (; i < nofTimeWords - 1; i++) {
+              reader.NextWord();
+            }
+            return;
+          }
+          ctx.monitor.fNumErrWildHeaderMessage++;
+          break;
+        }
+        case TdcWordType::Trailer: {
+          if (!wasEpoch || !wasTime || !wasHeader) {
+            L_(debug) << "DiRICH 0x" << std::hex << subSubEventId << std::dec
+                      << ": illegal position of TDC Trailer (before time/epoch/header)";
+            ctx.monitor.fNumErrWildTrailerMessage++;
+            ctx.monitor.fNumSkippedSubsubevent++;
+            for (; i < nofTimeWords - 1; i++) {
+              reader.NextWord();
+            }
+            return;
+          }
+          L_(debug) << "DiRICH 0x" << std::hex << subSubEventId << std::dec << ": TDC Trailer too early, "
+                    << (nofTimeWords - 1 - i) << " word(s) before last";
+          ctx.monitor.fNumErrWildTrailerMessage++;
+          wasTrailer = true;
+          break;
+        }
+        case TdcWordType::Debug: {
+          // for the moment do nothing
+          ctx.monitor.fNumDebugMessage++;
+          break;
+        }
+        case TdcWordType::Error: {
+          ctx.monitor.fNumErrTdcErrorWord++;
+          break;
+        }
+      }
+    }
+
+    // Last word is expected to be of type "trailer"
+    word = reader.NextWord();
+    if (GetTdcWordType(word) != TdcWordType::Trailer) {
+      L_(debug) << "DiRICH 0x" << std::hex << subSubEventId << std::dec << ": Last word not a TDC trailer";
+      ctx.monitor.fNumErrInvalidLastMessage++;
+      if (GetTdcWordType(word) == TdcWordType::TimeData && !wasTrailer) {
+        if (ProcessTimeDataWord(epoch, word, subSubEventId, raisingTime, ctx)) {
+          ctx.monitor.fNumWarnRecoveredLastDigi++;
+          L_(debug) << "DiRICH 0x" << std::hex << subSubEventId << std::dec
+                    << ": Rescuing TimeData in subsubevent with missing Trailer leading to saved Digi";
+        }
+        else {
+          ctx.monitor.fNumErrOrphanRecovTimeData++;
+          L_(debug) << "DiRICH 0x" << std::hex << subSubEventId << std::dec
+                    << ": Rescuing TimeData in subsubevent with missing Trailer w/o extra digi";
+        }
+      }
+    }
+  }
+
+  // ---- ProcessTimeDataWord ----
+  bool UnpackMS::ProcessTimeDataWord(uint32_t epoch, uint32_t tdcWord, uint32_t subSubEventId,
+                                     std::vector<double>& raisingTime, MSContext& ctx) const
+  {
+    const TdcTimeData td  = ProcessTimeData(tdcWord);
+    const double fullTime = CalculateTime(epoch, td.fCoarse, td.fFine);
+
+    bool madeDigi = false;
+    if (td.fChannel != 0) {
+      const double dT = fullTime - ctx.prevLastCh0ReTime[ctx.currentSubSubEvent];
+      const double subtrigOffset =
+        (ctx.cbmTimePacket - ctx.cbmTimeMS) * 25.0;  // offset of SubTrigger to MS start in ns
+      const double fullTimeCorr = dT - ctx.mbsCorr + subtrigOffset;
+
+      if (td.fChannel < 1 || td.fChannel >= raisingTime.size()) {
+        ctx.monitor.fNumErrChannelOutOfBounds++;
+        return false;
+      }
+      if (td.fIsRisingEdge) {
+        // 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.) {
+          // Matching was found, calculate ToT, if tot is in a good range -> create digi
+          const double ToT = fullTimeCorr - raisingTime[td.fChannel];
+          if (ToT >= fToTMin && ToT <= fToTMax) {
+            if (fullTimeCorr >= 0.0) {
+              WriteOutputDigi(subSubEventId, td.fChannel, raisingTime[td.fChannel], ToT, ctx);
+              L_(info) << "[PASTA DIGI] " << "TRBId: 0x" << std::hex << subSubEventId << std::dec << "; channel: 0x"
+                       << std::hex << td.fChannel << std::dec << "; raising time: " << raisingTime[td.fChannel]
+                       << "; ToT: " << ToT;
+              madeDigi = true;
+            }
+          }
+          // pair was created, set raising edge to -1.
+          raisingTime[td.fChannel] = -1.;
+        }
+      }
+    }
+    else {
+      ctx.monitor.fNumErrChannelOutOfBounds++;
+    }
+    return madeDigi;
+  }
+
+  double UnpackMS::CalculateTime(uint32_t epoch, uint32_t coarse, uint32_t fine) const
+  {
+    return ((double) epoch) * 2048. * 5. + ((double) coarse) * 5. - ((double) fine) * 0.005;
+  }
+
+  void UnpackMS::WriteOutputDigi(int32_t fpgaID, int32_t channel, double time, double tot, MSContext& ctx) const
+  {
+    ctx.digis.emplace_back();
+  }
+
+  bool UnpackMS::CheckMaskedDiRICH(int32_t subSubEventId) const
+  {
+    for (unsigned int i = 0; i < fMaskedDiRICHes.size(); ++i) {
+      if (fMaskedDiRICHes.at(i) == subSubEventId) return true;
+    }
+    return false;
+  }
+
+  TdcWordType UnpackMS::GetTdcWordType(uint32_t tdcWord) const
+  {
+    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 TdcWordType::TimeData;
+      }
+      else {
+        return TdcWordType::Error;
+      }
+    }
+    if (tdcMarker == 0x0) return TdcWordType::Trailer;
+    if (tdcMarker == 0x1) return TdcWordType::Header;
+    if (tdcMarker == 0x2) return TdcWordType::Debug;
+    if (tdcMarker == 0x3) return TdcWordType::Epoch;
+    return TdcWordType::Error;
+  }
+
+  int32_t UnpackMS::GetPixelUID(int32_t fpgaID, int32_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));
+  }
+
+  TdcTimeData UnpackMS::ProcessTimeData(uint32_t tdcWord) const
+  {
+    TdcTimeData out;
+    out.fCoarse       = static_cast<uint32_t>(tdcWord & 0x7ff);          // 11 bits
+    out.fIsRisingEdge = static_cast<uint32_t>((tdcWord >> 11) & 0x1);    // 1 bit
+    out.fFine         = static_cast<uint32_t>((tdcWord >> 12) & 0x3ff);  // 10 bits
+    out.fChannel      = static_cast<uint32_t>((tdcWord >> 22) & 0x7f);   // 7 bits
+    return out;
+  }
+
+  uint32_t UnpackMS::ProcessEpoch(uint32_t tdcWord) const { return static_cast<uint32_t>(tdcWord & 0xfffffff); }
+
+  uint16_t UnpackMS::ProcessHeader(uint32_t tdcWord) const
+  {
+    return static_cast<uint16_t>(tdcWord & 0xff);  //8 bits
+  }
+
+  uint16_t UnpackMS::ProcessTrailer(uint32_t tdcWord) const { return static_cast<uint16_t>(tdcWord & 0xffff); }
+
+}  // namespace cbm::algo::pasta
diff --git a/algo/detectors/pasta/UnpackMS.h b/algo/detectors/pasta/UnpackMS.h
index ce169a69ed..9c4786f3f8 100644
--- a/algo/detectors/pasta/UnpackMS.h
+++ b/algo/detectors/pasta/UnpackMS.h
@@ -1,17 +1,272 @@
-/* Copyright (C) 2025 Jagiellonian University, Krakow
+/* Copyright (C) 2021-2025 Jagiellonian University, Krakow; Goethe-University Frankfurt, Frankfurt
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Bartosz Sobol [committer], Pascal Raisig, Dominik Smith */
 
 #pragma once
 
-namespace cbm::algo::pasta {
+#include "CbmPastaDigi.h"
+#include "Definitions.h"
+#include "ReadoutConfig.h"
+#include "Timeslice.hpp"
+#include "UnpackMSBase.h"
 
-   class UnpackAuxData {};
+#include <cstddef>
+#include <cstdint>
+#include <iomanip>
+#include <memory>
+#include <sstream>
+#include <utility>
 
-class UnpackMS {
+namespace cbm::algo::pasta
+{
 
-};
+  class MicrosliceReader;
 
-}
+  enum class TdcWordType {
+    TimeData,
+    Header,
+    Epoch,
+    Trailer,
+    Debug,
+    Error
+  };
 
+  struct TdcTimeData {
+    uint32_t fCoarse       = 0;  // 11 bits
+    uint32_t fIsRisingEdge = 0;  // 1 bit
+    uint32_t fFine         = 0;  // 10 bits
+    uint32_t fChannel      = 0;  // 7 bits
+  };
 
+
+  /** @struct UnpackElinkPar
+   ** @author Dominik Smith <d.smith@gsi.de>
+   ** @since 26 May 2023
+   ** @brief RICH Unpacking parameters for one eLink / ASIC
+   **/
+  struct UnpackElinkPar {
+    std::vector<double> fToTshift;  ///< TOT shift for different channels
+    uint64_t fTimeOffset = 0.;      ///< Time calibration parameter
+  };
+
+
+  /** @struct UnpackPar
+   ** @author Dominik Smith <d.smith@gsi.de>
+   ** @since 26 May 2023
+   ** @brief Parameters required for the RICH unpacking (specific to one component)
+   **/
+  struct UnpackPar {
+    ReadoutConfig::TrbAddressArray_t fTRBAddresses;
+  };
+
+
+  /** @struct UnpackMonitorData
+   ** @author Dominik Smith <d.smith@gsi.de>
+   ** @since 26 May 2023
+   ** @brief Monitoring data for RICH unpacking
+   **/
+  struct UnpackMonitorData {
+    uint32_t fNumDebugMessage            = 0;  ///< Received debug messages
+    uint32_t fNumCtsAndUnmappedDirich    = 0;  ///< Dirich address is unknown (or is of a CTS)
+    uint32_t fNumErrInvalidFirstMessage  = 0;  ///< First message is not HEADER
+    uint32_t fNumErrInvalidSecondMessage = 0;  ///< Second message is not EPOCH
+    uint32_t fNumErrInvalidLastMessage   = 0;  ///< Last message is not TRAILER
+    uint32_t fNumErrWildHeaderMessage    = 0;  ///< TDC header in invalid position
+    uint32_t fNumErrWildTrailerMessage   = 0;  ///< TDC trailer in invalid position
+    uint32_t fNumErrWildEpoch            = 0;  ///< TDC epoch in invalid position
+    uint32_t fNumErrWildTdcTime          = 0;  ///< TDC time (digi) in invalid position
+    uint32_t fNumErrTdcErrorWord         = 0;  ///< TDC word of error type
+    uint32_t fNumErrChannelOutOfBounds   = 0;  ///< TDC channel out of bounds
+    uint32_t fNumErrOrphanRecovTimeData  = 0;  ///< TimeData in last position (not TRAILER) but not creating a Digi
+    uint32_t fNumWarnRecoveredLastDigi   = 0;  ///< TimeData in last position (not TRAILER) led to recovered Digi
+    uint32_t fNumErrInvalidHubId         = 0;  ///< "SubSubEvent" has invalid ID
+    uint32_t fNumErrInvalidHubSize       = 0;  ///< Premature end of hub block
+    uint32_t fNumErrExcessLastWords      = 0;  ///< More than expected trailing words
+    uint32_t fNumSkippedSubsubevent      = 0;  ///< Whenever subsubevent skipped due to error (but not mask)
+
+    bool HasErrors() const
+    {
+      uint32_t numErrors = fNumDebugMessage + fNumErrInvalidFirstMessage + fNumErrInvalidSecondMessage
+                           + fNumErrInvalidLastMessage + fNumErrWildHeaderMessage + fNumErrWildTrailerMessage
+                           + fNumErrWildEpoch + fNumErrWildTdcTime + fNumErrTdcErrorWord + fNumErrChannelOutOfBounds
+                           + fNumErrOrphanRecovTimeData + fNumErrInvalidHubId + fNumErrInvalidHubSize
+                           + fNumErrExcessLastWords;
+      return (numErrors > 0 ? true : false);
+    }
+    std::string print() const
+    {
+      std::stringstream ss;
+      ss << "errors " << fNumDebugMessage << " | " << fNumCtsAndUnmappedDirich << " | " << fNumErrInvalidFirstMessage
+         << " | " << fNumErrInvalidSecondMessage << " | " << fNumErrInvalidLastMessage << " | "
+         << fNumErrWildHeaderMessage << " | " << fNumErrWildTrailerMessage << " | " << fNumErrWildEpoch << " | "
+         << fNumErrWildTdcTime << " | " << fNumErrTdcErrorWord << " | " << fNumErrChannelOutOfBounds << " | "
+         << fNumErrOrphanRecovTimeData << " | " << fNumWarnRecoveredLastDigi << " | " << fNumErrInvalidHubId << " | "
+         << fNumErrInvalidHubSize << " | " << fNumErrExcessLastWords << " | " << fNumSkippedSubsubevent;
+      return ss.str();
+    }
+  };
+
+  /** @struct UnpackAux
+   ** @author Dominik Smith <d.smith@gsi.de>
+   ** @since 24 May 2024
+   ** @brief Auxiliary data for BMON unpacking
+   **/
+  struct UnpackAuxData {
+    ///// TO BE FILLED
+  };
+
+  class UnpackMS : public UnpackMSBase<CbmPastaDigi, UnpackMonitorData, UnpackAuxData> {
+
+   public:
+    UnpackMS() = delete;
+
+    /** @brief Construct from parameters **/
+    UnpackMS(const UnpackPar& pars);
+
+
+    /** @brief Destructor **/
+    ~UnpackMS() override;
+
+
+    /** @brief Algorithm execution
+     ** @param  msContent  Microslice payload
+     ** @param  msDescr    Microslice descriptor
+     ** @param  tTimeslice Unix start time of timeslice [ns]
+     ** @return RICH digi data
+     **/
+    Result_t operator()(const uint8_t* msContent, const fles::MicrosliceDescriptor& msDescr,
+                        const uint64_t tTimeslice) const override;
+
+    /** @brief Set the parameter container
+     ** @param params Pointer to parameter container
+     **/
+    void SetParams(std::unique_ptr<UnpackPar> params) { fParams = *(std::move(params)); }
+
+   private:
+    struct MSContext {
+      u64 cbmTimeMS     = 0;  // CbmTime of MS. Used to get time offset of subtriggers to MS start
+      u64 cbmTimePacket = 0;
+      u64 refTime       = 0;
+
+      // FIXME: Magic number, should be named.
+      //
+      // Comment from RICH expert (Martin Beyer):
+      //  > This number will also be valid for the Cbm Rich, 1 Rich backplane contains max. 12 DiRICHes.
+      //  > For the Cbm Rich the number of backplanes will be scaled
+      //  > up. Nevertheless it is very likely that fewer DiRiches(maybe not constant)
+      //  > per backplane are used in the day1 setup.
+      double prevLastCh0ReTime[13];  // 12 DiRICHes chnl0 + 1 CTS chnl0
+      double mbsCorr = 0.;
+
+      uint16_t currentSubSubEvent = 0;
+
+      std::vector<CbmPastaDigi> digis;
+      UnpackMonitorData monitor;
+    };
+
+    void ProcessTrbPacket(MicrosliceReader& reader, MSContext& ctx) const;
+
+    void ProcessHubBlock(MicrosliceReader& reader, MSContext& ctx) const;
+
+    int ProcessCtsHeader(MicrosliceReader& reader, uint32_t subSubEventSize, uint32_t subSubEventId) const;
+
+    void ProcessSubSubEvent(MicrosliceReader& reader, int nofTimeWords, uint32_t subSubEventId, MSContext& ctx) const;
+
+    bool ProcessTimeDataWord(uint32_t epoch, uint32_t tdcWord, uint32_t subSubEventId, std::vector<double>& raisingTime,
+                             MSContext& ctx) const;
+
+    TdcWordType GetTdcWordType(uint32_t tdcWord) const;
+
+    TdcTimeData ProcessTimeData(uint32_t tdcWord) const;
+
+    uint32_t ProcessEpoch(uint32_t tdcWord) const;
+
+    uint16_t ProcessHeader(uint32_t tdcWord) const;
+
+    uint16_t ProcessTrailer(uint32_t tdcWord) const;
+
+    void WriteOutputDigi(int32_t fpgaID, int32_t channel, double time, double tot, MSContext& ctx) const;
+
+    double CalculateTime(uint32_t epoch, uint32_t coarse, uint32_t fine) const;
+
+    int32_t GetPixelUID(int32_t fpgaID, int32_t ch) const;
+
+    bool CheckMaskedDiRICH(int32_t subSubEventId) const;
+
+    UnpackPar fParams;  ///< Parameter container
+
+    std::vector<int32_t> fMaskedDiRICHes;
+
+    bool fbDoToTCorr = true;  //activates ToT correction from parameter file
+
+    // uint64_t fCbmTimeMS;
+    // uint64_t fCbmTimePacket;
+
+    // double fMbsCorr = 0.;
+    // double fPrevLastCh0ReTime[13];  // 12 DiRICHes chnl0 + 1 CTS chnl0
+    // uint16_t fCurrentSubSubEvent = 0;
+
+    double fToTMin = -20.;
+    double fToTMax = 100.;
+  };
+
+
+  class MicrosliceReader {
+   private:
+    const uint8_t* fData = nullptr;
+    size_t fSize         = 0;
+    size_t fOffset       = 0;  // offset in bytes
+    size_t fWordCounter  = 0;
+    uint32_t fCurWord    = 0;
+
+   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()
+    {
+      uint32_t i = ((uint32_t*) (fData + fOffset))[0];
+      //swap bytes
+      i = (i >> 24) | ((i << 8) & 0x00FF0000) | ((i >> 8) & 0x0000FF00) | (i << 24);
+      fOffset += 4;
+      fWordCounter++;
+      fCurWord = i;
+      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;
+    }
+  };
+
+}  // namespace cbm::algo::pasta
diff --git a/core/data/pasta/CbmPastaDigi.h b/core/data/pasta/CbmPastaDigi.h
index 75369f53d5..8dd5d9f0bf 100644
--- a/core/data/pasta/CbmPastaDigi.h
+++ b/core/data/pasta/CbmPastaDigi.h
@@ -4,15 +4,27 @@
 
 #ifndef CBMPASTADIGI_H
 #define CBMPASTADIGI_H
-
+#include <cstdint>
 
 
 class CbmPastaDigi {
-public:
-
-
+ public:
+  template<class Archive>
+  void serialize(Archive& ar, const unsigned int /*version*/)
+  {
+    ar & fTRBId;
+    ar & fChannel;
+    ar & fTime;
+    ar & fToT;
+  }
+
+  double GetTime() const { return fTime; }
+
+  uint32_t fTRBId;
+  uint32_t fChannel;
+  double fTime;
+  double fToT;
 };
 
 
-
-#endif //CBMPASTADIGI_H
+#endif  //CBMPASTADIGI_H
-- 
GitLab


From b6ecb7b249a079af46f1184368e3d7f5e44423ce Mon Sep 17 00:00:00 2001
From: Bartosz Sobol <bartosz.sobol@doctoral.uj.edu.pl>
Date: Fri, 24 Jan 2025 13:16:06 +0100
Subject: [PATCH 04/21] [PASTA] pasta/UnpackMS differ log messages from rich,
 make rich/UnpackMS ignore PASTA data

---
 algo/detectors/pasta/UnpackMS.cxx     | 20 ++++++++++----------
 algo/detectors/rich/ReadoutConfig.cxx |  8 ++++----
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/algo/detectors/pasta/UnpackMS.cxx b/algo/detectors/pasta/UnpackMS.cxx
index 2da9fd07a4..f37df56c0c 100644
--- a/algo/detectors/pasta/UnpackMS.cxx
+++ b/algo/detectors/pasta/UnpackMS.cxx
@@ -210,7 +210,7 @@ namespace cbm::algo::pasta
 
     // First word is expected to be of type "header"
     if (GetTdcWordType(reader.NextWord()) != TdcWordType::Header) {
-      L_(debug) << "DiRICH 0x" << std::hex << subSubEventId << std::dec
+      L_(debug) << "PASTA DiRICH 0x" << std::hex << subSubEventId << std::dec
                 << ": 1st message is not a TDC Header, skipping subsubevent";
       ctx.monitor.fNumErrInvalidFirstMessage++;
       ctx.monitor.fNumSkippedSubsubevent++;
@@ -226,7 +226,7 @@ namespace cbm::algo::pasta
     // Second word is expected to be of type "epoch"
     uint32_t word = reader.NextWord();
     if (GetTdcWordType(word) != TdcWordType::Epoch) {
-      L_(debug) << "DiRICH 0x" << std::hex << subSubEventId << std::dec
+      L_(debug) << "PASTA DiRICH 0x" << std::hex << subSubEventId << std::dec
                 << ": 2nd message is not an epoch, skipping subsubevent";
       ctx.monitor.fNumErrInvalidSecondMessage++;
       ctx.monitor.fNumSkippedSubsubevent++;
@@ -248,7 +248,7 @@ namespace cbm::algo::pasta
       switch (GetTdcWordType(word)) {
         case TdcWordType::TimeData: {
           if (!wasHeader || !wasEpoch || wasTrailer) {
-            L_(debug) << "DiRICH 0x" << std::hex << subSubEventId << std::dec
+            L_(debug) << "PASTA DiRICH 0x" << std::hex << subSubEventId << std::dec
                       << ": illegal position of TDC Time (before header/epoch or after trailer)";
             ctx.monitor.fNumErrWildTdcTime++;
             ctx.monitor.fNumSkippedSubsubevent++;
@@ -265,7 +265,7 @@ namespace cbm::algo::pasta
         }
         case TdcWordType::Epoch: {
           if (!wasHeader || wasTrailer) {
-            L_(debug) << "DiRICH 0x" << std::hex << subSubEventId << std::dec
+            L_(debug) << "PASTA DiRICH 0x" << std::hex << subSubEventId << std::dec
                       << ": illegal position of TDC Epoch (before header or after trailer)";
             ctx.monitor.fNumErrWildEpoch++;
             ctx.monitor.fNumSkippedSubsubevent++;
@@ -280,7 +280,7 @@ namespace cbm::algo::pasta
         }
         case TdcWordType::Header: {
           if (wasEpoch || wasTime || wasTrailer) {
-            L_(debug) << "DiRICH 0x" << std::hex << subSubEventId << std::dec
+            L_(debug) << "PASTA DiRICH 0x" << std::hex << subSubEventId << std::dec
                       << ": illegal position of TDC Header (after time/epoch/trailer)";
             ctx.monitor.fNumErrWildHeaderMessage++;
             ctx.monitor.fNumSkippedSubsubevent++;
@@ -294,7 +294,7 @@ namespace cbm::algo::pasta
         }
         case TdcWordType::Trailer: {
           if (!wasEpoch || !wasTime || !wasHeader) {
-            L_(debug) << "DiRICH 0x" << std::hex << subSubEventId << std::dec
+            L_(debug) << "PASTA DiRICH 0x" << std::hex << subSubEventId << std::dec
                       << ": illegal position of TDC Trailer (before time/epoch/header)";
             ctx.monitor.fNumErrWildTrailerMessage++;
             ctx.monitor.fNumSkippedSubsubevent++;
@@ -303,7 +303,7 @@ namespace cbm::algo::pasta
             }
             return;
           }
-          L_(debug) << "DiRICH 0x" << std::hex << subSubEventId << std::dec << ": TDC Trailer too early, "
+          L_(debug) << "PASTA DiRICH 0x" << std::hex << subSubEventId << std::dec << ": TDC Trailer too early, "
                     << (nofTimeWords - 1 - i) << " word(s) before last";
           ctx.monitor.fNumErrWildTrailerMessage++;
           wasTrailer = true;
@@ -324,17 +324,17 @@ namespace cbm::algo::pasta
     // Last word is expected to be of type "trailer"
     word = reader.NextWord();
     if (GetTdcWordType(word) != TdcWordType::Trailer) {
-      L_(debug) << "DiRICH 0x" << std::hex << subSubEventId << std::dec << ": Last word not a TDC trailer";
+      L_(debug) << "PASTA DiRICH 0x" << std::hex << subSubEventId << std::dec << ": Last word not a TDC trailer";
       ctx.monitor.fNumErrInvalidLastMessage++;
       if (GetTdcWordType(word) == TdcWordType::TimeData && !wasTrailer) {
         if (ProcessTimeDataWord(epoch, word, subSubEventId, raisingTime, ctx)) {
           ctx.monitor.fNumWarnRecoveredLastDigi++;
-          L_(debug) << "DiRICH 0x" << std::hex << subSubEventId << std::dec
+          L_(debug) << "PASTA DiRICH 0x" << std::hex << subSubEventId << std::dec
                     << ": Rescuing TimeData in subsubevent with missing Trailer leading to saved Digi";
         }
         else {
           ctx.monitor.fNumErrOrphanRecovTimeData++;
-          L_(debug) << "DiRICH 0x" << std::hex << subSubEventId << std::dec
+          L_(debug) << "PASTA DiRICH 0x" << std::hex << subSubEventId << std::dec
                     << ": Rescuing TimeData in subsubevent with missing Trailer w/o extra digi";
         }
       }
diff --git a/algo/detectors/rich/ReadoutConfig.cxx b/algo/detectors/rich/ReadoutConfig.cxx
index cddc2ed1cd..5e9096018b 100644
--- a/algo/detectors/rich/ReadoutConfig.cxx
+++ b/algo/detectors/rich/ReadoutConfig.cxx
@@ -65,7 +65,7 @@ namespace cbm::algo::rich
 
     // Constants
     const uint16_t numComp          = 1;   // Number of components
-    const uint16_t numElinksPerComp = 87;  // Number of elinks per component (74 mRICH, 5 FSD/NCAL, 8 PASTA)
+    const uint16_t numElinksPerComp = 79;  // Number of elinks per component (74 mRICH, 5 FSD/NCAL, 8 PASTA)
     const uint16_t numChanPerElink  = 33;  // Number of channels per Elink
 
     // Equipment IDs for each component
@@ -79,7 +79,7 @@ namespace cbm::algo::rich
       0x7201, 0x7210, 0x7211, 0x7220, 0x7221, 0x7230, 0x7231, 0x7240, 0x7241, 0x7250, 0x7251, 0x7260, 0x7261,
       0x7270, 0x7271, 0x7280, 0x7281, 0x7300, 0x7301, 0x7310, 0x7311, 0x7320, 0x7321, 0x7330, 0x7331, 0x7340,
       0x7341, 0x7350, 0x7351, 0x7360, 0x7361, 0x7370, 0x7371, 0x7380, 0x7381, 0x7901, 0x7902, 0x7903, 0x7904,
-      0x7905, 0x9991, 0x9992, 0x9993, 0x9994, 0x9995, 0x9996, 0x9997, 0x9998};
+      0x7905/*, 0x9991, 0x9992, 0x9993, 0x9994, 0x9995, 0x9996, 0x9997, 0x9998*/};
     // TRBaddresses 0x7901 and 0x7902 are for FSD/NCAL
     // TRBaddresses 0x9991 to 0x9998 are for PASTA
 
@@ -318,7 +318,7 @@ namespace cbm::algo::rich
        10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00},
       {0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
        10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-       10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00},
+       10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00}/*,
       {0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
        10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
        10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00},
@@ -342,7 +342,7 @@ namespace cbm::algo::rich
        10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00},
       {0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
        10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-       10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00}};
+       10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00}*/};
 
     // Constructing the map (equipmentId, asic address, channel) -> (tot shift)
     for (uint16_t comp = 0; comp < numComp; comp++) {
-- 
GitLab


From 30ad78a86ab079f52401870c5455ccc549683345 Mon Sep 17 00:00:00 2001
From: Bartosz Sobol <bartosz.sobol@doctoral.uj.edu.pl>
Date: Fri, 24 Jan 2025 18:10:20 +0100
Subject: [PATCH 05/21] [PASTA] fix pasta TRB IDs

---
 algo/detectors/pasta/ReadoutConfig.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/algo/detectors/pasta/ReadoutConfig.h b/algo/detectors/pasta/ReadoutConfig.h
index e942c3ea6b..bf75843cc4 100644
--- a/algo/detectors/pasta/ReadoutConfig.h
+++ b/algo/detectors/pasta/ReadoutConfig.h
@@ -25,8 +25,8 @@ namespace cbm::algo::pasta
     uint8_t GetSystemVersion() const;
 
    private:
-    constexpr static TrbAddressArray_t fgTRBAddresses   = {0x9992, 0x9993, 0x9994, 0x9995,
-                                                           0x9996, 0x9997, 0x9998, 0x9999};
+    constexpr static TrbAddressArray_t fgTRBAddresses   = {0x9991, 0x9993, 0x9994, 0x9995,
+                                                           0x9996, 0x9997, 0x9998, 0x9998};
     constexpr static EquipmentIdsArray_t fgEquipmentIds = {0x3001};
     constexpr static uint8_t fgSystemVersion            = 0x03;
   };
-- 
GitLab


From eb541c97c1d481cad87ade5d3b83329f6d90399f Mon Sep 17 00:00:00 2001
From: Bartosz Sobol <bartosz.sobol@doctoral.uj.edu.pl>
Date: Mon, 27 Jan 2025 00:16:49 +0100
Subject: [PATCH 06/21] [PASTA] fix pasta TRB IDs

---
 algo/detectors/pasta/ReadoutConfig.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/algo/detectors/pasta/ReadoutConfig.h b/algo/detectors/pasta/ReadoutConfig.h
index bf75843cc4..ddbb8b534f 100644
--- a/algo/detectors/pasta/ReadoutConfig.h
+++ b/algo/detectors/pasta/ReadoutConfig.h
@@ -25,8 +25,8 @@ namespace cbm::algo::pasta
     uint8_t GetSystemVersion() const;
 
    private:
-    constexpr static TrbAddressArray_t fgTRBAddresses   = {0x9991, 0x9993, 0x9994, 0x9995,
-                                                           0x9996, 0x9997, 0x9998, 0x9998};
+    constexpr static TrbAddressArray_t fgTRBAddresses   = {0x9991, 0x9992, 0x9993, 0x9994,
+                                                           0x9995, 0x9996, 0x9997, 0x9998};
     constexpr static EquipmentIdsArray_t fgEquipmentIds = {0x3001};
     constexpr static uint8_t fgSystemVersion            = 0x03;
   };
-- 
GitLab


From a3f34131543930e6e2e363e5f4dbbb4e1258756b Mon Sep 17 00:00:00 2001
From: Bartosz Sobol <bartosz.sobol@doctoral.uj.edu.pl>
Date: Tue, 28 Jan 2025 00:12:05 +0100
Subject: [PATCH 07/21] [PASTA] fix digi write

---
 algo/detectors/pasta/UnpackMS.cxx |  4 ++--
 algo/detectors/pasta/UnpackMS.h   |  2 +-
 core/data/pasta/CbmPastaDigi.h    | 10 ++++++++++
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/algo/detectors/pasta/UnpackMS.cxx b/algo/detectors/pasta/UnpackMS.cxx
index f37df56c0c..80c4ed2e1d 100644
--- a/algo/detectors/pasta/UnpackMS.cxx
+++ b/algo/detectors/pasta/UnpackMS.cxx
@@ -392,9 +392,9 @@ namespace cbm::algo::pasta
     return ((double) epoch) * 2048. * 5. + ((double) coarse) * 5. - ((double) fine) * 0.005;
   }
 
-  void UnpackMS::WriteOutputDigi(int32_t fpgaID, int32_t channel, double time, double tot, MSContext& ctx) const
+  void UnpackMS::WriteOutputDigi(uint32_t trbId, uint16_t channel, double time, double tot, MSContext& ctx) const
   {
-    ctx.digis.emplace_back();
+    ctx.digis.emplace_back(trbId, channel, time, tot);
   }
 
   bool UnpackMS::CheckMaskedDiRICH(int32_t subSubEventId) const
diff --git a/algo/detectors/pasta/UnpackMS.h b/algo/detectors/pasta/UnpackMS.h
index 9c4786f3f8..a1691675ef 100644
--- a/algo/detectors/pasta/UnpackMS.h
+++ b/algo/detectors/pasta/UnpackMS.h
@@ -185,7 +185,7 @@ namespace cbm::algo::pasta
 
     uint16_t ProcessTrailer(uint32_t tdcWord) const;
 
-    void WriteOutputDigi(int32_t fpgaID, int32_t channel, double time, double tot, MSContext& ctx) const;
+    void WriteOutputDigi(uint32_t trbId, uint16_t channel, double time, double tot, MSContext& ctx) const;
 
     double CalculateTime(uint32_t epoch, uint32_t coarse, uint32_t fine) const;
 
diff --git a/core/data/pasta/CbmPastaDigi.h b/core/data/pasta/CbmPastaDigi.h
index 8dd5d9f0bf..b35ad25c4e 100644
--- a/core/data/pasta/CbmPastaDigi.h
+++ b/core/data/pasta/CbmPastaDigi.h
@@ -9,6 +9,16 @@
 
 class CbmPastaDigi {
  public:
+  CbmPastaDigi() = default;
+
+  CbmPastaDigi(const uint32_t trbId, const uint32_t channel, const double time, const double tot)
+    : fTRBId{trbId}
+    , fChannel{channel}
+    , fTime{time}
+    , fToT{tot}
+  {
+  }
+
   template<class Archive>
   void serialize(Archive& ar, const unsigned int /*version*/)
   {
-- 
GitLab


From 82fc63b635a5bd43ff399714090c74fa5c3f6f99 Mon Sep 17 00:00:00 2001
From: Bartosz Sobol <bartosz.sobol@doctoral.uj.edu.pl>
Date: Fri, 31 Jan 2025 02:35:55 +0100
Subject: [PATCH 08/21] [PASTA] implement DigiQa

---
 algo/CMakeLists.txt            |  1 +
 algo/base/Definitions.h        |  2 +
 algo/global/Reco.cxx           | 10 +++++
 algo/global/Reco.h             |  2 +
 algo/qa/unpack/PastaDigiQa.cxx | 75 ++++++++++++++++++++++++++++++++++
 algo/qa/unpack/PastaDigiQa.h   | 51 +++++++++++++++++++++++
 6 files changed, 141 insertions(+)
 create mode 100644 algo/qa/unpack/PastaDigiQa.cxx
 create mode 100644 algo/qa/unpack/PastaDigiQa.h

diff --git a/algo/CMakeLists.txt b/algo/CMakeLists.txt
index f0d829c4b0..5aed22a236 100644
--- a/algo/CMakeLists.txt
+++ b/algo/CMakeLists.txt
@@ -162,6 +162,7 @@ set(SRCS
   qa/hitfind/BmonHitfindQa.cxx
   qa/hitfind/BmonHitfindQaParameters.cxx
   qa/unpack/StsDigiQa.cxx
+        qa/unpack/PastaDigiQa.cxx
   ca/TrackingSetup.cxx
   ca/TrackingChain.cxx
   ca/qa/CaQa.cxx
diff --git a/algo/base/Definitions.h b/algo/base/Definitions.h
index b1ff4c9ccc..3cde44e913 100644
--- a/algo/base/Definitions.h
+++ b/algo/base/Definitions.h
@@ -67,6 +67,7 @@ namespace cbm::algo
     UnpackMuch,
     UnpackTof,
     UnpackFsd,
+    UnpackPasta,
     EventBuilding,
     RecoBmon,
     RecoSts,
@@ -139,6 +140,7 @@ CBM_ENUM_DICT(cbm::algo::QaStep,
   {"UnpackMuch", cbm::algo::QaStep::UnpackMuch},
   {"UnpackTof", cbm::algo::QaStep::UnpackTof},
   {"UnpackFsd", cbm::algo::QaStep::UnpackFsd},
+  {"UnpackPasta", cbm::algo::QaStep::UnpackPasta},
   {"EventBuilding", cbm::algo::QaStep::EventBuilding},
   {"RecoBmon", cbm::algo::QaStep::RecoBmon},
   {"RecoSts", cbm::algo::QaStep::RecoSts},
diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx
index 1085ecd758..bf8a6d4e09 100644
--- a/algo/global/Reco.cxx
+++ b/algo/global/Reco.cxx
@@ -11,6 +11,7 @@
 #include "Exceptions.h"
 #include "HistogramSender.h"
 #include "ParFiles.h"
+#include "PastaDigiQa.h"
 #include "RecoGeneralQa.h"
 #include "StsDigiQa.h"
 #include "TrackingSetup.h"
@@ -143,8 +144,12 @@ void Reco::Init(const Options& opts)
   if (Opts().Has(Subsystem::RICH) && Opts().Has(Step::Unpack)) {
     rich::ReadoutConfig richCfg{};
     fRichUnpack = std::make_unique<rich::Unpack>(richCfg);
+
     pasta::ReadoutConfig pastaCfg{};
     fPastaUnpack = std::make_unique<pasta::Unpack>(pastaCfg);
+    if (fSender != nullptr && Opts().Has(QaStep::UnpackPasta)) {
+      fPastaDigiQa = std::make_unique<pasta::DigiQa>(fSender, pastaCfg);
+    }
   }
 
   if (Opts().Has(Subsystem::STS) && Opts().Has(Step::Unpack)) {
@@ -338,6 +343,11 @@ RecoResults Reco::Run(const fles::Timeslice& ts)
                << " TRD2D=" << digis.fTrd2d.size() << " RICH=" << digis.fRich.size() << " PSD=" << digis.fPsd.size()
                << " FSD=" << digis.fFsd.size() << " PASTA=" << digis.fPasta.size();
       // --- Raw digi QAs
+
+      if (fSender != nullptr && Opts().Has(QaStep::UnpackPasta)) {
+        fPastaDigiQa->Exec(digis.fPasta, ts.index());
+      }
+
       if (fSender != nullptr && Opts().Has(Subsystem::STS)) {
         fStsDigiQa->RegisterDigiData(&digis.fSts);
         fStsDigiQa->RegisterAuxDigiData(&auxDigis.fSts);
diff --git a/algo/global/Reco.h b/algo/global/Reco.h
index 3ccb4b5ea1..481069615d 100644
--- a/algo/global/Reco.h
+++ b/algo/global/Reco.h
@@ -49,6 +49,7 @@ namespace cbm::algo
   namespace pasta
   {
     class Unpack;
+    class DigiQa;
   }
 
   namespace sts
@@ -173,6 +174,7 @@ namespace cbm::algo
 
     // PASTA
     std::unique_ptr<pasta::Unpack> fPastaUnpack;
+    std::unique_ptr<pasta::DigiQa> fPastaDigiQa;  ///< Raw PASTA-digis QA
 
     // STS
     std::unique_ptr<sts::Unpack> fStsUnpack;
diff --git a/algo/qa/unpack/PastaDigiQa.cxx b/algo/qa/unpack/PastaDigiQa.cxx
new file mode 100644
index 0000000000..96783fa3c8
--- /dev/null
+++ b/algo/qa/unpack/PastaDigiQa.cxx
@@ -0,0 +1,75 @@
+/* Copyright (C) 2025 Jagiellonian University, Krakow
+SPDX-License-Identifier: GPL-3.0-only
+Authors: Bartosz Sobol [committer] */
+
+#include "PastaDigiQa.h"
+
+#include <fmt/format.h>
+
+namespace cbm::algo::pasta
+{
+  DigiQa::DigiQa(std::shared_ptr<HistogramSender> pSender, const ReadoutConfig& config)
+    : fQaData{"RawDigi/PASTA"}
+    , fpSender{pSender}
+    , fReadoutSetup(config)
+  {
+    if (fpSender.get() == nullptr) {
+      return;
+    }
+
+    for (auto iTRB = 0; iTRB < config.GetTrbAddresses().size(); ++iTRB) {
+      const auto TRBId = config.GetTrbAddresses().at(iTRB);
+
+      auto canvas = qa::CanvasConfig(fmt::format("pasta_digi/pasta_digi_vs_channel_tot_{:x}", TRBId),
+                                     fmt::format("PASTA digis per channel and ToT for TRB 0x{:x}", TRBId), 2, 1);
+
+      {
+        fChannelHists.emplace_back(fQaData.MakeObj<qa::H1D>(
+          fmt::format("pasta_digi_{:x}_channel", TRBId),
+          fmt::format("Digis per channel for TRB 0x{:x};channel;N_{{digis}}", TRBId), 32, 0, 32));
+
+        auto pad = qa::PadConfig();
+        pad.RegisterHistogram(fChannelHists[iTRB], "hist");
+        canvas.AddPadConfig(pad);
+      }
+      {
+        fTotHists.emplace_back(fQaData.MakeObj<qa::H1D>(fmt::format("pasta_digi_{:x}_tot", TRBId),
+                                                        fmt::format("ToT for TRB 0x{:x};ToT;N_{{digis}}", TRBId), 20,
+                                                        30, 50));
+        auto pad = qa::PadConfig();
+        pad.RegisterHistogram(fTotHists[iTRB], "hist");
+        canvas.AddPadConfig(pad);
+      }
+
+      fQaData.AddCanvasConfig(canvas);
+    }
+
+    fQaData.Init(fpSender);
+  }
+
+  void DigiQa::Exec(const PODVector<CbmPastaDigi>& digis, const uint64_t tsIndex)
+  {
+    if (fpSender.get() == nullptr) {
+      return;
+    }
+
+    fQaData.SetTimesliceId(tsIndex);
+
+    for (const auto& digi : digis) {
+      const auto iHist = digi.fTRBId - fReadoutSetup.GetTrbAddresses()[0];
+
+      if (iHist >= fChannelHists.size()) {
+        L_(error) << fmt::format("pasta::DigiQa: digi TRBId {:x} out of range", digi.fTRBId);
+        continue;
+      }
+
+      fChannelHists[iHist]->Fill(digi.fChannel);
+      fTotHists[iHist]->Fill(digi.fToT);
+    }
+
+    fQaData.Send(fpSender);
+  }
+
+  void DigiQa::operator()(const PODVector<CbmPastaDigi>& digis, const uint64_t tsIndex) { Exec(digis, tsIndex); }
+
+}  // namespace cbm::algo::pasta
\ No newline at end of file
diff --git a/algo/qa/unpack/PastaDigiQa.h b/algo/qa/unpack/PastaDigiQa.h
new file mode 100644
index 0000000000..875a226951
--- /dev/null
+++ b/algo/qa/unpack/PastaDigiQa.h
@@ -0,0 +1,51 @@
+/* Copyright (C) 2025 Jagiellonian University, Krakow
+SPDX-License-Identifier: GPL-3.0-only
+Authors: Bartosz Sobol [committer] */
+
+#pragma once
+
+#include "CbmPastaDigi.h"
+#include "QaBase.h"
+
+#include <CommonUnpacker.h>
+#include <pasta/ReadoutConfig.h>
+
+namespace cbm::algo::pasta
+{
+  /* TODO probably cbm::algo::sts::QaBase can be used here as a base class, but for some reason it is in sts namespace.
+   * IMO it should be only in cbm::algo and be a base for all QA classes?
+   * For now I'm doing similar impl/interface, but without inheritance.
+  */
+  /// \class cbm::algo::pasta::DigiQa
+  /// \brief QA module for PASTA raw digis
+  class DigiQa {
+   public:
+    /// \brief Main constructor with HistogramSender
+    DigiQa(std::shared_ptr<HistogramSender> pSender, const ReadoutConfig& config);
+
+    DigiQa() = delete;
+
+    DigiQa(const DigiQa&) = delete;
+
+    DigiQa(DigiQa&&) = delete;
+
+    DigiQa& operator=(const DigiQa&) = delete;
+
+    DigiQa& operator=(DigiQa&&) = delete;
+
+    /// \brief Executes QA (filling histograms)
+    void Exec(const PODVector<CbmPastaDigi>& digis, uint64_t tsIndex);
+
+    /// \brief Executes QA (filling histograms), see Exec()
+    void operator()(const PODVector<CbmPastaDigi>& digis, uint64_t tsIndex);
+
+   private:
+    std::vector<qa::H1D*> fChannelHists{};  ///< histograms: nDigis per channel per TRB
+    std::vector<qa::H1D*> fTotHists{};      ///< histograms: ToT per TRB
+
+    qa::Data fQaData;
+    std::shared_ptr<HistogramSender> fpSender;
+    ReadoutConfig fReadoutSetup;
+  };
+
+}  // namespace cbm::algo::pasta
\ No newline at end of file
-- 
GitLab


From 80a96261f4f2a6196384fc94b1868640ae2d8def Mon Sep 17 00:00:00 2001
From: Bartosz Sobol <bartosz.sobol@doctoral.uj.edu.pl>
Date: Fri, 31 Jan 2025 10:51:14 +0100
Subject: [PATCH 09/21] [PASTA] details

---
 algo/qa/unpack/PastaDigiQa.cxx | 30 +++++++++++++-----------------
 1 file changed, 13 insertions(+), 17 deletions(-)

diff --git a/algo/qa/unpack/PastaDigiQa.cxx b/algo/qa/unpack/PastaDigiQa.cxx
index 96783fa3c8..0b3bed6e14 100644
--- a/algo/qa/unpack/PastaDigiQa.cxx
+++ b/algo/qa/unpack/PastaDigiQa.cxx
@@ -23,23 +23,19 @@ namespace cbm::algo::pasta
       auto canvas = qa::CanvasConfig(fmt::format("pasta_digi/pasta_digi_vs_channel_tot_{:x}", TRBId),
                                      fmt::format("PASTA digis per channel and ToT for TRB 0x{:x}", TRBId), 2, 1);
 
-      {
-        fChannelHists.emplace_back(fQaData.MakeObj<qa::H1D>(
-          fmt::format("pasta_digi_{:x}_channel", TRBId),
-          fmt::format("Digis per channel for TRB 0x{:x};channel;N_{{digis}}", TRBId), 32, 0, 32));
-
-        auto pad = qa::PadConfig();
-        pad.RegisterHistogram(fChannelHists[iTRB], "hist");
-        canvas.AddPadConfig(pad);
-      }
-      {
-        fTotHists.emplace_back(fQaData.MakeObj<qa::H1D>(fmt::format("pasta_digi_{:x}_tot", TRBId),
-                                                        fmt::format("ToT for TRB 0x{:x};ToT;N_{{digis}}", TRBId), 20,
-                                                        30, 50));
-        auto pad = qa::PadConfig();
-        pad.RegisterHistogram(fTotHists[iTRB], "hist");
-        canvas.AddPadConfig(pad);
-      }
+      fChannelHists.emplace_back(fQaData.MakeObj<qa::H1D>(
+        fmt::format("pasta_digi_{:x}_channel", TRBId),
+        fmt::format("Digis per channel for TRB 0x{:x};channel;N_{{digis}}", TRBId), 32, 0, 32));
+
+      auto padChannels = qa::PadConfig();
+      padChannels.RegisterHistogram(fChannelHists[iTRB], "hist");
+      canvas.AddPadConfig(padChannels);
+      fTotHists.emplace_back(fQaData.MakeObj<qa::H1D>(fmt::format("pasta_digi_{:x}_tot", TRBId),
+                                                      fmt::format("ToT for TRB 0x{:x};ToT;N_{{digis}}", TRBId), 20, 30,
+                                                      50));
+      auto padTot = qa::PadConfig();
+      padTot.RegisterHistogram(fTotHists[iTRB], "hist");
+      canvas.AddPadConfig(padTot);
 
       fQaData.AddCanvasConfig(canvas);
     }
-- 
GitLab


From 46502f8d0c6c9e6cba0e37748361b76f431b3c5d Mon Sep 17 00:00:00 2001
From: Bartosz Sobol <bartosz.sobol@doctoral.uj.edu.pl>
Date: Fri, 31 Jan 2025 13:29:55 +0100
Subject: [PATCH 10/21] [PASTA] fix format

---
 algo/detectors/pasta/ReadoutConfig.cxx |  2 +-
 algo/detectors/pasta/Unpack.cxx        |  2 +-
 algo/qa/unpack/PastaDigiQa.cxx         | 10 +++++-----
 algo/qa/unpack/PastaDigiQa.h           |  6 +++---
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/algo/detectors/pasta/ReadoutConfig.cxx b/algo/detectors/pasta/ReadoutConfig.cxx
index b03a0246ba..5056ed97d7 100644
--- a/algo/detectors/pasta/ReadoutConfig.cxx
+++ b/algo/detectors/pasta/ReadoutConfig.cxx
@@ -15,4 +15,4 @@ namespace cbm::algo::pasta
 
   uint8_t ReadoutConfig::GetSystemVersion() const { return fgSystemVersion; }
 
-}  // namespace cbm::algo::pasta
\ No newline at end of file
+}  // namespace cbm::algo::pasta
diff --git a/algo/detectors/pasta/Unpack.cxx b/algo/detectors/pasta/Unpack.cxx
index c63a81c064..d80af3cc5e 100644
--- a/algo/detectors/pasta/Unpack.cxx
+++ b/algo/detectors/pasta/Unpack.cxx
@@ -24,4 +24,4 @@ namespace cbm::algo::pasta
 
   Unpack::Result_t Unpack::operator()(const fles::Timeslice& ts) const { return DoUnpack(fles::Subsystem::RICH, ts); }
 
-}  // namespace cbm::algo::pasta
\ No newline at end of file
+}  // namespace cbm::algo::pasta
diff --git a/algo/qa/unpack/PastaDigiQa.cxx b/algo/qa/unpack/PastaDigiQa.cxx
index 0b3bed6e14..745a62f14b 100644
--- a/algo/qa/unpack/PastaDigiQa.cxx
+++ b/algo/qa/unpack/PastaDigiQa.cxx
@@ -1,6 +1,6 @@
 /* Copyright (C) 2025 Jagiellonian University, Krakow
-SPDX-License-Identifier: GPL-3.0-only
-Authors: Bartosz Sobol [committer] */
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Bartosz Sobol [committer] */
 
 #include "PastaDigiQa.h"
 
@@ -13,7 +13,7 @@ namespace cbm::algo::pasta
     , fpSender{pSender}
     , fReadoutSetup(config)
   {
-    if (fpSender.get() == nullptr) {
+    if (fpSender == nullptr) {
       return;
     }
 
@@ -45,7 +45,7 @@ namespace cbm::algo::pasta
 
   void DigiQa::Exec(const PODVector<CbmPastaDigi>& digis, const uint64_t tsIndex)
   {
-    if (fpSender.get() == nullptr) {
+    if (fpSender == nullptr) {
       return;
     }
 
@@ -68,4 +68,4 @@ namespace cbm::algo::pasta
 
   void DigiQa::operator()(const PODVector<CbmPastaDigi>& digis, const uint64_t tsIndex) { Exec(digis, tsIndex); }
 
-}  // namespace cbm::algo::pasta
\ No newline at end of file
+}  // namespace cbm::algo::pasta
diff --git a/algo/qa/unpack/PastaDigiQa.h b/algo/qa/unpack/PastaDigiQa.h
index 875a226951..ab4f11fa7f 100644
--- a/algo/qa/unpack/PastaDigiQa.h
+++ b/algo/qa/unpack/PastaDigiQa.h
@@ -1,6 +1,6 @@
 /* Copyright (C) 2025 Jagiellonian University, Krakow
-SPDX-License-Identifier: GPL-3.0-only
-Authors: Bartosz Sobol [committer] */
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Bartosz Sobol [committer] */
 
 #pragma once
 
@@ -48,4 +48,4 @@ namespace cbm::algo::pasta
     ReadoutConfig fReadoutSetup;
   };
 
-}  // namespace cbm::algo::pasta
\ No newline at end of file
+}  // namespace cbm::algo::pasta
-- 
GitLab


From e51a48a2a076ca81b40830caadb2bb1365b7bed3 Mon Sep 17 00:00:00 2001
From: Bartosz Sobol <bartosz.sobol@doctoral.uj.edu.pl>
Date: Fri, 31 Jan 2025 18:20:30 +0100
Subject: [PATCH 11/21] [PASTA] fix format 2

---
 algo/base/AuxDigiData.h               |  2 +-
 algo/base/DigiData.h                  |  4 ++--
 algo/detectors/pasta/UnpackMS.cxx     |  6 +++---
 algo/detectors/rich/ReadoutConfig.cxx | 18 ++++++++++--------
 algo/global/Reco.h                    |  2 +-
 core/data/base/CbmDigiData.h          |  2 +-
 reco/app/cbmreco/main.cxx             |  2 +-
 7 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/algo/base/AuxDigiData.h b/algo/base/AuxDigiData.h
index 0f67256afc..9fdda66f06 100644
--- a/algo/base/AuxDigiData.h
+++ b/algo/base/AuxDigiData.h
@@ -12,8 +12,8 @@
 #include "CommonUnpacker.h"
 #include "bmon/UnpackMS.h"
 #include "much/UnpackMS.h"
-#include "rich/UnpackMS.h"
 #include "pasta/UnpackMS.h"
+#include "rich/UnpackMS.h"
 #include "sts/UnpackMS.h"
 #include "tof/UnpackMS.h"
 #include "trd/UnpackMS.h"
diff --git a/algo/base/DigiData.h b/algo/base/DigiData.h
index 14f8ec848d..6e8877f21c 100644
--- a/algo/base/DigiData.h
+++ b/algo/base/DigiData.h
@@ -10,9 +10,9 @@
 #include "CbmEventTriggers.h"
 #include "CbmFsdDigi.h"
 #include "CbmMuchDigi.h"
+#include "CbmPastaDigi.h"
 #include "CbmPsdDigi.h"
 #include "CbmRichDigi.h"
-#include "CbmPastaDigi.h"
 #include "CbmStsDigi.h"
 #include "CbmTofDigi.h"
 #include "CbmTrdDigi.h"
@@ -40,7 +40,7 @@ namespace cbm::algo
     PODVector<CbmRichDigi> fRich;  ///< Unpacked RICH digis
     PODVector<CbmPsdDigi> fPsd;    ///< Unpacked PSD digis
     PODVector<CbmFsdDigi> fFsd;    ///< Unpacked FSD digis
-    PODVector<CbmPastaDigi> fPasta;///< Unpacked PASTA digis
+    PODVector<CbmPastaDigi> fPasta;  ///< Unpacked PASTA digis
 
     DigiData();
     ~DigiData();
diff --git a/algo/detectors/pasta/UnpackMS.cxx b/algo/detectors/pasta/UnpackMS.cxx
index 80c4ed2e1d..2366e69e02 100644
--- a/algo/detectors/pasta/UnpackMS.cxx
+++ b/algo/detectors/pasta/UnpackMS.cxx
@@ -370,9 +370,9 @@ namespace cbm::algo::pasta
           if (ToT >= fToTMin && ToT <= fToTMax) {
             if (fullTimeCorr >= 0.0) {
               WriteOutputDigi(subSubEventId, td.fChannel, raisingTime[td.fChannel], ToT, ctx);
-              L_(info) << "[PASTA DIGI] " << "TRBId: 0x" << std::hex << subSubEventId << std::dec << "; channel: 0x"
-                       << std::hex << td.fChannel << std::dec << "; raising time: " << raisingTime[td.fChannel]
-                       << "; ToT: " << ToT;
+              L_(info) << "[PASTA DIGI] "
+                       << "TRBId: 0x" << std::hex << subSubEventId << std::dec << "; channel: 0x" << std::hex
+                       << td.fChannel << std::dec << "; raising time: " << raisingTime[td.fChannel] << "; ToT: " << ToT;
               madeDigi = true;
             }
           }
diff --git a/algo/detectors/rich/ReadoutConfig.cxx b/algo/detectors/rich/ReadoutConfig.cxx
index 5e9096018b..78099eeeda 100644
--- a/algo/detectors/rich/ReadoutConfig.cxx
+++ b/algo/detectors/rich/ReadoutConfig.cxx
@@ -72,14 +72,16 @@ namespace cbm::algo::rich
     // This number is written to the data stream (MicrosliceDescriptor).
     uint16_t eqId[numComp] = {12289};
 
-    uint32_t TRBaddresses[numElinksPerComp] = {
-      0xc000, 0xc001, 0x7000, 0x7001, 0x7010, 0x7011, 0x7020, 0x7021, 0x7030, 0x7031, 0x7040, 0x7041, 0x7050,
-      0x7051, 0x7060, 0x7061, 0x7070, 0x7071, 0x7080, 0x7081, 0x7100, 0x7101, 0x7110, 0x7111, 0x7120, 0x7121,
-      0x7130, 0x7131, 0x7140, 0x7141, 0x7150, 0x7151, 0x7160, 0x7161, 0x7170, 0x7171, 0x7180, 0x7181, 0x7200,
-      0x7201, 0x7210, 0x7211, 0x7220, 0x7221, 0x7230, 0x7231, 0x7240, 0x7241, 0x7250, 0x7251, 0x7260, 0x7261,
-      0x7270, 0x7271, 0x7280, 0x7281, 0x7300, 0x7301, 0x7310, 0x7311, 0x7320, 0x7321, 0x7330, 0x7331, 0x7340,
-      0x7341, 0x7350, 0x7351, 0x7360, 0x7361, 0x7370, 0x7371, 0x7380, 0x7381, 0x7901, 0x7902, 0x7903, 0x7904,
-      0x7905/*, 0x9991, 0x9992, 0x9993, 0x9994, 0x9995, 0x9996, 0x9997, 0x9998*/};
+    uint32_t
+      TRBaddresses[numElinksPerComp] =
+        {
+          0xc000, 0xc001, 0x7000, 0x7001, 0x7010, 0x7011, 0x7020, 0x7021, 0x7030, 0x7031, 0x7040, 0x7041,
+          0x7050, 0x7051, 0x7060, 0x7061, 0x7070, 0x7071, 0x7080, 0x7081, 0x7100, 0x7101, 0x7110, 0x7111,
+          0x7120, 0x7121, 0x7130, 0x7131, 0x7140, 0x7141, 0x7150, 0x7151, 0x7160, 0x7161, 0x7170, 0x7171,
+          0x7180, 0x7181, 0x7200, 0x7201, 0x7210, 0x7211, 0x7220, 0x7221, 0x7230, 0x7231, 0x7240, 0x7241,
+          0x7250, 0x7251, 0x7260, 0x7261, 0x7270, 0x7271, 0x7280, 0x7281, 0x7300, 0x7301, 0x7310, 0x7311,
+          0x7320, 0x7321, 0x7330, 0x7331, 0x7340, 0x7341, 0x7350, 0x7351, 0x7360, 0x7361, 0x7370, 0x7371,
+          0x7380, 0x7381, 0x7901, 0x7902, 0x7903, 0x7904, 0x7905 /*, 0x9991, 0x9992, 0x9993, 0x9994, 0x9995, 0x9996, 0x9997, 0x9998*/};
     // TRBaddresses 0x7901 and 0x7902 are for FSD/NCAL
     // TRBaddresses 0x9991 to 0x9998 are for PASTA
 
diff --git a/algo/global/Reco.h b/algo/global/Reco.h
index 481069615d..7f763c7855 100644
--- a/algo/global/Reco.h
+++ b/algo/global/Reco.h
@@ -50,7 +50,7 @@ namespace cbm::algo
   {
     class Unpack;
     class DigiQa;
-  }
+  }  // namespace pasta
 
   namespace sts
   {
diff --git a/core/data/base/CbmDigiData.h b/core/data/base/CbmDigiData.h
index 9f5a67caa6..8317e3971c 100644
--- a/core/data/base/CbmDigiData.h
+++ b/core/data/base/CbmDigiData.h
@@ -9,12 +9,12 @@
 #include "CbmBmonDigiData.h"
 #include "CbmFsdDigiData.h"
 #include "CbmMuchDigiData.h"
+#include "CbmPastaDigiData.h"
 #include "CbmPsdDigiData.h"
 #include "CbmRichDigiData.h"
 #include "CbmStsDigiData.h"
 #include "CbmTofDigiData.h"
 #include "CbmTrdDigiData.h"
-#include "CbmPastaDigiData.h"
 
 #include <boost/serialization/access.hpp>
 #include <boost/serialization/base_object.hpp>
diff --git a/reco/app/cbmreco/main.cxx b/reco/app/cbmreco/main.cxx
index 2317119d53..8bb47de69b 100644
--- a/reco/app/cbmreco/main.cxx
+++ b/reco/app/cbmreco/main.cxx
@@ -43,7 +43,7 @@ std::shared_ptr<StorableRecoResults> makeStorableRecoResults(const fles::Timesli
   storable->TrdDigis()   = ToStdVector(results.trdDigis);
   storable->TofDigis()   = ToStdVector(results.tofDigis);
   storable->RichDigis()  = ToStdVector(results.richDigis);
-  storable->PastaDigis()  = ToStdVector(results.pastaDigis);
+  storable->PastaDigis() = ToStdVector(results.pastaDigis);
 
   storable->StsClusters() = results.stsClusters;
   storable->StsHits()     = results.stsHits;
-- 
GitLab


From ec43cddd47f58d1142f1f7afc0a51538452e9ff9 Mon Sep 17 00:00:00 2001
From: Bartosz Sobol <bartosz.sobol@doctoral.uj.edu.pl>
Date: Fri, 31 Jan 2025 18:33:32 +0100
Subject: [PATCH 12/21] [PASTA] fix format 3, final

---
 algo/detectors/pasta/ReadoutConfig.h | 2 +-
 algo/detectors/pasta/UnpackMS.h      | 3 ++-
 core/data/pasta/CbmPastaDigi.h       | 8 ++++----
 core/data/pasta/CbmPastaDigiData.h   | 2 +-
 4 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/algo/detectors/pasta/ReadoutConfig.h b/algo/detectors/pasta/ReadoutConfig.h
index ddbb8b534f..38eacf2c77 100644
--- a/algo/detectors/pasta/ReadoutConfig.h
+++ b/algo/detectors/pasta/ReadoutConfig.h
@@ -26,7 +26,7 @@ namespace cbm::algo::pasta
 
    private:
     constexpr static TrbAddressArray_t fgTRBAddresses   = {0x9991, 0x9992, 0x9993, 0x9994,
-                                                           0x9995, 0x9996, 0x9997, 0x9998};
+                                                         0x9995, 0x9996, 0x9997, 0x9998};
     constexpr static EquipmentIdsArray_t fgEquipmentIds = {0x3001};
     constexpr static uint8_t fgSystemVersion            = 0x03;
   };
diff --git a/algo/detectors/pasta/UnpackMS.h b/algo/detectors/pasta/UnpackMS.h
index a1691675ef..eafea45aa2 100644
--- a/algo/detectors/pasta/UnpackMS.h
+++ b/algo/detectors/pasta/UnpackMS.h
@@ -22,7 +22,8 @@ namespace cbm::algo::pasta
 
   class MicrosliceReader;
 
-  enum class TdcWordType {
+  enum class TdcWordType
+  {
     TimeData,
     Header,
     Epoch,
diff --git a/core/data/pasta/CbmPastaDigi.h b/core/data/pasta/CbmPastaDigi.h
index b35ad25c4e..2b0d841627 100644
--- a/core/data/pasta/CbmPastaDigi.h
+++ b/core/data/pasta/CbmPastaDigi.h
@@ -22,10 +22,10 @@ class CbmPastaDigi {
   template<class Archive>
   void serialize(Archive& ar, const unsigned int /*version*/)
   {
-    ar & fTRBId;
-    ar & fChannel;
-    ar & fTime;
-    ar & fToT;
+    ar& fTRBId;
+    ar& fChannel;
+    ar& fTime;
+    ar& fToT;
   }
 
   double GetTime() const { return fTime; }
diff --git a/core/data/pasta/CbmPastaDigiData.h b/core/data/pasta/CbmPastaDigiData.h
index a64de1d0b1..b788bc99b4 100644
--- a/core/data/pasta/CbmPastaDigiData.h
+++ b/core/data/pasta/CbmPastaDigiData.h
@@ -20,7 +20,7 @@ class CbmPastaDigiData {
   template<class Archive>
   void serialize(Archive& ar, const unsigned int /*version*/)
   {
-    ar & fDigis;
+    ar& fDigis;
   }
 
   void Clear() { fDigis.clear(); }
-- 
GitLab


From 358c467f29831a85fafffae32a0d21c6df4e7703 Mon Sep 17 00:00:00 2001
From: Bartosz Sobol <bartosz.sobol@doctoral.uj.edu.pl>
Date: Mon, 3 Feb 2025 00:22:03 +0100
Subject: [PATCH 13/21] [PASTA/MUST] move DigiQa initialization to Init()
 method

---
 algo/global/Reco.cxx           |  1 +
 algo/qa/unpack/PastaDigiQa.cxx | 14 +++++++++-----
 algo/qa/unpack/PastaDigiQa.h   |  7 +++++--
 3 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx
index bf8a6d4e09..0e669b4f50 100644
--- a/algo/global/Reco.cxx
+++ b/algo/global/Reco.cxx
@@ -149,6 +149,7 @@ void Reco::Init(const Options& opts)
     fPastaUnpack = std::make_unique<pasta::Unpack>(pastaCfg);
     if (fSender != nullptr && Opts().Has(QaStep::UnpackPasta)) {
       fPastaDigiQa = std::make_unique<pasta::DigiQa>(fSender, pastaCfg);
+      fPastaDigiQa->Init();
     }
   }
 
diff --git a/algo/qa/unpack/PastaDigiQa.cxx b/algo/qa/unpack/PastaDigiQa.cxx
index 745a62f14b..125e1b9c0a 100644
--- a/algo/qa/unpack/PastaDigiQa.cxx
+++ b/algo/qa/unpack/PastaDigiQa.cxx
@@ -8,17 +8,21 @@
 
 namespace cbm::algo::pasta
 {
-  DigiQa::DigiQa(std::shared_ptr<HistogramSender> pSender, const ReadoutConfig& config)
+  DigiQa::DigiQa(std::shared_ptr<HistogramSender> pSender, const ReadoutConfig& readoutConfig)
     : fQaData{"RawDigi/PASTA"}
     , fpSender{pSender}
-    , fReadoutSetup(config)
+    , fReadoutConfig(readoutConfig)
+  {
+  }
+
+  void DigiQa::Init()
   {
     if (fpSender == nullptr) {
       return;
     }
 
-    for (auto iTRB = 0; iTRB < config.GetTrbAddresses().size(); ++iTRB) {
-      const auto TRBId = config.GetTrbAddresses().at(iTRB);
+    for (auto iTRB = 0; iTRB < fReadoutConfig.GetTrbAddresses().size(); ++iTRB) {
+      const auto TRBId = fReadoutConfig.GetTrbAddresses().at(iTRB);
 
       auto canvas = qa::CanvasConfig(fmt::format("pasta_digi/pasta_digi_vs_channel_tot_{:x}", TRBId),
                                      fmt::format("PASTA digis per channel and ToT for TRB 0x{:x}", TRBId), 2, 1);
@@ -52,7 +56,7 @@ namespace cbm::algo::pasta
     fQaData.SetTimesliceId(tsIndex);
 
     for (const auto& digi : digis) {
-      const auto iHist = digi.fTRBId - fReadoutSetup.GetTrbAddresses()[0];
+      const auto iHist = digi.fTRBId - fReadoutConfig.GetTrbAddresses()[0];
 
       if (iHist >= fChannelHists.size()) {
         L_(error) << fmt::format("pasta::DigiQa: digi TRBId {:x} out of range", digi.fTRBId);
diff --git a/algo/qa/unpack/PastaDigiQa.h b/algo/qa/unpack/PastaDigiQa.h
index ab4f11fa7f..fe671f8069 100644
--- a/algo/qa/unpack/PastaDigiQa.h
+++ b/algo/qa/unpack/PastaDigiQa.h
@@ -21,7 +21,7 @@ namespace cbm::algo::pasta
   class DigiQa {
    public:
     /// \brief Main constructor with HistogramSender
-    DigiQa(std::shared_ptr<HistogramSender> pSender, const ReadoutConfig& config);
+    DigiQa(std::shared_ptr<HistogramSender> pSender, const ReadoutConfig& readoutConfig);
 
     DigiQa() = delete;
 
@@ -33,6 +33,9 @@ namespace cbm::algo::pasta
 
     DigiQa& operator=(DigiQa&&) = delete;
 
+    /// \brief Initializes QA (initialization of histograms and canvases)
+    void Init();
+
     /// \brief Executes QA (filling histograms)
     void Exec(const PODVector<CbmPastaDigi>& digis, uint64_t tsIndex);
 
@@ -45,7 +48,7 @@ namespace cbm::algo::pasta
 
     qa::Data fQaData;
     std::shared_ptr<HistogramSender> fpSender;
-    ReadoutConfig fReadoutSetup;
+    ReadoutConfig fReadoutConfig;
   };
 
 }  // namespace cbm::algo::pasta
-- 
GitLab


From 8ee42968805df751cb5d2c7490fc614e3b87d08a Mon Sep 17 00:00:00 2001
From: Bartosz Sobol <bartosz.sobol@doctoral.uj.edu.pl>
Date: Mon, 3 Feb 2025 02:44:17 +0100
Subject: [PATCH 14/21] [PASTA/MUST] ReadoutConfig from YAML file

---
 algo/detectors/pasta/ReadoutConfig.cxx  | 16 +++++++++------
 algo/detectors/pasta/ReadoutConfig.h    | 26 ++++++++++++++-----------
 algo/detectors/pasta/UnpackMS.h         |  2 +-
 algo/global/ParFiles.cxx                |  2 ++
 algo/global/ParFiles.h                  |  4 ++++
 algo/global/Reco.cxx                    |  4 +++-
 macro/must/MustReadout_mcbm2025_02.yaml |  3 +++
 7 files changed, 38 insertions(+), 19 deletions(-)
 create mode 100644 macro/must/MustReadout_mcbm2025_02.yaml

diff --git a/algo/detectors/pasta/ReadoutConfig.cxx b/algo/detectors/pasta/ReadoutConfig.cxx
index 5056ed97d7..4c1aaea395 100644
--- a/algo/detectors/pasta/ReadoutConfig.cxx
+++ b/algo/detectors/pasta/ReadoutConfig.cxx
@@ -4,15 +4,19 @@
 
 #include "ReadoutConfig.h"
 
-namespace cbm::algo::pasta
+namespace cbm::algo
 {
+  CBM_YAML_INSTANTIATE(pasta::ReadoutConfig);
 
-  ReadoutConfig::ReadoutConfig() {}
+  namespace pasta
+  {
 
-  const ReadoutConfig::EquipmentIdsArray_t& ReadoutConfig::GetEquipmentIds() const { return fgEquipmentIds; }
+    const std::vector<uint16_t>& ReadoutConfig::GetEquipmentIds() const { return fEquipmentIds; }
 
-  const ReadoutConfig::TrbAddressArray_t& ReadoutConfig::GetTrbAddresses() const { return fgTRBAddresses; }
+    const std::vector<uint32_t>& ReadoutConfig::GetTrbAddresses() const { return fTRBAddresses; }
 
-  uint8_t ReadoutConfig::GetSystemVersion() const { return fgSystemVersion; }
+    uint8_t ReadoutConfig::GetSystemVersion() const { return fSystemVersion; }
 
-}  // namespace cbm::algo::pasta
+  }  // namespace pasta
+
+}  // namespace cbm::algo
diff --git a/algo/detectors/pasta/ReadoutConfig.h b/algo/detectors/pasta/ReadoutConfig.h
index 38eacf2c77..74c56caae1 100644
--- a/algo/detectors/pasta/ReadoutConfig.h
+++ b/algo/detectors/pasta/ReadoutConfig.h
@@ -4,6 +4,9 @@
 
 #pragma once
 
+#include "yaml/Property.h"
+#include "yaml/Yaml.h"
+
 #include <array>
 #include <cstdint>
 
@@ -13,22 +16,23 @@ namespace cbm::algo::pasta
   class ReadoutConfig {
 
    public:
-    using TrbAddressArray_t   = std::array<uint32_t, 8>;
-    using EquipmentIdsArray_t = std::array<uint16_t, 1>;
-
-    ReadoutConfig();
+    ReadoutConfig() = default;
 
-    const EquipmentIdsArray_t& GetEquipmentIds() const;
+    const std::vector<uint16_t>& GetEquipmentIds() const;
 
-    const TrbAddressArray_t& GetTrbAddresses() const;
+    const std::vector<uint32_t>& GetTrbAddresses() const;
 
     uint8_t GetSystemVersion() const;
 
-   private:
-    constexpr static TrbAddressArray_t fgTRBAddresses   = {0x9991, 0x9992, 0x9993, 0x9994,
-                                                         0x9995, 0x9996, 0x9997, 0x9998};
-    constexpr static EquipmentIdsArray_t fgEquipmentIds = {0x3001};
-    constexpr static uint8_t fgSystemVersion            = 0x03;
+    std::vector<uint16_t> fEquipmentIds{};
+    std::vector<uint32_t> fTRBAddresses{};
+    uint8_t fSystemVersion{};
+
+    CBM_YAML_PROPERTIES(yaml::Property(&ReadoutConfig::fEquipmentIds, "equipmentIds", "List of equipment IDs", {}, YAML::Flow),
+                        yaml::Property(&ReadoutConfig::fTRBAddresses, "TRBAddresses", "List of TRB addresses",  {}, YAML::Flow),
+                        yaml::Property(&ReadoutConfig::fSystemVersion, "systemVersion", "System version"));
   };
 
 }  // namespace cbm::algo::pasta
+
+CBM_YAML_EXTERN_DECL(cbm::algo::pasta::ReadoutConfig);
diff --git a/algo/detectors/pasta/UnpackMS.h b/algo/detectors/pasta/UnpackMS.h
index eafea45aa2..faf4ad6d5e 100644
--- a/algo/detectors/pasta/UnpackMS.h
+++ b/algo/detectors/pasta/UnpackMS.h
@@ -57,7 +57,7 @@ namespace cbm::algo::pasta
    ** @brief Parameters required for the RICH unpacking (specific to one component)
    **/
   struct UnpackPar {
-    ReadoutConfig::TrbAddressArray_t fTRBAddresses;
+    std::vector<uint32_t> fTRBAddresses;
   };
 
 
diff --git a/algo/global/ParFiles.cxx b/algo/global/ParFiles.cxx
index 9d4e8ee2cd..779694a2b7 100644
--- a/algo/global/ParFiles.cxx
+++ b/algo/global/ParFiles.cxx
@@ -22,6 +22,8 @@ ParFiles::ParFiles(uint32_t runId)
     setup = Setup::mCBM2025_02;
   }
 
+  must.readout = "MustReadout_mcbm2025_02.yaml";  //TODO this should be moved to 2025 case when available
+
   switch (setup) {
 
     case Setup::mCBM2022:
diff --git a/algo/global/ParFiles.h b/algo/global/ParFiles.h
index 0fe7b3094b..b95f695782 100644
--- a/algo/global/ParFiles.h
+++ b/algo/global/ParFiles.h
@@ -55,6 +55,10 @@ namespace cbm::algo
       fs::path mainConfig;
     } ca;
 
+    struct {
+      fs::path readout;
+    } must;
+
     struct {
       fs::path V0FinderConfig;
     } kfp;
diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx
index 0e669b4f50..16f5e31dd3 100644
--- a/algo/global/Reco.cxx
+++ b/algo/global/Reco.cxx
@@ -145,7 +145,9 @@ void Reco::Init(const Options& opts)
     rich::ReadoutConfig richCfg{};
     fRichUnpack = std::make_unique<rich::Unpack>(richCfg);
 
-    pasta::ReadoutConfig pastaCfg{};
+    //TODO handle under fles::Subsystem::MUST when available
+    pasta::ReadoutConfig pastaCfg =
+      yaml::ReadFromFile<pasta::ReadoutConfig>(Opts().ParamsDir() / parFiles.must.readout);
     fPastaUnpack = std::make_unique<pasta::Unpack>(pastaCfg);
     if (fSender != nullptr && Opts().Has(QaStep::UnpackPasta)) {
       fPastaDigiQa = std::make_unique<pasta::DigiQa>(fSender, pastaCfg);
diff --git a/macro/must/MustReadout_mcbm2025_02.yaml b/macro/must/MustReadout_mcbm2025_02.yaml
new file mode 100644
index 0000000000..023f6e7ee9
--- /dev/null
+++ b/macro/must/MustReadout_mcbm2025_02.yaml
@@ -0,0 +1,3 @@
+systemVersion: 0x03
+equipmentIds: [ 0x3001 ]
+TRBAddresses: [ 0x9991, 0x9992, 0x9993, 0x9994, 0x9995, 0x9996, 0x9997, 0x9998 ]
-- 
GitLab


From f2fccf04e7b8841c664db1ee143ebddc952d8f67 Mon Sep 17 00:00:00 2001
From: Bartosz Sobol <bartosz.sobol@doctoral.uj.edu.pl>
Date: Mon, 3 Feb 2025 03:03:26 +0100
Subject: [PATCH 15/21] [PASTA/MUST] rename PASTA to MUST

---
 algo/CMakeLists.txt                           | 10 ++---
 algo/base/AuxDigiData.h                       |  4 +-
 algo/base/Definitions.h                       |  4 +-
 algo/base/DigiData.cxx                        | 12 +++---
 algo/base/DigiData.h                          |  4 +-
 algo/data/CMakeLists.txt                      |  4 +-
 .../{pasta => must}/ReadoutConfig.cxx         |  6 +--
 .../detectors/{pasta => must}/ReadoutConfig.h |  6 +--
 algo/detectors/{pasta => must}/Unpack.cxx     |  8 ++--
 algo/detectors/{pasta => must}/Unpack.h       |  6 +--
 algo/detectors/{pasta => must}/UnpackMS.cxx   | 38 +++++++++----------
 algo/detectors/{pasta => must}/UnpackMS.h     | 10 ++---
 algo/detectors/rich/ReadoutConfig.cxx         |  4 +-
 algo/global/Reco.cxx                          | 25 ++++++------
 algo/global/Reco.h                            | 10 ++---
 algo/global/RecoResults.h                     |  2 +-
 algo/global/StorableRecoResults.h             |  8 ++--
 .../{PastaDigiQa.cxx => MustDigiQa.cxx}       | 22 +++++------
 .../qa/unpack/{PastaDigiQa.h => MustDigiQa.h} | 16 ++++----
 core/data/CMakeLists.txt                      |  8 ++--
 core/data/CbmDefs.h                           |  2 +-
 core/data/base/CbmDigiData.h                  | 12 +++---
 .../CbmPastaDigi.cxx => must/CbmMustDigi.cxx} |  2 +-
 .../CbmPastaDigi.h => must/CbmMustDigi.h}     | 12 +++---
 .../CbmMustDigiData.h}                        | 14 +++----
 reco/app/cbmreco/main.cxx                     |  2 +-
 .../rich/mcbm/CbmRichMCbmHitProducer.cxx      |  2 +-
 27 files changed, 126 insertions(+), 127 deletions(-)
 rename algo/detectors/{pasta => must}/ReadoutConfig.cxx (84%)
 rename algo/detectors/{pasta => must}/ReadoutConfig.h (89%)
 rename algo/detectors/{pasta => must}/Unpack.cxx (80%)
 rename algo/detectors/{pasta => must}/Unpack.h (77%)
 rename algo/detectors/{pasta => must}/UnpackMS.cxx (91%)
 rename algo/detectors/{pasta => must}/UnpackMS.h (97%)
 rename algo/qa/unpack/{PastaDigiQa.cxx => MustDigiQa.cxx} (70%)
 rename algo/qa/unpack/{PastaDigiQa.h => MustDigiQa.h} (79%)
 rename core/data/{pasta/CbmPastaDigi.cxx => must/CbmMustDigi.cxx} (84%)
 rename core/data/{pasta/CbmPastaDigi.h => must/CbmMustDigi.h} (71%)
 rename core/data/{pasta/CbmPastaDigiData.h => must/CbmMustDigiData.h} (69%)

diff --git a/algo/CMakeLists.txt b/algo/CMakeLists.txt
index 5aed22a236..b07afd7458 100644
--- a/algo/CMakeLists.txt
+++ b/algo/CMakeLists.txt
@@ -143,9 +143,9 @@ set(SRCS
   detectors/rich/ReadoutConfig.cxx
   detectors/rich/Unpack.cxx
   detectors/rich/UnpackMS.cxx
-  detectors/pasta/Unpack.cxx
-  detectors/pasta/UnpackMS.cxx
-  detectors/pasta/ReadoutConfig.cxx
+  detectors/must/Unpack.cxx
+  detectors/must/UnpackMS.cxx
+  detectors/must/ReadoutConfig.cxx
   global/ParFiles.cxx
   global/StorableRecoResults.cxx
   global/Reco.cxx
@@ -162,7 +162,7 @@ set(SRCS
   qa/hitfind/BmonHitfindQa.cxx
   qa/hitfind/BmonHitfindQaParameters.cxx
   qa/unpack/StsDigiQa.cxx
-        qa/unpack/PastaDigiQa.cxx
+  qa/unpack/MustDigiQa.cxx
   ca/TrackingSetup.cxx
   ca/TrackingChain.cxx
   ca/qa/CaQa.cxx
@@ -341,7 +341,7 @@ install(DIRECTORY base/gpu TYPE INCLUDE FILES_MATCHING PATTERN "*.h")
 install(DIRECTORY data/sts TYPE INCLUDE FILES_MATCHING PATTERN "*.h")
 install(DIRECTORY detectors/bmon TYPE INCLUDE FILES_MATCHING PATTERN "*.h")
 install(DIRECTORY detectors/much TYPE INCLUDE FILES_MATCHING PATTERN "*.h")
-install(DIRECTORY detectors/pasta TYPE INCLUDE FILES_MATCHING PATTERN "*.h")
+install(DIRECTORY detectors/must TYPE INCLUDE FILES_MATCHING PATTERN "*.h")
 install(DIRECTORY detectors/sts TYPE INCLUDE FILES_MATCHING PATTERN "*.h")
 install(DIRECTORY detectors/tof TYPE INCLUDE FILES_MATCHING PATTERN "*.h")
 install(DIRECTORY detectors/trd TYPE INCLUDE FILES_MATCHING PATTERN "*.h")
diff --git a/algo/base/AuxDigiData.h b/algo/base/AuxDigiData.h
index 9fdda66f06..a2bb320161 100644
--- a/algo/base/AuxDigiData.h
+++ b/algo/base/AuxDigiData.h
@@ -12,7 +12,7 @@
 #include "CommonUnpacker.h"
 #include "bmon/UnpackMS.h"
 #include "much/UnpackMS.h"
-#include "pasta/UnpackMS.h"
+#include "must/UnpackMS.h"
 #include "rich/UnpackMS.h"
 #include "sts/UnpackMS.h"
 #include "tof/UnpackMS.h"
@@ -29,7 +29,7 @@ namespace cbm::algo
     UnpackAux<bmon::UnpackAuxData> fBmon;
     UnpackAux<much::UnpackAuxData> fMuch;
     UnpackAux<rich::UnpackAuxData> fRich;
-    UnpackAux<pasta::UnpackAuxData> fPasta;
+    UnpackAux<must::UnpackAuxData> fMust;
     UnpackAux<sts::UnpackAuxData> fSts;
     UnpackAux<tof::UnpackAuxData> fTof;
     UnpackAux<trd::UnpackAuxData> fTrd;
diff --git a/algo/base/Definitions.h b/algo/base/Definitions.h
index 3cde44e913..74b2f532bb 100644
--- a/algo/base/Definitions.h
+++ b/algo/base/Definitions.h
@@ -67,7 +67,7 @@ namespace cbm::algo
     UnpackMuch,
     UnpackTof,
     UnpackFsd,
-    UnpackPasta,
+    UnpackMust,
     EventBuilding,
     RecoBmon,
     RecoSts,
@@ -140,7 +140,7 @@ CBM_ENUM_DICT(cbm::algo::QaStep,
   {"UnpackMuch", cbm::algo::QaStep::UnpackMuch},
   {"UnpackTof", cbm::algo::QaStep::UnpackTof},
   {"UnpackFsd", cbm::algo::QaStep::UnpackFsd},
-  {"UnpackPasta", cbm::algo::QaStep::UnpackPasta},
+  {"UnpackMust", cbm::algo::QaStep::UnpackMust},
   {"EventBuilding", cbm::algo::QaStep::EventBuilding},
   {"RecoBmon", cbm::algo::QaStep::RecoBmon},
   {"RecoSts", cbm::algo::QaStep::RecoSts},
diff --git a/algo/base/DigiData.cxx b/algo/base/DigiData.cxx
index d075119cc5..2277a0dac2 100644
--- a/algo/base/DigiData.cxx
+++ b/algo/base/DigiData.cxx
@@ -21,7 +21,7 @@ DigiData::DigiData(const CbmDigiData& storable)
   , fRich(ToPODVector(storable.fRich.fDigis))
   , fPsd(ToPODVector(storable.fPsd.fDigis))
   , fFsd(ToPODVector(storable.fFsd.fDigis))
-  , fPasta(ToPODVector(storable.fPasta.fDigis))
+  , fMust(ToPODVector(storable.fMust.fDigis))
 {
 }
 
@@ -37,7 +37,7 @@ size_t DigiData::Size(ECbmModuleId system) const
     case ECbmModuleId::kRich: return fRich.size();
     case ECbmModuleId::kPsd: return fPsd.size();
     case ECbmModuleId::kFsd: return fFsd.size();
-    case ECbmModuleId::kPasta: return fPasta.size();
+    case ECbmModuleId::kMust: return fMust.size();
     default: throw std::runtime_error("DigiData: Invalid system Id " + ::ToString(system));
   }
 }
@@ -45,7 +45,7 @@ size_t DigiData::Size(ECbmModuleId system) const
 size_t DigiData::TotalSize() const
 {
   return fSts.size() + fMuch.size() + fTof.size() + fBmon.size() + fTrd.size() + fTrd2d.size() + fRich.size()
-         + fPsd.size() + fFsd.size() + fPasta.size();
+         + fPsd.size() + fFsd.size() + fMust.size();
 }
 
 size_t DigiData::TotalSizeBytes() const
@@ -53,7 +53,7 @@ size_t DigiData::TotalSizeBytes() const
   return sizeof(CbmStsDigi) * fSts.size() + sizeof(CbmMuchDigi) * fMuch.size() + sizeof(CbmTofDigi) * fTof.size()
          + sizeof(CbmBmonDigi) * fBmon.size() + sizeof(CbmTrdDigi) * fTrd.size() + sizeof(CbmTrdDigi) * fTrd2d.size()
          + sizeof(CbmRichDigi) * fRich.size() + sizeof(CbmPsdDigi) * fPsd.size() + sizeof(CbmFsdDigi) * fFsd.size()
-         + sizeof(CbmPastaDigi) * fPasta.size();
+         + sizeof(CbmMustDigi) * fMust.size();
 }
 
 CbmDigiData DigiData::ToStorable() const
@@ -95,9 +95,9 @@ CbmDigiData DigiData::ToStorable() const
       {
         .fDigis = ToStdVector(fFsd),
       },
-    .fPasta =
+    .fMust =
       {
-        .fDigis = ToStdVector(fPasta),
+        .fDigis = ToStdVector(fMust),
       },
   };
 }
diff --git a/algo/base/DigiData.h b/algo/base/DigiData.h
index 6e8877f21c..9347579634 100644
--- a/algo/base/DigiData.h
+++ b/algo/base/DigiData.h
@@ -10,7 +10,7 @@
 #include "CbmEventTriggers.h"
 #include "CbmFsdDigi.h"
 #include "CbmMuchDigi.h"
-#include "CbmPastaDigi.h"
+#include "CbmMustDigi.h"
 #include "CbmPsdDigi.h"
 #include "CbmRichDigi.h"
 #include "CbmStsDigi.h"
@@ -40,7 +40,7 @@ namespace cbm::algo
     PODVector<CbmRichDigi> fRich;  ///< Unpacked RICH digis
     PODVector<CbmPsdDigi> fPsd;    ///< Unpacked PSD digis
     PODVector<CbmFsdDigi> fFsd;    ///< Unpacked FSD digis
-    PODVector<CbmPastaDigi> fPasta;  ///< Unpacked PASTA digis
+    PODVector<CbmMustDigi> fMust;  ///< Unpacked MUST digis
 
     DigiData();
     ~DigiData();
diff --git a/algo/data/CMakeLists.txt b/algo/data/CMakeLists.txt
index e65eaba58e..5dd6ae7c12 100644
--- a/algo/data/CMakeLists.txt
+++ b/algo/data/CMakeLists.txt
@@ -32,7 +32,7 @@ set(SRCS
   ${OFFLINE_DATA_DIR}/fsd/CbmFsdDigi.cxx
   ${OFFLINE_DATA_DIR}/fsd/CbmFsdAddress.cxx
 
-  ${OFFLINE_DATA_DIR}/pasta/CbmPastaDigi.cxx
+  ${OFFLINE_DATA_DIR}/must/CbmMustDigi.cxx
 
   ${OFFLINE_DATA_DIR}/raw/CriGet4Mess001.cxx
   ${OFFLINE_DATA_DIR}/raw/StsXyterMessage.cxx
@@ -51,7 +51,7 @@ target_include_directories(OnlineData
   PUBLIC ${OFFLINE_DATA_DIR}/tof
   PUBLIC ${OFFLINE_DATA_DIR}/psd
   PUBLIC ${OFFLINE_DATA_DIR}/fsd
-  PUBLIC ${OFFLINE_DATA_DIR}/pasta
+  PUBLIC ${OFFLINE_DATA_DIR}/must
   PUBLIC ${OFFLINE_DATA_DIR}/global
   PUBLIC ${OFFLINE_DATA_DIR}/raw
 )
diff --git a/algo/detectors/pasta/ReadoutConfig.cxx b/algo/detectors/must/ReadoutConfig.cxx
similarity index 84%
rename from algo/detectors/pasta/ReadoutConfig.cxx
rename to algo/detectors/must/ReadoutConfig.cxx
index 4c1aaea395..190d06c53f 100644
--- a/algo/detectors/pasta/ReadoutConfig.cxx
+++ b/algo/detectors/must/ReadoutConfig.cxx
@@ -6,9 +6,9 @@
 
 namespace cbm::algo
 {
-  CBM_YAML_INSTANTIATE(pasta::ReadoutConfig);
+  CBM_YAML_INSTANTIATE(must::ReadoutConfig);
 
-  namespace pasta
+  namespace must
   {
 
     const std::vector<uint16_t>& ReadoutConfig::GetEquipmentIds() const { return fEquipmentIds; }
@@ -17,6 +17,6 @@ namespace cbm::algo
 
     uint8_t ReadoutConfig::GetSystemVersion() const { return fSystemVersion; }
 
-  }  // namespace pasta
+  }  // namespace must
 
 }  // namespace cbm::algo
diff --git a/algo/detectors/pasta/ReadoutConfig.h b/algo/detectors/must/ReadoutConfig.h
similarity index 89%
rename from algo/detectors/pasta/ReadoutConfig.h
rename to algo/detectors/must/ReadoutConfig.h
index 74c56caae1..7e99cfe5a0 100644
--- a/algo/detectors/pasta/ReadoutConfig.h
+++ b/algo/detectors/must/ReadoutConfig.h
@@ -10,7 +10,7 @@
 #include <array>
 #include <cstdint>
 
-namespace cbm::algo::pasta
+namespace cbm::algo::must
 {
 
   class ReadoutConfig {
@@ -33,6 +33,6 @@ namespace cbm::algo::pasta
                         yaml::Property(&ReadoutConfig::fSystemVersion, "systemVersion", "System version"));
   };
 
-}  // namespace cbm::algo::pasta
+}  // namespace cbm::algo::must
 
-CBM_YAML_EXTERN_DECL(cbm::algo::pasta::ReadoutConfig);
+CBM_YAML_EXTERN_DECL(cbm::algo::must::ReadoutConfig);
diff --git a/algo/detectors/pasta/Unpack.cxx b/algo/detectors/must/Unpack.cxx
similarity index 80%
rename from algo/detectors/pasta/Unpack.cxx
rename to algo/detectors/must/Unpack.cxx
index d80af3cc5e..bf81676b13 100644
--- a/algo/detectors/pasta/Unpack.cxx
+++ b/algo/detectors/must/Unpack.cxx
@@ -7,7 +7,7 @@
 #include "AlgoFairloggerCompat.h"
 
 
-namespace cbm::algo::pasta
+namespace cbm::algo::must
 {
   Unpack::Unpack(const ReadoutConfig& readout) : fReadout(readout)
   {
@@ -16,12 +16,12 @@ namespace cbm::algo::pasta
     for (const auto eqId : fReadout.GetEquipmentIds()) {
       fAlgos.emplace(UnpackKey{eqId, fReadout.GetSystemVersion()}, std::make_unique<UnpackMS>(unpackPar));
 
-      L_(info) << "--- Configured equipment " << eqId << " of PASTA@RICH.";
+      L_(info) << "--- Configured equipment " << eqId << " of MUST@RICH.";
     }
 
-    L_(info) << "--- Configured " << fAlgos.size() << " unpacker algorithms for PASTA@RICH.";
+    L_(info) << "--- Configured " << fAlgos.size() << " unpacker algorithms for MUST@RICH.";
   }
 
   Unpack::Result_t Unpack::operator()(const fles::Timeslice& ts) const { return DoUnpack(fles::Subsystem::RICH, ts); }
 
-}  // namespace cbm::algo::pasta
+}  // namespace cbm::algo::must
diff --git a/algo/detectors/pasta/Unpack.h b/algo/detectors/must/Unpack.h
similarity index 77%
rename from algo/detectors/pasta/Unpack.h
rename to algo/detectors/must/Unpack.h
index e3f5f626be..d98c8a77c0 100644
--- a/algo/detectors/pasta/Unpack.h
+++ b/algo/detectors/must/Unpack.h
@@ -8,12 +8,12 @@
 #include "ReadoutConfig.h"
 #include "UnpackMS.h"
 
-namespace cbm::algo::pasta
+namespace cbm::algo::must
 {
 
   namespace detail
   {
-    using UnpackBase = CommonUnpacker<CbmPastaDigi, UnpackMonitorData, UnpackAuxData>;
+    using UnpackBase = CommonUnpacker<CbmMustDigi, UnpackMonitorData, UnpackAuxData>;
   }
 
   class Unpack : public detail::UnpackBase {
@@ -28,4 +28,4 @@ namespace cbm::algo::pasta
     ReadoutConfig fReadout;
   };
 
-}  // namespace cbm::algo::pasta
+}  // namespace cbm::algo::must
diff --git a/algo/detectors/pasta/UnpackMS.cxx b/algo/detectors/must/UnpackMS.cxx
similarity index 91%
rename from algo/detectors/pasta/UnpackMS.cxx
rename to algo/detectors/must/UnpackMS.cxx
index 2366e69e02..81f90bae22 100644
--- a/algo/detectors/pasta/UnpackMS.cxx
+++ b/algo/detectors/must/UnpackMS.cxx
@@ -8,7 +8,7 @@
 
 #include <cstdint>
 
-namespace cbm::algo::pasta
+namespace cbm::algo::must
 {
   UnpackMS::UnpackMS(const UnpackPar& pars) : fParams(pars) {}
 
@@ -24,7 +24,7 @@ namespace cbm::algo::pasta
     ctx.cbmTimeMS = 0;
     ctx.digis.reserve(msDescr.size / sizeof(u32));
 
-    pasta::MicrosliceReader reader;
+    must::MicrosliceReader reader;
     reader.SetData(msContent, msDescr.size);
 
     const auto mstime = msDescr.idx;
@@ -50,7 +50,7 @@ namespace cbm::algo::pasta
   }
 
 
-  void UnpackMS::ProcessTrbPacket(pasta::MicrosliceReader& reader, MSContext& ctx) const
+  void UnpackMS::ProcessTrbPacket(must::MicrosliceReader& reader, MSContext& ctx) const
   {
     //process CBM time
     const uint32_t word_MSB = reader.NextWord();  // CBM 63:32
@@ -80,7 +80,7 @@ namespace cbm::algo::pasta
   }
 
 
-  void UnpackMS::ProcessHubBlock(pasta::MicrosliceReader& reader, MSContext& ctx) const
+  void UnpackMS::ProcessHubBlock(must::MicrosliceReader& reader, MSContext& ctx) const
   {
     uint32_t word = reader.NextWord();
 
@@ -135,7 +135,7 @@ namespace cbm::algo::pasta
     }
   }
 
-  int UnpackMS::ProcessCtsHeader(pasta::MicrosliceReader& reader, uint32_t subSubEventSize,
+  int UnpackMS::ProcessCtsHeader(must::MicrosliceReader& reader, uint32_t subSubEventSize,
                                  uint32_t /*subSubEventId*/) const
   {
     const uint32_t word = reader.NextWord();
@@ -163,7 +163,7 @@ namespace cbm::algo::pasta
     return nofTimeWords;
   }
 
-  void UnpackMS::ProcessSubSubEvent(pasta::MicrosliceReader& reader, int nofTimeWords, uint32_t subSubEventId,
+  void UnpackMS::ProcessSubSubEvent(must::MicrosliceReader& reader, int nofTimeWords, uint32_t subSubEventId,
                                     MSContext& ctx) const
   {
     bool wasHeader  = false;
@@ -185,7 +185,7 @@ namespace cbm::algo::pasta
       return;
     }
 
-    // Skip SubSubEvent for CTS and not PASTA addresses
+    // Skip SubSubEvent for CTS and not MUST addresses
     if (std::find(fParams.fTRBAddresses.cbegin(), fParams.fTRBAddresses.cend(), subSubEventId)
         == fParams.fTRBAddresses.end()) {
       ctx.monitor.fNumCtsAndUnmappedDirich++;
@@ -210,7 +210,7 @@ namespace cbm::algo::pasta
 
     // First word is expected to be of type "header"
     if (GetTdcWordType(reader.NextWord()) != TdcWordType::Header) {
-      L_(debug) << "PASTA DiRICH 0x" << std::hex << subSubEventId << std::dec
+      L_(debug) << "MUST DiRICH 0x" << std::hex << subSubEventId << std::dec
                 << ": 1st message is not a TDC Header, skipping subsubevent";
       ctx.monitor.fNumErrInvalidFirstMessage++;
       ctx.monitor.fNumSkippedSubsubevent++;
@@ -226,7 +226,7 @@ namespace cbm::algo::pasta
     // Second word is expected to be of type "epoch"
     uint32_t word = reader.NextWord();
     if (GetTdcWordType(word) != TdcWordType::Epoch) {
-      L_(debug) << "PASTA DiRICH 0x" << std::hex << subSubEventId << std::dec
+      L_(debug) << "MUST DiRICH 0x" << std::hex << subSubEventId << std::dec
                 << ": 2nd message is not an epoch, skipping subsubevent";
       ctx.monitor.fNumErrInvalidSecondMessage++;
       ctx.monitor.fNumSkippedSubsubevent++;
@@ -248,7 +248,7 @@ namespace cbm::algo::pasta
       switch (GetTdcWordType(word)) {
         case TdcWordType::TimeData: {
           if (!wasHeader || !wasEpoch || wasTrailer) {
-            L_(debug) << "PASTA DiRICH 0x" << std::hex << subSubEventId << std::dec
+            L_(debug) << "MUST DiRICH 0x" << std::hex << subSubEventId << std::dec
                       << ": illegal position of TDC Time (before header/epoch or after trailer)";
             ctx.monitor.fNumErrWildTdcTime++;
             ctx.monitor.fNumSkippedSubsubevent++;
@@ -265,7 +265,7 @@ namespace cbm::algo::pasta
         }
         case TdcWordType::Epoch: {
           if (!wasHeader || wasTrailer) {
-            L_(debug) << "PASTA DiRICH 0x" << std::hex << subSubEventId << std::dec
+            L_(debug) << "MUST DiRICH 0x" << std::hex << subSubEventId << std::dec
                       << ": illegal position of TDC Epoch (before header or after trailer)";
             ctx.monitor.fNumErrWildEpoch++;
             ctx.monitor.fNumSkippedSubsubevent++;
@@ -280,7 +280,7 @@ namespace cbm::algo::pasta
         }
         case TdcWordType::Header: {
           if (wasEpoch || wasTime || wasTrailer) {
-            L_(debug) << "PASTA DiRICH 0x" << std::hex << subSubEventId << std::dec
+            L_(debug) << "MUST DiRICH 0x" << std::hex << subSubEventId << std::dec
                       << ": illegal position of TDC Header (after time/epoch/trailer)";
             ctx.monitor.fNumErrWildHeaderMessage++;
             ctx.monitor.fNumSkippedSubsubevent++;
@@ -294,7 +294,7 @@ namespace cbm::algo::pasta
         }
         case TdcWordType::Trailer: {
           if (!wasEpoch || !wasTime || !wasHeader) {
-            L_(debug) << "PASTA DiRICH 0x" << std::hex << subSubEventId << std::dec
+            L_(debug) << "MUST DiRICH 0x" << std::hex << subSubEventId << std::dec
                       << ": illegal position of TDC Trailer (before time/epoch/header)";
             ctx.monitor.fNumErrWildTrailerMessage++;
             ctx.monitor.fNumSkippedSubsubevent++;
@@ -303,7 +303,7 @@ namespace cbm::algo::pasta
             }
             return;
           }
-          L_(debug) << "PASTA DiRICH 0x" << std::hex << subSubEventId << std::dec << ": TDC Trailer too early, "
+          L_(debug) << "MUST DiRICH 0x" << std::hex << subSubEventId << std::dec << ": TDC Trailer too early, "
                     << (nofTimeWords - 1 - i) << " word(s) before last";
           ctx.monitor.fNumErrWildTrailerMessage++;
           wasTrailer = true;
@@ -324,17 +324,17 @@ namespace cbm::algo::pasta
     // Last word is expected to be of type "trailer"
     word = reader.NextWord();
     if (GetTdcWordType(word) != TdcWordType::Trailer) {
-      L_(debug) << "PASTA DiRICH 0x" << std::hex << subSubEventId << std::dec << ": Last word not a TDC trailer";
+      L_(debug) << "MUST DiRICH 0x" << std::hex << subSubEventId << std::dec << ": Last word not a TDC trailer";
       ctx.monitor.fNumErrInvalidLastMessage++;
       if (GetTdcWordType(word) == TdcWordType::TimeData && !wasTrailer) {
         if (ProcessTimeDataWord(epoch, word, subSubEventId, raisingTime, ctx)) {
           ctx.monitor.fNumWarnRecoveredLastDigi++;
-          L_(debug) << "PASTA DiRICH 0x" << std::hex << subSubEventId << std::dec
+          L_(debug) << "MUST DiRICH 0x" << std::hex << subSubEventId << std::dec
                     << ": Rescuing TimeData in subsubevent with missing Trailer leading to saved Digi";
         }
         else {
           ctx.monitor.fNumErrOrphanRecovTimeData++;
-          L_(debug) << "PASTA DiRICH 0x" << std::hex << subSubEventId << std::dec
+          L_(debug) << "MUST DiRICH 0x" << std::hex << subSubEventId << std::dec
                     << ": Rescuing TimeData in subsubevent with missing Trailer w/o extra digi";
         }
       }
@@ -370,7 +370,7 @@ namespace cbm::algo::pasta
           if (ToT >= fToTMin && ToT <= fToTMax) {
             if (fullTimeCorr >= 0.0) {
               WriteOutputDigi(subSubEventId, td.fChannel, raisingTime[td.fChannel], ToT, ctx);
-              L_(info) << "[PASTA DIGI] "
+              L_(info) << "[MUST DIGI] "
                        << "TRBId: 0x" << std::hex << subSubEventId << std::dec << "; channel: 0x" << std::hex
                        << td.fChannel << std::dec << "; raising time: " << raisingTime[td.fChannel] << "; ToT: " << ToT;
               madeDigi = true;
@@ -452,4 +452,4 @@ namespace cbm::algo::pasta
 
   uint16_t UnpackMS::ProcessTrailer(uint32_t tdcWord) const { return static_cast<uint16_t>(tdcWord & 0xffff); }
 
-}  // namespace cbm::algo::pasta
+}  // namespace cbm::algo::must
diff --git a/algo/detectors/pasta/UnpackMS.h b/algo/detectors/must/UnpackMS.h
similarity index 97%
rename from algo/detectors/pasta/UnpackMS.h
rename to algo/detectors/must/UnpackMS.h
index faf4ad6d5e..229f499824 100644
--- a/algo/detectors/pasta/UnpackMS.h
+++ b/algo/detectors/must/UnpackMS.h
@@ -4,7 +4,7 @@
 
 #pragma once
 
-#include "CbmPastaDigi.h"
+#include "CbmMustDigi.h"
 #include "Definitions.h"
 #include "ReadoutConfig.h"
 #include "Timeslice.hpp"
@@ -17,7 +17,7 @@
 #include <sstream>
 #include <utility>
 
-namespace cbm::algo::pasta
+namespace cbm::algo::must
 {
 
   class MicrosliceReader;
@@ -116,7 +116,7 @@ namespace cbm::algo::pasta
     ///// TO BE FILLED
   };
 
-  class UnpackMS : public UnpackMSBase<CbmPastaDigi, UnpackMonitorData, UnpackAuxData> {
+  class UnpackMS : public UnpackMSBase<CbmMustDigi, UnpackMonitorData, UnpackAuxData> {
 
    public:
     UnpackMS() = delete;
@@ -161,7 +161,7 @@ namespace cbm::algo::pasta
 
       uint16_t currentSubSubEvent = 0;
 
-      std::vector<CbmPastaDigi> digis;
+      std::vector<CbmMustDigi> digis;
       UnpackMonitorData monitor;
     };
 
@@ -270,4 +270,4 @@ namespace cbm::algo::pasta
     }
   };
 
-}  // namespace cbm::algo::pasta
+}  // namespace cbm::algo::must
diff --git a/algo/detectors/rich/ReadoutConfig.cxx b/algo/detectors/rich/ReadoutConfig.cxx
index 78099eeeda..fb8db23657 100644
--- a/algo/detectors/rich/ReadoutConfig.cxx
+++ b/algo/detectors/rich/ReadoutConfig.cxx
@@ -65,7 +65,7 @@ namespace cbm::algo::rich
 
     // Constants
     const uint16_t numComp          = 1;   // Number of components
-    const uint16_t numElinksPerComp = 79;  // Number of elinks per component (74 mRICH, 5 FSD/NCAL, 8 PASTA)
+    const uint16_t numElinksPerComp = 79;  // Number of elinks per component (74 mRICH, 5 FSD/NCAL, 8 MUST)
     const uint16_t numChanPerElink  = 33;  // Number of channels per Elink
 
     // Equipment IDs for each component
@@ -83,7 +83,7 @@ namespace cbm::algo::rich
           0x7320, 0x7321, 0x7330, 0x7331, 0x7340, 0x7341, 0x7350, 0x7351, 0x7360, 0x7361, 0x7370, 0x7371,
           0x7380, 0x7381, 0x7901, 0x7902, 0x7903, 0x7904, 0x7905 /*, 0x9991, 0x9992, 0x9993, 0x9994, 0x9995, 0x9996, 0x9997, 0x9998*/};
     // TRBaddresses 0x7901 and 0x7902 are for FSD/NCAL
-    // TRBaddresses 0x9991 to 0x9998 are for PASTA
+    // TRBaddresses 0x9991 to 0x9998 are for MUST
 
     double ToTshifts[numElinksPerComp][numChanPerElink] = {
       {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,
diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx
index 16f5e31dd3..c2f4bbca2d 100644
--- a/algo/global/Reco.cxx
+++ b/algo/global/Reco.cxx
@@ -10,8 +10,8 @@
 #include "EventbuildChain.h"
 #include "Exceptions.h"
 #include "HistogramSender.h"
+#include "MustDigiQa.h"
 #include "ParFiles.h"
-#include "PastaDigiQa.h"
 #include "RecoGeneralQa.h"
 #include "StsDigiQa.h"
 #include "TrackingSetup.h"
@@ -25,10 +25,10 @@
 #include "evbuild/Config.h"
 #include "kfp/KfpV0FinderChain.h"
 #include "much/Unpack.h"
+#include "must/Unpack.h"
 #include "qa/QaManager.h"
 #include "qa/hitfind/BmonHitfindQa.h"
 #include "rich/Unpack.h"
-#include "pasta/Unpack.h"
 #include "sts/ChannelMaskSet.h"
 #include "sts/HitfinderChain.h"
 #include "sts/Unpack.h"
@@ -146,12 +146,11 @@ void Reco::Init(const Options& opts)
     fRichUnpack = std::make_unique<rich::Unpack>(richCfg);
 
     //TODO handle under fles::Subsystem::MUST when available
-    pasta::ReadoutConfig pastaCfg =
-      yaml::ReadFromFile<pasta::ReadoutConfig>(Opts().ParamsDir() / parFiles.must.readout);
-    fPastaUnpack = std::make_unique<pasta::Unpack>(pastaCfg);
-    if (fSender != nullptr && Opts().Has(QaStep::UnpackPasta)) {
-      fPastaDigiQa = std::make_unique<pasta::DigiQa>(fSender, pastaCfg);
-      fPastaDigiQa->Init();
+    must::ReadoutConfig mustCfg = yaml::ReadFromFile<must::ReadoutConfig>(Opts().ParamsDir() / parFiles.must.readout);
+    fMustUnpack                 = std::make_unique<must::Unpack>(mustCfg);
+    if (fSender != nullptr && Opts().Has(QaStep::UnpackMust)) {
+      fMustDigiQa = std::make_unique<must::DigiQa>(fSender, mustCfg);
+      fMustDigiQa->Init();
     }
   }
 
@@ -331,7 +330,7 @@ RecoResults Reco::Run(const fles::Timeslice& ts)
       std::tie(digis.fBmon, auxDigis.fBmon)   = RunUnpacker(fBmonUnpack, ts);
       std::tie(digis.fMuch, auxDigis.fMuch)   = RunUnpacker(fMuchUnpack, ts);
       std::tie(digis.fRich, auxDigis.fRich)   = RunUnpacker(fRichUnpack, ts);
-      std::tie(digis.fPasta, auxDigis.fPasta) = RunUnpacker(fPastaUnpack, ts);
+      std::tie(digis.fMust, auxDigis.fMust)   = RunUnpacker(fMustUnpack, ts);
       std::tie(digis.fSts, auxDigis.fSts)     = RunUnpacker(fStsUnpack, ts);
       std::tie(digis.fTof, auxDigis.fTof)     = RunUnpacker(fTofUnpack, ts);
       std::tie(digis.fTrd, auxDigis.fTrd)     = RunUnpacker(fTrdUnpack, ts);
@@ -344,11 +343,11 @@ RecoResults Reco::Run(const fles::Timeslice& ts)
       L_(info) << "TS contains Digis: STS=" << digis.fSts.size() << " MUCH=" << digis.fMuch.size()
                << " TOF=" << digis.fTof.size() << " BMON=" << digis.fBmon.size() << " TRD=" << digis.fTrd.size()
                << " TRD2D=" << digis.fTrd2d.size() << " RICH=" << digis.fRich.size() << " PSD=" << digis.fPsd.size()
-               << " FSD=" << digis.fFsd.size() << " PASTA=" << digis.fPasta.size();
+               << " FSD=" << digis.fFsd.size() << " MUST=" << digis.fMust.size();
       // --- Raw digi QAs
 
-      if (fSender != nullptr && Opts().Has(QaStep::UnpackPasta)) {
-        fPastaDigiQa->Exec(digis.fPasta, ts.index());
+      if (fSender != nullptr && Opts().Has(QaStep::UnpackMust)) {
+        fMustDigiQa->Exec(digis.fMust, ts.index());
       }
 
       if (fSender != nullptr && Opts().Has(Subsystem::STS)) {
@@ -461,7 +460,7 @@ RecoResults Reco::Run(const fles::Timeslice& ts)
       results.trdDigis   = std::move(digis.fTrd);
       results.tofDigis   = std::move(digis.fTof);
       results.richDigis  = std::move(digis.fRich);
-      results.pastaDigis = std::move(digis.fPasta);
+      results.mustDigis  = std::move(digis.fMust);
     }
     if (Opts().HasOutput(RecoData::Track)) {
       results.tracks             = std::move(recoData.tracks);
diff --git a/algo/global/Reco.h b/algo/global/Reco.h
index 7f763c7855..ad2a272d2e 100644
--- a/algo/global/Reco.h
+++ b/algo/global/Reco.h
@@ -46,11 +46,11 @@ namespace cbm::algo
     class Unpack;
   }
 
-  namespace pasta
+  namespace must
   {
     class Unpack;
     class DigiQa;
-  }  // namespace pasta
+  }  // namespace must
 
   namespace sts
   {
@@ -172,9 +172,9 @@ namespace cbm::algo
     // RICH
     std::unique_ptr<rich::Unpack> fRichUnpack;
 
-    // PASTA
-    std::unique_ptr<pasta::Unpack> fPastaUnpack;
-    std::unique_ptr<pasta::DigiQa> fPastaDigiQa;  ///< Raw PASTA-digis QA
+    // MUST
+    std::unique_ptr<must::Unpack> fMustUnpack;
+    std::unique_ptr<must::DigiQa> fMustDigiQa;  ///< Raw MUST-digis QA
 
     // STS
     std::unique_ptr<sts::Unpack> fStsUnpack;
diff --git a/algo/global/RecoResults.h b/algo/global/RecoResults.h
index ee0bd49c78..4a0cf6574d 100644
--- a/algo/global/RecoResults.h
+++ b/algo/global/RecoResults.h
@@ -36,7 +36,7 @@ namespace cbm::algo
     PODVector<CbmTrdDigi> trdDigis;
     PODVector<CbmTofDigi> tofDigis;
     PODVector<CbmRichDigi> richDigis;
-    PODVector<CbmPastaDigi> pastaDigis;
+    PODVector<CbmMustDigi> mustDigis;
 
     std::vector<DigiEvent> events;
 
diff --git a/algo/global/StorableRecoResults.h b/algo/global/StorableRecoResults.h
index ae911f774f..31e08876a9 100644
--- a/algo/global/StorableRecoResults.h
+++ b/algo/global/StorableRecoResults.h
@@ -70,8 +70,8 @@ namespace cbm::algo
     std::vector<CbmRichDigi>& RichDigis() { return fRichDigis; }
     const std::vector<CbmRichDigi>& RichDigis() const { return fRichDigis; }
 
-    std::vector<CbmPastaDigi>& PastaDigis() { return fPastaDigis; }
-    const std::vector<CbmPastaDigi>& PastaDigis() const { return fPastaDigis; }
+    std::vector<CbmMustDigi>& MustDigis() { return fMustDigis; }
+    const std::vector<CbmMustDigi>& MustDigis() const { return fMustDigis; }
 
     std::vector<CbmDigiEvent>& DigiEvents() { return fDigiEvents; }
     const std::vector<CbmDigiEvent>& DigiEvents() const { return fDigiEvents; }
@@ -109,7 +109,7 @@ namespace cbm::algo
     std::vector<CbmTrdDigi> fTrdDigis;
     std::vector<CbmTofDigi> fTofDigis;
     std::vector<CbmRichDigi> fRichDigis;
-    std::vector<CbmPastaDigi> fPastaDigis;
+    std::vector<CbmMustDigi> fMustDigis;
 
     // Event builder/filter output
     std::vector<CbmDigiEvent> fDigiEvents;
@@ -146,7 +146,7 @@ namespace cbm::algo
       ar& fTrdDigis;
       ar& fTofDigis;
       ar& fRichDigis;
-      ar& fPastaDigis;
+      ar& fMustDigis;
 
       ar& fDigiEvents;
 
diff --git a/algo/qa/unpack/PastaDigiQa.cxx b/algo/qa/unpack/MustDigiQa.cxx
similarity index 70%
rename from algo/qa/unpack/PastaDigiQa.cxx
rename to algo/qa/unpack/MustDigiQa.cxx
index 125e1b9c0a..efedc14377 100644
--- a/algo/qa/unpack/PastaDigiQa.cxx
+++ b/algo/qa/unpack/MustDigiQa.cxx
@@ -2,14 +2,14 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Bartosz Sobol [committer] */
 
-#include "PastaDigiQa.h"
+#include "MustDigiQa.h"
 
 #include <fmt/format.h>
 
-namespace cbm::algo::pasta
+namespace cbm::algo::must
 {
   DigiQa::DigiQa(std::shared_ptr<HistogramSender> pSender, const ReadoutConfig& readoutConfig)
-    : fQaData{"RawDigi/PASTA"}
+    : fQaData{"RawDigi/MUST"}
     , fpSender{pSender}
     , fReadoutConfig(readoutConfig)
   {
@@ -24,17 +24,17 @@ namespace cbm::algo::pasta
     for (auto iTRB = 0; iTRB < fReadoutConfig.GetTrbAddresses().size(); ++iTRB) {
       const auto TRBId = fReadoutConfig.GetTrbAddresses().at(iTRB);
 
-      auto canvas = qa::CanvasConfig(fmt::format("pasta_digi/pasta_digi_vs_channel_tot_{:x}", TRBId),
-                                     fmt::format("PASTA digis per channel and ToT for TRB 0x{:x}", TRBId), 2, 1);
+      auto canvas = qa::CanvasConfig(fmt::format("must_digi/must_digi_vs_channel_tot_{:x}", TRBId),
+                                     fmt::format("MUST digis per channel and ToT for TRB 0x{:x}", TRBId), 2, 1);
 
       fChannelHists.emplace_back(fQaData.MakeObj<qa::H1D>(
-        fmt::format("pasta_digi_{:x}_channel", TRBId),
+        fmt::format("must_digi_{:x}_channel", TRBId),
         fmt::format("Digis per channel for TRB 0x{:x};channel;N_{{digis}}", TRBId), 32, 0, 32));
 
       auto padChannels = qa::PadConfig();
       padChannels.RegisterHistogram(fChannelHists[iTRB], "hist");
       canvas.AddPadConfig(padChannels);
-      fTotHists.emplace_back(fQaData.MakeObj<qa::H1D>(fmt::format("pasta_digi_{:x}_tot", TRBId),
+      fTotHists.emplace_back(fQaData.MakeObj<qa::H1D>(fmt::format("must_digi_{:x}_tot", TRBId),
                                                       fmt::format("ToT for TRB 0x{:x};ToT;N_{{digis}}", TRBId), 20, 30,
                                                       50));
       auto padTot = qa::PadConfig();
@@ -47,7 +47,7 @@ namespace cbm::algo::pasta
     fQaData.Init(fpSender);
   }
 
-  void DigiQa::Exec(const PODVector<CbmPastaDigi>& digis, const uint64_t tsIndex)
+  void DigiQa::Exec(const PODVector<CbmMustDigi>& digis, const uint64_t tsIndex)
   {
     if (fpSender == nullptr) {
       return;
@@ -59,7 +59,7 @@ namespace cbm::algo::pasta
       const auto iHist = digi.fTRBId - fReadoutConfig.GetTrbAddresses()[0];
 
       if (iHist >= fChannelHists.size()) {
-        L_(error) << fmt::format("pasta::DigiQa: digi TRBId {:x} out of range", digi.fTRBId);
+        L_(error) << fmt::format("must::DigiQa: digi TRBId {:x} out of range", digi.fTRBId);
         continue;
       }
 
@@ -70,6 +70,6 @@ namespace cbm::algo::pasta
     fQaData.Send(fpSender);
   }
 
-  void DigiQa::operator()(const PODVector<CbmPastaDigi>& digis, const uint64_t tsIndex) { Exec(digis, tsIndex); }
+  void DigiQa::operator()(const PODVector<CbmMustDigi>& digis, const uint64_t tsIndex) { Exec(digis, tsIndex); }
 
-}  // namespace cbm::algo::pasta
+}  // namespace cbm::algo::must
diff --git a/algo/qa/unpack/PastaDigiQa.h b/algo/qa/unpack/MustDigiQa.h
similarity index 79%
rename from algo/qa/unpack/PastaDigiQa.h
rename to algo/qa/unpack/MustDigiQa.h
index fe671f8069..3ef02e1ef0 100644
--- a/algo/qa/unpack/PastaDigiQa.h
+++ b/algo/qa/unpack/MustDigiQa.h
@@ -4,20 +4,20 @@
 
 #pragma once
 
-#include "CbmPastaDigi.h"
+#include "CbmMustDigi.h"
 #include "QaBase.h"
 
 #include <CommonUnpacker.h>
-#include <pasta/ReadoutConfig.h>
+#include <must/ReadoutConfig.h>
 
-namespace cbm::algo::pasta
+namespace cbm::algo::must
 {
   /* TODO probably cbm::algo::sts::QaBase can be used here as a base class, but for some reason it is in sts namespace.
    * IMO it should be only in cbm::algo and be a base for all QA classes?
    * For now I'm doing similar impl/interface, but without inheritance.
   */
-  /// \class cbm::algo::pasta::DigiQa
-  /// \brief QA module for PASTA raw digis
+  /// \class cbm::algo::must::DigiQa
+  /// \brief QA module for MUST raw digis
   class DigiQa {
    public:
     /// \brief Main constructor with HistogramSender
@@ -37,10 +37,10 @@ namespace cbm::algo::pasta
     void Init();
 
     /// \brief Executes QA (filling histograms)
-    void Exec(const PODVector<CbmPastaDigi>& digis, uint64_t tsIndex);
+    void Exec(const PODVector<CbmMustDigi>& digis, uint64_t tsIndex);
 
     /// \brief Executes QA (filling histograms), see Exec()
-    void operator()(const PODVector<CbmPastaDigi>& digis, uint64_t tsIndex);
+    void operator()(const PODVector<CbmMustDigi>& digis, uint64_t tsIndex);
 
    private:
     std::vector<qa::H1D*> fChannelHists{};  ///< histograms: nDigis per channel per TRB
@@ -51,4 +51,4 @@ namespace cbm::algo::pasta
     ReadoutConfig fReadoutConfig;
   };
 
-}  // namespace cbm::algo::pasta
+}  // namespace cbm::algo::must
diff --git a/core/data/CMakeLists.txt b/core/data/CMakeLists.txt
index 3cc9465592..4c5f8f974d 100644
--- a/core/data/CMakeLists.txt
+++ b/core/data/CMakeLists.txt
@@ -15,7 +15,7 @@ set(INCLUDE_DIRECTORIES
   ${CMAKE_CURRENT_SOURCE_DIR}/rich
   ${CMAKE_CURRENT_SOURCE_DIR}/psd
   ${CMAKE_CURRENT_SOURCE_DIR}/fsd
-  ${CMAKE_CURRENT_SOURCE_DIR}/pasta
+  ${CMAKE_CURRENT_SOURCE_DIR}/must
   ${CMAKE_CURRENT_SOURCE_DIR}/global
   )
 
@@ -67,7 +67,7 @@ set(SRCS
   rich/CbmRichTrbDigi.cxx
   rich/CbmRichDigi.cxx
 
-  pasta/CbmPastaDigi.cxx
+  must/CbmMustDigi.cxx
 
   much/CbmMuchPixelHit.cxx
   much/CbmMuchPoint.cxx
@@ -137,7 +137,7 @@ SET_SOURCE_FILES_PROPERTIES(tof/etof/star_rhicf.c PROPERTIES COMPILE_FLAGS -Wno-
 
 
 list(APPEND HEADERS base/CbmDigiData.h global/CbmDigiEvent.h global/CbmDigiTimeslice.h
-bmon/CbmBmonDigiData.h sts/CbmStsDigiData.h much/CbmMuchDigiData.h rich/CbmRichDigiData.h pasta/CbmPastaDigiData.h
+bmon/CbmBmonDigiData.h sts/CbmStsDigiData.h much/CbmMuchDigiData.h rich/CbmRichDigiData.h must/CbmMustDigiData.h
 trd/CbmTrdDigiData.h tof/CbmTofDigiData.h psd/CbmPsdDigiData.h fsd/CbmFsdDigiData.h trd/CbmTrdFexMessageSpadic.h)
 
 set(LIBRARY_NAME CbmData)
@@ -169,7 +169,7 @@ Install(FILES
         psd/CbmPsdDigiData.h
         fsd/CbmFsdDigiData.h
         rich/CbmRichDigiData.h rich/CbmRichRingLight.h
-        pasta/CbmPastaDigiData.h
+        must/CbmMustDigiData.h
         sts/CbmStsDigiData.h
         trd/CbmTrdDigiData.h
         tof/CbmTofDigiData.h
diff --git a/core/data/CbmDefs.h b/core/data/CbmDefs.h
index 4e0471d999..59b25b5191 100644
--- a/core/data/CbmDefs.h
+++ b/core/data/CbmDefs.h
@@ -61,7 +61,7 @@ enum class ECbmModuleId
   kCave       = 22,  ///< Cave
   kLastModule = 23,  ///< For loops over all modules
   kNotExist   = -1,  ///< If not found
-  kPasta      = 100  ///< PANDA Straws //TODO
+  kMust       = 100  ///< PANDA Straws //TODO
 };
 
 // operator ++ for ECbmModuleId for convenient usage in loops
diff --git a/core/data/base/CbmDigiData.h b/core/data/base/CbmDigiData.h
index 8317e3971c..efae0b8cb9 100644
--- a/core/data/base/CbmDigiData.h
+++ b/core/data/base/CbmDigiData.h
@@ -9,7 +9,7 @@
 #include "CbmBmonDigiData.h"
 #include "CbmFsdDigiData.h"
 #include "CbmMuchDigiData.h"
-#include "CbmPastaDigiData.h"
+#include "CbmMustDigiData.h"
 #include "CbmPsdDigiData.h"
 #include "CbmRichDigiData.h"
 #include "CbmStsDigiData.h"
@@ -42,7 +42,7 @@ class CbmDigiData {
   CbmTofDigiData fTof;    ///< TOF data
   CbmPsdDigiData fPsd;    ///< PSD data
   CbmFsdDigiData fFsd;    ///< FSD data
-  CbmPastaDigiData fPasta;  ///< PASTA data
+  CbmMustDigiData fMust;  ///< MUST data
 
   friend class boost::serialization::access;
   /** @brief BOOST serializer**/
@@ -59,7 +59,7 @@ class CbmDigiData {
     ar& fPsd;
     ar& fFsd;
     ar& fRich;
-    ar& fPasta;
+    ar& fMust;
   }
 
   // --- ROOT serializer
@@ -79,7 +79,7 @@ class CbmDigiData {
     fPsd.Clear();
     fFsd.Clear();
     fRich.Clear();
-    fPasta.Clear();
+    fMust.Clear();
   }
 
   /** @brief Size of detector data **/
@@ -95,7 +95,7 @@ class CbmDigiData {
       case ECbmModuleId::kPsd: return fPsd.Size(); break;
       case ECbmModuleId::kRich: return fRich.Size(); break;
       case ECbmModuleId::kFsd: return fFsd.Size(); break;
-      case ECbmModuleId::kPasta: return fPasta.Size(); break;
+      case ECbmModuleId::kMust: return fMust.Size(); break;
       default: return 0; break;
     }
   }
@@ -113,7 +113,7 @@ class CbmDigiData {
     size += fPsd.Size() * sizeof(CbmPsdDigi);
     size += fFsd.Size() * sizeof(CbmFsdDigi);
     size += fRich.Size() * sizeof(CbmRichDigi);
-    size += fPasta.Size() * sizeof(CbmPastaDigi);
+    size += fMust.Size() * sizeof(CbmMustDigi);
     return size;
   }
 };
diff --git a/core/data/pasta/CbmPastaDigi.cxx b/core/data/must/CbmMustDigi.cxx
similarity index 84%
rename from core/data/pasta/CbmPastaDigi.cxx
rename to core/data/must/CbmMustDigi.cxx
index 445f9a6df6..2f8332a413 100644
--- a/core/data/pasta/CbmPastaDigi.cxx
+++ b/core/data/must/CbmMustDigi.cxx
@@ -2,4 +2,4 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Bartosz Sobol [committer] */
 
-#include "CbmPastaDigi.h"
+#include "CbmMustDigi.h"
diff --git a/core/data/pasta/CbmPastaDigi.h b/core/data/must/CbmMustDigi.h
similarity index 71%
rename from core/data/pasta/CbmPastaDigi.h
rename to core/data/must/CbmMustDigi.h
index 2b0d841627..b25c335ad2 100644
--- a/core/data/pasta/CbmPastaDigi.h
+++ b/core/data/must/CbmMustDigi.h
@@ -2,16 +2,16 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Bartosz Sobol [committer] */
 
-#ifndef CBMPASTADIGI_H
-#define CBMPASTADIGI_H
+#ifndef CBMMUSTDIGI_H
+#define CBMMUSTDIGI_H
 #include <cstdint>
 
 
-class CbmPastaDigi {
+class CbmMustDigi {
  public:
-  CbmPastaDigi() = default;
+  CbmMustDigi() = default;
 
-  CbmPastaDigi(const uint32_t trbId, const uint32_t channel, const double time, const double tot)
+  CbmMustDigi(const uint32_t trbId, const uint32_t channel, const double time, const double tot)
     : fTRBId{trbId}
     , fChannel{channel}
     , fTime{time}
@@ -37,4 +37,4 @@ class CbmPastaDigi {
 };
 
 
-#endif  //CBMPASTADIGI_H
+#endif  //CBMMUSTDIGI_H
diff --git a/core/data/pasta/CbmPastaDigiData.h b/core/data/must/CbmMustDigiData.h
similarity index 69%
rename from core/data/pasta/CbmPastaDigiData.h
rename to core/data/must/CbmMustDigiData.h
index b788bc99b4..39b8f8267a 100644
--- a/core/data/pasta/CbmPastaDigiData.h
+++ b/core/data/must/CbmMustDigiData.h
@@ -2,10 +2,10 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Bartosz Sobol [committer] */
 
-#ifndef CBMPASTADIGIDATA_H
-#define CBMPASTADIGIDATA_H
+#ifndef CBMMUSTDIGIDATA_H
+#define CBMMUSTDIGIDATA_H
 
-#include "CbmPastaDigi.h"
+#include "CbmMustDigi.h"
 
 #ifndef NO_ROOT
 #include <Rtypes.h>  // for ClassDef
@@ -13,9 +13,9 @@
 
 #include <boost/serialization/vector.hpp>
 
-class CbmPastaDigiData {
+class CbmMustDigiData {
  public:
-  std::vector<CbmPastaDigi> fDigis{};
+  std::vector<CbmMustDigi> fDigis{};
 
   template<class Archive>
   void serialize(Archive& ar, const unsigned int /*version*/)
@@ -28,8 +28,8 @@ class CbmPastaDigiData {
   size_t Size() const { return fDigis.size(); }
 
 #ifndef NO_ROOT
-  ClassDefNV(CbmPastaDigiData, 1);
+  ClassDefNV(CbmMustDigiData, 1);
 #endif
 };
 
-#endif  //CBMPASTADIGIDATA_H
+#endif  //CBMMUSTDIGIDATA_H
diff --git a/reco/app/cbmreco/main.cxx b/reco/app/cbmreco/main.cxx
index 8bb47de69b..7c24c76ee7 100644
--- a/reco/app/cbmreco/main.cxx
+++ b/reco/app/cbmreco/main.cxx
@@ -43,7 +43,7 @@ std::shared_ptr<StorableRecoResults> makeStorableRecoResults(const fles::Timesli
   storable->TrdDigis()   = ToStdVector(results.trdDigis);
   storable->TofDigis()   = ToStdVector(results.tofDigis);
   storable->RichDigis()  = ToStdVector(results.richDigis);
-  storable->PastaDigis() = ToStdVector(results.pastaDigis);
+  storable->MustDigis()  = ToStdVector(results.mustDigis);
 
   storable->StsClusters() = results.stsClusters;
   storable->StsHits()     = results.stsHits;
diff --git a/reco/detectors/rich/mcbm/CbmRichMCbmHitProducer.cxx b/reco/detectors/rich/mcbm/CbmRichMCbmHitProducer.cxx
index 5f3cd3ad47..f445694be8 100644
--- a/reco/detectors/rich/mcbm/CbmRichMCbmHitProducer.cxx
+++ b/reco/detectors/rich/mcbm/CbmRichMCbmHitProducer.cxx
@@ -204,7 +204,7 @@ void CbmRichMCbmHitProducer::ProcessDigi(CbmEvent* event, Int_t digiIndex)
   Int_t DiRICH_Add = (digi->GetAddress() >> 16) & 0xFFFF;
   if ((0x7901 <= DiRICH_Add && DiRICH_Add <= 0x7905) || (0x9991 <= DiRICH_Add && DiRICH_Add <= 0x9998)) {
     // TRBaddresses 0x7901 to 0x7905 are for FSD/NCAL
-    // TRBaddresses 0x9991 to 0x9998 are for PASTA
+    // TRBaddresses 0x9991 to 0x9998 are for MUST
     return;
   }
   fNofDigis++;
-- 
GitLab


From baa60b979676a7b71861e69c7dee04456fb9696c Mon Sep 17 00:00:00 2001
From: Bartosz Sobol <bartosz.sobol@doctoral.uj.edu.pl>
Date: Mon, 10 Feb 2025 01:23:05 +0100
Subject: [PATCH 16/21] [PASTA/MUST] Add 2D digi histogram to QA,

---
 algo/qa/unpack/MustDigiQa.cxx | 30 ++++++++++++++++++++++++------
 algo/qa/unpack/MustDigiQa.h   |  1 +
 2 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/algo/qa/unpack/MustDigiQa.cxx b/algo/qa/unpack/MustDigiQa.cxx
index efedc14377..d75ef44690 100644
--- a/algo/qa/unpack/MustDigiQa.cxx
+++ b/algo/qa/unpack/MustDigiQa.cxx
@@ -21,22 +21,24 @@ namespace cbm::algo::must
       return;
     }
 
-    for (auto iTRB = 0; iTRB < fReadoutConfig.GetTrbAddresses().size(); ++iTRB) {
-      const auto TRBId = fReadoutConfig.GetTrbAddresses().at(iTRB);
+    const auto& TRBIds = fReadoutConfig.GetTrbAddresses();
+
+    for (auto iTRB = 0; iTRB < TRBIds.size(); ++iTRB) {
+      const auto TRBId = TRBIds.at(iTRB);
 
       auto canvas = qa::CanvasConfig(fmt::format("must_digi/must_digi_vs_channel_tot_{:x}", TRBId),
                                      fmt::format("MUST digis per channel and ToT for TRB 0x{:x}", TRBId), 2, 1);
 
       fChannelHists.emplace_back(fQaData.MakeObj<qa::H1D>(
         fmt::format("must_digi_{:x}_channel", TRBId),
-        fmt::format("Digis per channel for TRB 0x{:x};channel;N_{{digis}}", TRBId), 32, 0, 32));
-
+        fmt::format("Digis per channel for TRB 0x{:x};channel;N_{{digis}}", TRBId), 33, 0, 33));
       auto padChannels = qa::PadConfig();
       padChannels.RegisterHistogram(fChannelHists[iTRB], "hist");
       canvas.AddPadConfig(padChannels);
+
       fTotHists.emplace_back(fQaData.MakeObj<qa::H1D>(fmt::format("must_digi_{:x}_tot", TRBId),
-                                                      fmt::format("ToT for TRB 0x{:x};ToT;N_{{digis}}", TRBId), 20, 30,
-                                                      50));
+                                                      fmt::format("ToT for TRB 0x{:x};ToT;N_{{digis}}", TRBId), 30, 10,
+                                                      40));
       auto padTot = qa::PadConfig();
       padTot.RegisterHistogram(fTotHists[iTRB], "hist");
       canvas.AddPadConfig(padTot);
@@ -44,6 +46,18 @@ namespace cbm::algo::must
       fQaData.AddCanvasConfig(canvas);
     }
 
+    auto canvas    = qa::CanvasConfig("must_digi/must_digi_vs_trb_channel", "MUST digis per channel in TRBs", 1, 1);
+    fChannel2DHist = fQaData.MakeObj<qa::H2D>("must_digi_trb_channel", "Digis per channel inTRBs", TRBIds.size(), 0,
+                                              *std::max_element(TRBIds.cbegin(), TRBIds.cend())
+                                                - *std::min_element(TRBIds.cbegin(), TRBIds.cend()) + 1,
+                                              33, 0, 33);
+
+    auto padChannels2D = qa::PadConfig();
+    padChannels2D.RegisterHistogram(fChannel2DHist, "hist");
+    canvas.AddPadConfig(padChannels2D);
+
+    fQaData.AddCanvasConfig(canvas);
+
     fQaData.Init(fpSender);
   }
 
@@ -53,6 +67,9 @@ namespace cbm::algo::must
       return;
     }
 
+    const auto minTRB =
+      *std::min_element(fReadoutConfig.GetTrbAddresses().cbegin(), fReadoutConfig.GetTrbAddresses().cend());
+
     fQaData.SetTimesliceId(tsIndex);
 
     for (const auto& digi : digis) {
@@ -65,6 +82,7 @@ namespace cbm::algo::must
 
       fChannelHists[iHist]->Fill(digi.fChannel);
       fTotHists[iHist]->Fill(digi.fToT);
+      fChannel2DHist->Fill(digi.fTRBId - minTRB, digi.fChannel);
     }
 
     fQaData.Send(fpSender);
diff --git a/algo/qa/unpack/MustDigiQa.h b/algo/qa/unpack/MustDigiQa.h
index 3ef02e1ef0..a14fd667b9 100644
--- a/algo/qa/unpack/MustDigiQa.h
+++ b/algo/qa/unpack/MustDigiQa.h
@@ -45,6 +45,7 @@ namespace cbm::algo::must
    private:
     std::vector<qa::H1D*> fChannelHists{};  ///< histograms: nDigis per channel per TRB
     std::vector<qa::H1D*> fTotHists{};      ///< histograms: ToT per TRB
+    qa::H2D* fChannel2DHist{};              ///< histogram: nDigis per channel per TRB
 
     qa::Data fQaData;
     std::shared_ptr<HistogramSender> fpSender;
-- 
GitLab


From 752d76bb3056bb3681ef5d19a37debd710c9a62a Mon Sep 17 00:00:00 2001
From: Bartosz Sobol <bartosz.sobol@doctoral.uj.edu.pl>
Date: Mon, 10 Feb 2025 01:30:37 +0100
Subject: [PATCH 17/21] [PASTA/MUST] Add ToT shift and time offset to
 ReadoutConfig, unpacking and params

---
 algo/detectors/must/ReadoutConfig.cxx   |  7 +++++++
 algo/detectors/must/ReadoutConfig.h     |  8 ++++++++
 algo/detectors/must/Unpack.cxx          |  4 +++-
 algo/detectors/must/UnpackMS.cxx        | 11 ++++++++---
 algo/detectors/must/UnpackMS.h          |  4 +++-
 macro/must/MustReadout_mcbm2025_02.yaml | 26 +++++++++++++++++++++++++
 6 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/algo/detectors/must/ReadoutConfig.cxx b/algo/detectors/must/ReadoutConfig.cxx
index 190d06c53f..5d05975000 100644
--- a/algo/detectors/must/ReadoutConfig.cxx
+++ b/algo/detectors/must/ReadoutConfig.cxx
@@ -15,6 +15,13 @@ namespace cbm::algo
 
     const std::vector<uint32_t>& ReadoutConfig::GetTrbAddresses() const { return fTRBAddresses; }
 
+    const std::array<float, 33>& ReadoutConfig::GetToTShifts(const uint32_t TRBId) const
+    {
+      return fToTShifts.at(TRBId);
+    }
+
+    uint32_t ReadoutConfig::GetTimeOffset() const { return fTimeOffset; }
+
     uint8_t ReadoutConfig::GetSystemVersion() const { return fSystemVersion; }
 
   }  // namespace must
diff --git a/algo/detectors/must/ReadoutConfig.h b/algo/detectors/must/ReadoutConfig.h
index 7e99cfe5a0..1bc75edbae 100644
--- a/algo/detectors/must/ReadoutConfig.h
+++ b/algo/detectors/must/ReadoutConfig.h
@@ -22,14 +22,22 @@ namespace cbm::algo::must
 
     const std::vector<uint32_t>& GetTrbAddresses() const;
 
+    const std::array<float, 33>& GetToTShifts(const uint32_t TRBId) const;
+
+    uint32_t GetTimeOffset() const;
+
     uint8_t GetSystemVersion() const;
 
     std::vector<uint16_t> fEquipmentIds{};
     std::vector<uint32_t> fTRBAddresses{};
+    std::map<uint32_t, std::array<float, 33>> fToTShifts;
+    uint32_t fTimeOffset{};
     uint8_t fSystemVersion{};
 
     CBM_YAML_PROPERTIES(yaml::Property(&ReadoutConfig::fEquipmentIds, "equipmentIds", "List of equipment IDs", {}, YAML::Flow),
                         yaml::Property(&ReadoutConfig::fTRBAddresses, "TRBAddresses", "List of TRB addresses",  {}, YAML::Flow),
+                        yaml::Property(&ReadoutConfig::fToTShifts, "ToTShifts", "Map from TRB to list of ToT shifts per channel",  {}, YAML::Flow),
+                        yaml::Property(&ReadoutConfig::fTimeOffset, "timeOffset", "System time offset"),
                         yaml::Property(&ReadoutConfig::fSystemVersion, "systemVersion", "System version"));
   };
 
diff --git a/algo/detectors/must/Unpack.cxx b/algo/detectors/must/Unpack.cxx
index bf81676b13..326ed5e31b 100644
--- a/algo/detectors/must/Unpack.cxx
+++ b/algo/detectors/must/Unpack.cxx
@@ -11,7 +11,9 @@ namespace cbm::algo::must
 {
   Unpack::Unpack(const ReadoutConfig& readout) : fReadout(readout)
   {
-    const UnpackPar unpackPar{fReadout.GetTrbAddresses()};
+    const UnpackPar unpackPar{.fTRBAddresses = fReadout.fTRBAddresses,
+                              .fToTShifts    = fReadout.fToTShifts,
+                              .fTimeOffset   = fReadout.fTimeOffset};
 
     for (const auto eqId : fReadout.GetEquipmentIds()) {
       fAlgos.emplace(UnpackKey{eqId, fReadout.GetSystemVersion()}, std::make_unique<UnpackMS>(unpackPar));
diff --git a/algo/detectors/must/UnpackMS.cxx b/algo/detectors/must/UnpackMS.cxx
index 81f90bae22..92cc8d4de3 100644
--- a/algo/detectors/must/UnpackMS.cxx
+++ b/algo/detectors/must/UnpackMS.cxx
@@ -102,7 +102,7 @@ namespace cbm::algo::must
       totalSize += (1 + subSubEventSize);
 
       if (!isLast) {                                 // all except last are DiRICH events
-        if (((subSubEventId >> 12) & 0xF) != 0x7) {  // catch invalid ids
+        if (((subSubEventId >> 12) & 0xF) != 0x9) {  // catch invalid ids
           ctx.monitor.fNumErrInvalidHubId++;
         }
         if (totalSize == hubSize) {
@@ -394,7 +394,12 @@ namespace cbm::algo::must
 
   void UnpackMS::WriteOutputDigi(uint32_t trbId, uint16_t channel, double time, double tot, MSContext& ctx) const
   {
-    ctx.digis.emplace_back(trbId, channel, time, tot);
+    const double ToTCorrection = fbDoToTCorr ? fParams.fToTShifts.at(trbId)[channel] : 0.;
+    const double finalToT      = tot - ToTCorrection;
+
+    const double finalTime = time + static_cast<double>(ctx.refTime) - fParams.fTimeOffset;
+
+    ctx.digis.emplace_back(trbId, channel, finalTime, finalToT);
   }
 
   bool UnpackMS::CheckMaskedDiRICH(int32_t subSubEventId) const
@@ -426,7 +431,7 @@ namespace cbm::algo::must
     return TdcWordType::Error;
   }
 
-  int32_t UnpackMS::GetPixelUID(int32_t fpgaID, int32_t ch) const
+  uint32_t UnpackMS::GetStrawUID(uint32_t fpgaID, uint32_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
diff --git a/algo/detectors/must/UnpackMS.h b/algo/detectors/must/UnpackMS.h
index 229f499824..1532e22c28 100644
--- a/algo/detectors/must/UnpackMS.h
+++ b/algo/detectors/must/UnpackMS.h
@@ -58,6 +58,8 @@ namespace cbm::algo::must
    **/
   struct UnpackPar {
     std::vector<uint32_t> fTRBAddresses;
+    std::map<uint32_t, std::array<float, 33>> fToTShifts;
+    uint32_t fTimeOffset;
   };
 
 
@@ -190,7 +192,7 @@ namespace cbm::algo::must
 
     double CalculateTime(uint32_t epoch, uint32_t coarse, uint32_t fine) const;
 
-    int32_t GetPixelUID(int32_t fpgaID, int32_t ch) const;
+    uint32_t GetStrawUID(uint32_t fpgaID, uint32_t ch) const;
 
     bool CheckMaskedDiRICH(int32_t subSubEventId) const;
 
diff --git a/macro/must/MustReadout_mcbm2025_02.yaml b/macro/must/MustReadout_mcbm2025_02.yaml
index 023f6e7ee9..ecce596f6a 100644
--- a/macro/must/MustReadout_mcbm2025_02.yaml
+++ b/macro/must/MustReadout_mcbm2025_02.yaml
@@ -1,3 +1,29 @@
 systemVersion: 0x03
+timeOffset: 100
 equipmentIds: [ 0x3001 ]
 TRBAddresses: [ 0x9991, 0x9992, 0x9993, 0x9994, 0x9995, 0x9996, 0x9997, 0x9998 ]
+ToTShifts:
+  0x9991: [ 0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
+            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
+            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00 ]
+  0x9992: [ 0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
+            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
+            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00 ]
+  0x9993: [ 0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
+            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
+            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00 ]
+  0x9994: [ 0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
+            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
+            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00 ]
+  0x9995: [ 0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
+            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
+            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00 ]
+  0x9996: [ 0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
+            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
+            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00 ]
+  0x9997: [ 0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
+            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
+            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00 ]
+  0x9998: [ 0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
+            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
+            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00 ]
-- 
GitLab


From d4dfdb53064bd179120b0b796f74bc0661451708 Mon Sep 17 00:00:00 2001
From: Bartosz Sobol <bartosz.sobol@doctoral.uj.edu.pl>
Date: Mon, 10 Feb 2025 19:25:21 +0100
Subject: [PATCH 18/21] [PASTA/MUST] fix must unpacker for old runs, cleanup

---
 algo/detectors/rich/ReadoutConfig.cxx   | 44 +++++--------------------
 algo/global/ParFiles.cxx                |  2 +-
 algo/global/Reco.cxx                    | 12 ++++---
 macro/must/MustReadout_mcbm2025_02.yaml | 29 ----------------
 4 files changed, 16 insertions(+), 71 deletions(-)
 delete mode 100644 macro/must/MustReadout_mcbm2025_02.yaml

diff --git a/algo/detectors/rich/ReadoutConfig.cxx b/algo/detectors/rich/ReadoutConfig.cxx
index fb8db23657..5d74b68d13 100644
--- a/algo/detectors/rich/ReadoutConfig.cxx
+++ b/algo/detectors/rich/ReadoutConfig.cxx
@@ -72,18 +72,14 @@ namespace cbm::algo::rich
     // This number is written to the data stream (MicrosliceDescriptor).
     uint16_t eqId[numComp] = {12289};
 
-    uint32_t
-      TRBaddresses[numElinksPerComp] =
-        {
-          0xc000, 0xc001, 0x7000, 0x7001, 0x7010, 0x7011, 0x7020, 0x7021, 0x7030, 0x7031, 0x7040, 0x7041,
-          0x7050, 0x7051, 0x7060, 0x7061, 0x7070, 0x7071, 0x7080, 0x7081, 0x7100, 0x7101, 0x7110, 0x7111,
-          0x7120, 0x7121, 0x7130, 0x7131, 0x7140, 0x7141, 0x7150, 0x7151, 0x7160, 0x7161, 0x7170, 0x7171,
-          0x7180, 0x7181, 0x7200, 0x7201, 0x7210, 0x7211, 0x7220, 0x7221, 0x7230, 0x7231, 0x7240, 0x7241,
-          0x7250, 0x7251, 0x7260, 0x7261, 0x7270, 0x7271, 0x7280, 0x7281, 0x7300, 0x7301, 0x7310, 0x7311,
-          0x7320, 0x7321, 0x7330, 0x7331, 0x7340, 0x7341, 0x7350, 0x7351, 0x7360, 0x7361, 0x7370, 0x7371,
-          0x7380, 0x7381, 0x7901, 0x7902, 0x7903, 0x7904, 0x7905 /*, 0x9991, 0x9992, 0x9993, 0x9994, 0x9995, 0x9996, 0x9997, 0x9998*/};
+    uint32_t TRBaddresses[numElinksPerComp] = {
+      0xc000, 0xc001, 0x7000, 0x7001, 0x7010, 0x7011, 0x7020, 0x7021, 0x7030, 0x7031, 0x7040, 0x7041, 0x7050, 0x7051,
+      0x7060, 0x7061, 0x7070, 0x7071, 0x7080, 0x7081, 0x7100, 0x7101, 0x7110, 0x7111, 0x7120, 0x7121, 0x7130, 0x7131,
+      0x7140, 0x7141, 0x7150, 0x7151, 0x7160, 0x7161, 0x7170, 0x7171, 0x7180, 0x7181, 0x7200, 0x7201, 0x7210, 0x7211,
+      0x7220, 0x7221, 0x7230, 0x7231, 0x7240, 0x7241, 0x7250, 0x7251, 0x7260, 0x7261, 0x7270, 0x7271, 0x7280, 0x7281,
+      0x7300, 0x7301, 0x7310, 0x7311, 0x7320, 0x7321, 0x7330, 0x7331, 0x7340, 0x7341, 0x7350, 0x7351, 0x7360, 0x7361,
+      0x7370, 0x7371, 0x7380, 0x7381, 0x7901, 0x7902, 0x7903, 0x7904, 0x7905};
     // TRBaddresses 0x7901 and 0x7902 are for FSD/NCAL
-    // TRBaddresses 0x9991 to 0x9998 are for MUST
 
     double ToTshifts[numElinksPerComp][numChanPerElink] = {
       {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,
@@ -320,31 +316,7 @@ namespace cbm::algo::rich
        10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00},
       {0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
        10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-       10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00}/*,
-      {0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-       10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-       10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00},
-      {0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-       10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-       10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00},
-      {0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-       10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-       10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00},
-      {0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-       10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-       10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00},
-      {0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-       10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-       10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00},
-      {0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-       10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-       10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00},
-      {0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-       10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-       10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00},
-      {0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-       10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-       10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00}*/};
+       10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00}};
 
     // Constructing the map (equipmentId, asic address, channel) -> (tot shift)
     for (uint16_t comp = 0; comp < numComp; comp++) {
diff --git a/algo/global/ParFiles.cxx b/algo/global/ParFiles.cxx
index 779694a2b7..df00edbb98 100644
--- a/algo/global/ParFiles.cxx
+++ b/algo/global/ParFiles.cxx
@@ -22,7 +22,7 @@ ParFiles::ParFiles(uint32_t runId)
     setup = Setup::mCBM2025_02;
   }
 
-  must.readout = "MustReadout_mcbm2025_02.yaml";  //TODO this should be moved to 2025 case when available
+  must.readout = "mcbm2025/MustReadout_mcbm2025_02.yaml";  //TODO this should be moved to 2025 case when available
 
   switch (setup) {
 
diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx
index c2f4bbca2d..87d2391ef8 100644
--- a/algo/global/Reco.cxx
+++ b/algo/global/Reco.cxx
@@ -146,11 +146,13 @@ void Reco::Init(const Options& opts)
     fRichUnpack = std::make_unique<rich::Unpack>(richCfg);
 
     //TODO handle under fles::Subsystem::MUST when available
-    must::ReadoutConfig mustCfg = yaml::ReadFromFile<must::ReadoutConfig>(Opts().ParamsDir() / parFiles.must.readout);
-    fMustUnpack                 = std::make_unique<must::Unpack>(mustCfg);
-    if (fSender != nullptr && Opts().Has(QaStep::UnpackMust)) {
-      fMustDigiQa = std::make_unique<must::DigiQa>(fSender, mustCfg);
-      fMustDigiQa->Init();
+    if (opts.RunId() >= 3231) {
+      must::ReadoutConfig mustCfg = yaml::ReadFromFile<must::ReadoutConfig>(Opts().ParamsDir() / parFiles.must.readout);
+      fMustUnpack                 = std::make_unique<must::Unpack>(mustCfg);
+      if (fSender != nullptr && Opts().Has(QaStep::UnpackMust)) {
+        fMustDigiQa = std::make_unique<must::DigiQa>(fSender, mustCfg);
+        fMustDigiQa->Init();
+      }
     }
   }
 
diff --git a/macro/must/MustReadout_mcbm2025_02.yaml b/macro/must/MustReadout_mcbm2025_02.yaml
deleted file mode 100644
index ecce596f6a..0000000000
--- a/macro/must/MustReadout_mcbm2025_02.yaml
+++ /dev/null
@@ -1,29 +0,0 @@
-systemVersion: 0x03
-timeOffset: 100
-equipmentIds: [ 0x3001 ]
-TRBAddresses: [ 0x9991, 0x9992, 0x9993, 0x9994, 0x9995, 0x9996, 0x9997, 0x9998 ]
-ToTShifts:
-  0x9991: [ 0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00 ]
-  0x9992: [ 0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00 ]
-  0x9993: [ 0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00 ]
-  0x9994: [ 0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00 ]
-  0x9995: [ 0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00 ]
-  0x9996: [ 0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00 ]
-  0x9997: [ 0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00 ]
-  0x9998: [ 0.00,  10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
-            10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00 ]
-- 
GitLab


From 5245a7f362a187f1113f2233c8d0f8ff807517b3 Mon Sep 17 00:00:00 2001
From: Bartosz Sobol <bartosz.sobol@doctoral.uj.edu.pl>
Date: Mon, 10 Feb 2025 20:29:18 +0100
Subject: [PATCH 19/21] [PASTA/MUST] typo, comment run id

---
 algo/global/Reco.cxx          | 2 +-
 algo/qa/unpack/MustDigiQa.cxx | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx
index 87d2391ef8..e98143bbca 100644
--- a/algo/global/Reco.cxx
+++ b/algo/global/Reco.cxx
@@ -146,7 +146,7 @@ void Reco::Init(const Options& opts)
     fRichUnpack = std::make_unique<rich::Unpack>(richCfg);
 
     //TODO handle under fles::Subsystem::MUST when available
-    if (opts.RunId() >= 3231) {
+    if (opts.RunId() >= 3231) {  // ID of the first PASTA run
       must::ReadoutConfig mustCfg = yaml::ReadFromFile<must::ReadoutConfig>(Opts().ParamsDir() / parFiles.must.readout);
       fMustUnpack                 = std::make_unique<must::Unpack>(mustCfg);
       if (fSender != nullptr && Opts().Has(QaStep::UnpackMust)) {
diff --git a/algo/qa/unpack/MustDigiQa.cxx b/algo/qa/unpack/MustDigiQa.cxx
index d75ef44690..3d9530c636 100644
--- a/algo/qa/unpack/MustDigiQa.cxx
+++ b/algo/qa/unpack/MustDigiQa.cxx
@@ -47,7 +47,7 @@ namespace cbm::algo::must
     }
 
     auto canvas    = qa::CanvasConfig("must_digi/must_digi_vs_trb_channel", "MUST digis per channel in TRBs", 1, 1);
-    fChannel2DHist = fQaData.MakeObj<qa::H2D>("must_digi_trb_channel", "Digis per channel inTRBs", TRBIds.size(), 0,
+    fChannel2DHist = fQaData.MakeObj<qa::H2D>("must_digi_trb_channel", "Digis per channel in TRBs", TRBIds.size(), 0,
                                               *std::max_element(TRBIds.cbegin(), TRBIds.cend())
                                                 - *std::min_element(TRBIds.cbegin(), TRBIds.cend()) + 1,
                                               33, 0, 33);
-- 
GitLab


From d340ee131f822474965fe019f7342e696caec78b Mon Sep 17 00:00:00 2001
From: Bartosz Sobol <bartosz.sobol@doctoral.uj.edu.pl>
Date: Wed, 12 Feb 2025 21:04:16 +0100
Subject: [PATCH 20/21] [PASTA/MUST] apply Setup::mCBM2025_02

---
 algo/global/ParFiles.cxx | 4 ++--
 algo/global/Reco.cxx     | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/algo/global/ParFiles.cxx b/algo/global/ParFiles.cxx
index df00edbb98..adf9f8f93b 100644
--- a/algo/global/ParFiles.cxx
+++ b/algo/global/ParFiles.cxx
@@ -22,8 +22,6 @@ ParFiles::ParFiles(uint32_t runId)
     setup = Setup::mCBM2025_02;
   }
 
-  must.readout = "mcbm2025/MustReadout_mcbm2025_02.yaml";  //TODO this should be moved to 2025 case when available
-
   switch (setup) {
 
     case Setup::mCBM2022:
@@ -121,6 +119,8 @@ ParFiles::ParFiles(uint32_t runId)
       trd.hitfinder   = "mcbm2025_02/TrdHitfinderPar.yaml";
       trd.hitfinder2d = "mcbm2025_02/TrdHitfinder2DPar.yaml";
 
+      must.readout = "mcbm2025/MustReadout_mcbm2025_02.yaml";
+
       ca.mainConfig = "mcbm2025_02/TrackingChainConfig.yaml";
 
       kfp.V0FinderConfig = "mcbm2025_02/kfp_lambda_v25a.yaml";
diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx
index e98143bbca..e5f5a0375a 100644
--- a/algo/global/Reco.cxx
+++ b/algo/global/Reco.cxx
@@ -146,7 +146,7 @@ void Reco::Init(const Options& opts)
     fRichUnpack = std::make_unique<rich::Unpack>(richCfg);
 
     //TODO handle under fles::Subsystem::MUST when available
-    if (opts.RunId() >= 3231) {  // ID of the first PASTA run
+    if (parFiles.setup == Setup::mCBM2025_02) {
       must::ReadoutConfig mustCfg = yaml::ReadFromFile<must::ReadoutConfig>(Opts().ParamsDir() / parFiles.must.readout);
       fMustUnpack                 = std::make_unique<must::Unpack>(mustCfg);
       if (fSender != nullptr && Opts().Has(QaStep::UnpackMust)) {
-- 
GitLab


From d8f089cdda9a6a3647d3067ec915bc3d15c491ff Mon Sep 17 00:00:00 2001
From: Bartosz Sobol <bartosz.sobol@doctoral.uj.edu.pl>
Date: Wed, 12 Feb 2025 21:22:15 +0100
Subject: [PATCH 21/21] [PASTA/MUST] fix

---
 algo/global/ParFiles.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/algo/global/ParFiles.cxx b/algo/global/ParFiles.cxx
index adf9f8f93b..0c37f2781d 100644
--- a/algo/global/ParFiles.cxx
+++ b/algo/global/ParFiles.cxx
@@ -119,7 +119,7 @@ ParFiles::ParFiles(uint32_t runId)
       trd.hitfinder   = "mcbm2025_02/TrdHitfinderPar.yaml";
       trd.hitfinder2d = "mcbm2025_02/TrdHitfinder2DPar.yaml";
 
-      must.readout = "mcbm2025/MustReadout_mcbm2025_02.yaml";
+      must.readout = "mcbm2025_02/MustReadout_mcbm2025_02.yaml";
 
       ca.mainConfig = "mcbm2025_02/TrackingChainConfig.yaml";
 
-- 
GitLab