From 2f2be3d3232eaf0836255ffd825a647783112578 Mon Sep 17 00:00:00 2001
From: Adrian Weber <adrian.a.weber@physik.uni-giessen.de>
Date: Mon, 14 Feb 2022 11:05:32 +0100
Subject: [PATCH] add Monitoring possibility to Rich unpacker v3

---
 macro/run/run_unpack_tsa.C                    | 39 +++++++++++
 reco/detectors/rich/CMakeLists.txt            |  1 +
 reco/detectors/rich/CbmRichRecoLinkDef.h      |  1 +
 .../rich/unpack/CbmRichUnpackAlgo2022.cxx     | 11 ++++
 .../rich/unpack/CbmRichUnpackAlgoBase.cxx     |  2 +
 .../rich/unpack/CbmRichUnpackAlgoBase.h       | 64 +++++++++++--------
 .../rich/unpack/CbmRichUnpackConfig.cxx       |  2 +
 .../rich/unpack/CbmRichUnpackConfig.h         | 10 ++-
 8 files changed, 103 insertions(+), 27 deletions(-)

diff --git a/macro/run/run_unpack_tsa.C b/macro/run/run_unpack_tsa.C
index ed2ec39e97..9cabe33e61 100644
--- a/macro/run/run_unpack_tsa.C
+++ b/macro/run/run_unpack_tsa.C
@@ -31,6 +31,7 @@
 std::shared_ptr<CbmTrdUnpackMonitor> GetTrdMonitor(std::string treefilename);
 std::shared_ptr<CbmTrdSpadic> GetTrdSpadic(bool useAvgBaseline = false);
 std::shared_ptr<CbmStsUnpackMonitor> GetStsMonitor(std::string treefilename, bool bDebugMode = false);
+std::shared_ptr<CbmRichUnpackMonitor> GetRichMonitor(std::string treefilename, bool bDebugMode = false);
 const char* defaultSetupName = "mcbm_beam_2021_07_surveyed";
 
 void run_unpack_tsa(std::vector<std::string> infile = {"test.tsa"}, UInt_t runid = 0,
@@ -110,6 +111,7 @@ void run_unpack_tsa(std::vector<std::string> infile = {"test.tsa"}, UInt_t runid
     if (1904 < runid) {
       /// Switch to new unpacking algo starting from first combined cosmics run in 2022
       richconfig->SetUnpackerVersion(CbmRichUnpackerVersion::v03);
+      richconfig->SetMonitor(GetRichMonitor(outfilename, true));
     }
 
     richconfig->SetDebugState();
@@ -117,6 +119,7 @@ void run_unpack_tsa(std::vector<std::string> infile = {"test.tsa"}, UInt_t runid
     std::string parfilesbasepathRich = Form("%s/macro/beamtime/mcbm2021/", srcDir.Data());
     richconfig->SetParFilesBasePath(parfilesbasepathRich);
     richconfig->SetSystemTimeOffset(256000 - 1200);  // [ns] 1 MS and additional correction
+    if (runid > 1904)  richconfig->SetSystemTimeOffset(-1200);
     if (runid == 1588) richconfig->MaskDiRICH(0x7150);
   }
   // -------------
@@ -418,6 +421,42 @@ std::shared_ptr<CbmStsUnpackMonitor> GetStsMonitor(std::string treefilename, boo
   return monitor;
 }
 
+/**
+ * @brief Get the Rich Monitor. Extra function to keep default macro part more silent.
+ * @return std::shared_ptr<CbmRichUnpackMonitor>
+*/
+std::shared_ptr<CbmRichUnpackMonitor> GetRichMonitor(std::string treefilename, bool bDebugMode = false)
+{
+  // -----   Output filename and path   -------------------------------------
+  std::string outpath  = "";
+  std::string filename = "";
+  auto filenamepos     = treefilename.find_last_of("/");
+  if (filenamepos != treefilename.npos) {
+    outpath  = treefilename.substr(0, filenamepos);
+    filename = treefilename.substr(filenamepos++);
+  }
+  if (outpath.empty()) outpath = gSystem->GetWorkingDirectory();
+
+  auto currentdir = gSystem->GetWorkingDirectory();
+
+  if (!gSystem->cd(outpath.data())) gSystem->MakeDirectory(outpath.data());
+  else
+    gSystem->cd(currentdir.data());
+
+  std::string outfilename = outpath + filename;
+  auto filetypepos        = outfilename.find(".digi.root");
+  if (filetypepos != outfilename.npos) outfilename.replace(filetypepos, 10, ".mon.rich.root");
+  else
+    outfilename += ".mon.rich.root";
+  // ------------------------------------------------------------------------
+
+  auto monitor = std::make_shared<CbmRichUnpackMonitor>();
+  monitor->SetHistoFileName(outfilename);
+  monitor->SetDebugMode(bDebugMode);
+
+  return monitor;
+}
+
 void run_unpack_tsa(std::string infile = "test.tsa", UInt_t runid = 0, const char* setupName = defaultSetupName,
                     std::int32_t nevents = -1, std::string outpath = "data/")
 {
diff --git a/reco/detectors/rich/CMakeLists.txt b/reco/detectors/rich/CMakeLists.txt
index b1defbaef2..f4839c5a96 100644
--- a/reco/detectors/rich/CMakeLists.txt
+++ b/reco/detectors/rich/CMakeLists.txt
@@ -86,6 +86,7 @@ qa/CbmRichRecoQa.cxx
 unpack/CbmRichUnpackAlgo.cxx
 unpack/CbmRichUnpackAlgo2022.cxx
 unpack/CbmRichUnpackAlgoBase.cxx
+unpack/CbmRichUnpackMonitor.cxx
 unpack/CbmRichUnpackConfig.cxx
 )
 
diff --git a/reco/detectors/rich/CbmRichRecoLinkDef.h b/reco/detectors/rich/CbmRichRecoLinkDef.h
index 667b0bf5d4..d6f65b9be9 100644
--- a/reco/detectors/rich/CbmRichRecoLinkDef.h
+++ b/reco/detectors/rich/CbmRichRecoLinkDef.h
@@ -36,6 +36,7 @@
 #pragma link C++ class CbmRichUnpackAlgo + ;
 #pragma link C++ class CbmRichUnpackAlgo2022 + ;
 #pragma link C++ class CbmRichUnpackAlgoBase + ;
+#pragma link C++ class CbmRichUnpackMonitor + ;
 #pragma link C++ class CbmRichUnpackConfig + ;
 
 
diff --git a/reco/detectors/rich/unpack/CbmRichUnpackAlgo2022.cxx b/reco/detectors/rich/unpack/CbmRichUnpackAlgo2022.cxx
index ca4e143092..31aeaba0b1 100644
--- a/reco/detectors/rich/unpack/CbmRichUnpackAlgo2022.cxx
+++ b/reco/detectors/rich/unpack/CbmRichUnpackAlgo2022.cxx
@@ -58,6 +58,14 @@ bool CbmRichUnpackAlgo2022::unpack(const fles::Timeslice* ts, std::uint16_t icom
   uint32_t msIndexWord2 = reader.NextWord();
   if (isLog()) LOG(DEBUG4) << getLogHeader(reader) << "Microslice Index 2:" << reader.GetWordAsHexString(msIndexWord2);
 
+  //Output debugging info
+  if (fMonitor) {
+    for (auto itHit = fOutputVec.begin(); itHit != fOutputVec.end(); ++itHit) {
+      fMonitor->FillDigisTimeInRun(itHit->GetTime());
+      fMonitor->FillDigisToT(itHit->GetToT());
+    }
+    fMonitor->FillVectorSize(ts->index(), fOutputVec.size());
+  }
 
   return true;
 }
@@ -391,6 +399,9 @@ void CbmRichUnpackAlgo2022::writeOutputDigi(Int_t fpgaID, Int_t channel, Double_
   //check ordering
   Double_t finalTime = time + (Double_t) fMsRefTime - fSystemTimeOffset;
 
+  // Do not accept digis, where the MS und TS differs by more than 6 sec (mainly TS0)
+  if (6e9 < finalTime) return;
+
   fOutputVec.emplace_back(pixelUID, finalTime, tot - ToTcorr);
 }
 
diff --git a/reco/detectors/rich/unpack/CbmRichUnpackAlgoBase.cxx b/reco/detectors/rich/unpack/CbmRichUnpackAlgoBase.cxx
index fd057ba80b..b7ef4db910 100644
--- a/reco/detectors/rich/unpack/CbmRichUnpackAlgoBase.cxx
+++ b/reco/detectors/rich/unpack/CbmRichUnpackAlgoBase.cxx
@@ -73,6 +73,8 @@ Bool_t CbmRichUnpackAlgoBase::initParSet(CbmMcbm2018RichPar* parset)
 
   LOG(info) << fName << "::initParSetRichMcbm2018 - Successfully initialized RICH unpacking parameters";
 
+  if (fMonitor) fMonitor->Init(parset);
+
   return kTRUE;
 }
 
diff --git a/reco/detectors/rich/unpack/CbmRichUnpackAlgoBase.h b/reco/detectors/rich/unpack/CbmRichUnpackAlgoBase.h
index 2f6cfc6111..a07b0b54c7 100644
--- a/reco/detectors/rich/unpack/CbmRichUnpackAlgoBase.h
+++ b/reco/detectors/rich/unpack/CbmRichUnpackAlgoBase.h
@@ -8,14 +8,14 @@
  * @brief Baseclass for the TrdR unpacker algorithms
  * @version 0.1
  * @date 2021-04-21
- * 
+ *
  * @copyright Copyright (c) 2021
- * 
- * This is the base class for the algorithmic part of the tsa data unpacking 
- * processes of the CbmTrd.
- * The actual translation from tsa to digi happens in the derived classes. 
- * 
- * 
+ *
+ * This is the base class for the algorithmic part of the tsa data unpacking
+ * processes of the CbmRich
+ * The actual translation from tsa to digi happens in the derived classes.
+ *
+ *
 */
 
 #ifndef CbmRichUnpackAlgoBase_H
@@ -25,6 +25,8 @@
 #include "CbmRecoUnpackAlgo.tmpl"
 #include "CbmRichDigi.h"
 
+#include "CbmRichUnpackMonitor.h"
+
 #include "Timeslice.hpp"  // timeslice
 
 #include <Rtypes.h>  // for types
@@ -209,9 +211,9 @@ public:
 
   /**
    * @brief Get the requested parameter containers. To be defined in the derived classes!
-   * Return the required parameter containers together with the paths to the ascii 
+   * Return the required parameter containers together with the paths to the ascii
    * files to.
-   *  
+   *
    * @param[in] std::string geoTag as used in CbmSetup
    * @param[in] std::uint32_t runId for runwise defined parameters
    * @return fParContVec
@@ -219,6 +221,11 @@ public:
   virtual std::vector<std::pair<std::string, std::shared_ptr<FairParGenericSet>>>*
   GetParContainerRequest(std::string geoTag, std::uint32_t runId);
 
+  // Setters
+  /** @brief Set a predefined monitor @param monitor predefined unpacking monitor */
+  void SetMonitor(std::shared_ptr<CbmRichUnpackMonitor> monitor) { fMonitor = monitor; }
+
+  /** @brief Set Addresses of DiRICH boards to be masked @param maskedDiRICHes vector of Addresses */
   void SetMaskedDiRICHes(std::vector<Int_t>* maskedDiRICHes) { fMaskedDiRICHes = maskedDiRICHes; }
 
 protected:
@@ -229,9 +236,14 @@ protected:
   {
     finishDerived();
     // Finish the monitor if we have one
-    // if (fMonitor) fMonitor->Finish();
+    std::cout<<"Finish Monitor"<<std::endl;
+    if (fMonitor) fMonitor->Finish();
   }
 
+  // Monitoring
+  /** @brief Potential (online) monitor for the unpacking process */
+  std::shared_ptr<CbmRichUnpackMonitor> fMonitor = nullptr;
+
   /** @brief Function that allows special calls during Finish in the derived algos */
   virtual void finishDerived() { return; }
 
@@ -246,24 +258,24 @@ protected:
 
   /**
    * @brief Intialisation at begin of run. Special inits of the derived algos.
-   * 
+   *
    * @retval Bool_t initOk
   */
   Bool_t init();
 
   /**
    * @brief Handles the distribution of the hidden derived classes to their explicit functions.
-   * 
-   * @param parset 
-   * @return Bool_t initOk 
+   *
+   * @param parset
+   * @return Bool_t initOk
   */
   Bool_t initParSet(FairParGenericSet* parset);
 
   /**
    * @brief Handles the distribution of the hidden derived classes to their explicit functions.
-   * 
-   * @param parset 
-   * @return Bool_t initOk 
+   *
+   * @param parset
+   * @return Bool_t initOk
   */
   Bool_t initParSet(CbmMcbm2018RichPar* parset);
 
@@ -271,24 +283,24 @@ protected:
 
   /**
    * @brief Set the Derived Ts Parameters
-   * 
+   *
    * In this function parameters required by the explicit algo connected to the timeslice can be set.
-   * 
-   * @param itimeslice 
-   * @return true 
-   * @return false 
+   *
+   * @param itimeslice
+   * @return true
+   * @return false
   */
   bool setDerivedTsParameters(size_t /*itimeslice*/) { return true; }
 
   /**
    * @brief Unpack a given microslice. To be implemented in the derived unpacker algos.
-   * 
+   *
    * @param ts timeslice pointer
    * @param icomp index to the component to be unpacked
    * @param imslice index of the microslice to be unpacked
-   * @return true 
-   * @return false 
-   * 
+   * @return true
+   * @return false
+   *
    * @remark The content of the µslice can only be accessed via the timeslice. Hence, we need to pass the pointer to the full timeslice
   */
   //bool unpack(const fles::Timeslice* ts, std::uint16_t icomp, UInt_t imslice);
diff --git a/reco/detectors/rich/unpack/CbmRichUnpackConfig.cxx b/reco/detectors/rich/unpack/CbmRichUnpackConfig.cxx
index 6aa968f57d..3137f57c65 100644
--- a/reco/detectors/rich/unpack/CbmRichUnpackConfig.cxx
+++ b/reco/detectors/rich/unpack/CbmRichUnpackConfig.cxx
@@ -28,6 +28,8 @@ void CbmRichUnpackConfig::InitAlgo()
   if (fDoLog) LOG(info) << fName << "::Init - SetMaskedDiRICHes";
   fAlgo->SetMaskedDiRICHes(&fMaskedDiRICHes);
 
+  if (fMonitor) { fAlgo->SetMonitor(fMonitor); }
+
   // Now we have all information required to initialise the algorithm
   fAlgo->Init();
 }
diff --git a/reco/detectors/rich/unpack/CbmRichUnpackConfig.h b/reco/detectors/rich/unpack/CbmRichUnpackConfig.h
index 68c5da1d59..369a50ffae 100644
--- a/reco/detectors/rich/unpack/CbmRichUnpackConfig.h
+++ b/reco/detectors/rich/unpack/CbmRichUnpackConfig.h
@@ -21,6 +21,7 @@
 #include "CbmRecoUnpackConfig.tmpl"
 #include "CbmRichDigi.h"
 #include "CbmRichUnpackAlgoBase.h"
+#include "CbmRichUnpackMonitor.h"
 
 #include <FairLogger.h>
 #include <Logger.h>
@@ -65,6 +66,8 @@ public:
   CbmRichUnpackConfig& operator=(const CbmRichUnpackConfig&) = delete;
 
   // Getters
+  /** @brief Get the potentially added monitor. */
+  std::shared_ptr<CbmRichUnpackMonitor> GetMonitor() { return fMonitor; }
 
 
   /**
@@ -74,11 +77,13 @@ public:
   void InitAlgo();
 
   // Setters
-
   void MaskDiRICH(Int_t DiRICH) { fMaskedDiRICHes.push_back(DiRICH); }
 
   void SetUnpackerVersion(CbmRichUnpackerVersion vers) { fUnpackerVersion = vers; }
 
+  /** @brief Add a monitor to the unpacker. @param value CbmRichUnpackMonitor */
+  void SetMonitor(std::shared_ptr<CbmRichUnpackMonitor> value) { fMonitor = value; }
+
 protected:
   /**
    * @brief Choose the derived unpacker algorithm to be used for the DAQ output to Digi translation. If algo was already set manually by the user this algorithm is used.
@@ -89,6 +94,9 @@ protected:
 
   std::vector<Int_t> fMaskedDiRICHes = {};
 
+  /** @brief pointer to the monitor object */
+  std::shared_ptr<CbmRichUnpackMonitor> fMonitor = nullptr;
+
   /** @brief Selector of Unpacker Version. */
   CbmRichUnpackerVersion fUnpackerVersion = CbmRichUnpackerVersion::v02;
 
-- 
GitLab