From 9f3e7bf8a16619efb683881d3056cbd2cbdf52bf Mon Sep 17 00:00:00 2001
From: "s.zharko@gsi.de" <s.zharko@gsi.de>
Date: Thu, 13 Feb 2025 20:12:02 +0100
Subject: [PATCH 1/4] fixing the Setup QA

---
 macro/beamtime/mcbm2024/reco_mcbm.sh | 62 ++++++++++++++++++----------
 macro/mcbm/mcbm_qa.C                 |  2 +-
 reco/L1/qa/CbmCaInputQaSetup.cxx     | 19 +++++++++
 reco/L1/qa/CbmCaInputQaSetup.h       |  3 ++
 4 files changed, 63 insertions(+), 23 deletions(-)

diff --git a/macro/beamtime/mcbm2024/reco_mcbm.sh b/macro/beamtime/mcbm2024/reco_mcbm.sh
index c3053f4cd7..f004b131b9 100755
--- a/macro/beamtime/mcbm2024/reco_mcbm.sh
+++ b/macro/beamtime/mcbm2024/reco_mcbm.sh
@@ -61,6 +61,7 @@
 #   Options for running on the batch farm:
 #     -j [--job] <jobId>        Index of the job (default == 1)
 #        
+#     --disable-logs  Disables storing output in the temporary log files   
 #
 # 3. File names involved:
 #   <geo>:       Input geometry file:  <top_dir>/<setup>.geo.root
@@ -101,6 +102,7 @@
 
 # Data directory
 DATA_TOP_DIR='./data'
+DISABLE_LOGS=0
 
 # Subsystem flags
 RECO_MVD=0
@@ -223,6 +225,9 @@ while [[ $# -gt 0 ]]; do
     --run )
       RUN_IF_ONLY_SETUP_NEEDED=${2}
       ;;
+    --disable-logs )
+      DISABLE_LOGS=1
+      ;;
   esac
   shift
 done
@@ -485,16 +490,20 @@ if [[ ${DO_RECO} -eq 1 ]]; then
   if [[ ${MACRO_RECO} == "*.mcbm2024*" ]]; then
     PARS="${PARS},${RECO_PV}"
   fi
-  root -b -l -q ${MACRO_RECO}"(${PARS})" &> ${RECO_LOG}
-  cat ${RECO_LOG}
 
-  if [[ (1 -ne $(grep -c " Test passed" "${RECO_LOG}")) || (1 -ne $(grep -c " All ok " "${RECO_LOG}")) ]]; then
-    printf "\nReconstruction of %s failed, stopping there\n" "${TSA_INP}"
+  if [[ ${DISABLE_LOGS} -eq 1 ]]; then
+    root -b -l -q ${MACRO_RECO}"(${PARS})"
+  else 
+    root -b -l -q ${MACRO_RECO}"(${PARS})" &> ${RECO_LOG}
+    cat ${RECO_LOG}
+
+    if [[ (1 -ne $(grep -c " Test passed" "${RECO_LOG}")) || (1 -ne $(grep -c " All ok " "${RECO_LOG}")) ]]; then
+      printf "\nReconstruction of %s failed, stopping there\n" "${TSA_INP}"
+      rm ${RECO_LOG}
+      exit 7
+    fi
     rm ${RECO_LOG}
-    exit 7
   fi
-  rm ${RECO_LOG}
-
   # ln -s -f "${FILE_LABEL}.digi.root" "${DATA_TOP_DIR}/${FILE_LABEL}.raw.root"  # TMP for QA
   # Commented out as the output of mcbm_event_reco_L1.C is already [...].rec.root
   #  ln -s -f "${FILE_LABEL}.reco.root" "${DATA_TOP_DIR}/${FILE_LABEL}.rec.root"  # TMP for QA
@@ -526,15 +535,19 @@ if [[ ${DO_QA_MODULE} -eq 1 ]]; then
   ln -s ${SETUP_GEO_FILE} $(basename ${QA_GEO})
 
   PARS="-1,\"${QA_REC}\",\"${SETUP_NAME}\",kFALSE,${RECO_ALI}"
-  root -b -l -q ${MACRO_QA_MODULE}"(${PARS})" &> ${RECO_QA_LOG}
-  cat ${RECO_QA_LOG}
-
-  if [[ (1 -ne $(grep -c " Test passed" "${RECO_QA_LOG}")) || (1 -ne $(grep -c " All ok " "${RECO_QA_LOG}")) ]]; then
-    printf "\nReco Modules QA for %s failed, stopping there\n" "${TSA_INP}"
+  if [[ ${DISABLE_LOGS} -eq 1 ]]; then
+    root -b -l -q ${MACRO_QA_MODULE}"(${PARS})"
+  else
+    root -b -l -q ${MACRO_QA_MODULE}"(${PARS})" &> ${RECO_QA_LOG}
+    cat ${RECO_QA_LOG}
+
+    if [[ (1 -ne $(grep -c " Test passed" "${RECO_QA_LOG}")) || (1 -ne $(grep -c " All ok " "${RECO_QA_LOG}")) ]]; then
+      printf "\nReco Modules QA for %s failed, stopping there\n" "${TSA_INP}"
+      rm ${RECO_QA_LOG}
+      exit 8
+    fi
     rm ${RECO_QA_LOG}
-    exit 8
   fi
-  rm ${RECO_QA_LOG}
 fi
 
 # ----- Run QA
@@ -551,16 +564,21 @@ if [[ ${DO_QA} -eq 1 ]]; then
 
   PARS="0,\"\",\"${QA_RAW}\",\"${QA_REC}\",\"${QA_PAR}\",\"${QA_GEO}\",\"${QA_OUT}\",\"${SETUP_NAME}\""
   PARS="${PARS},${USE_MC},\"${CONFIG}\",\"${BENCHMARK}\",${RECO_ALI}"
-  root -b -l -q ${MACRO_QA}"(${PARS})" &> ${QA_LOG}
-  cat ${QA_LOG}
-
-  if [[ (1 -eq $(grep -c " QA checks failed" "${QA_LOG}")) || (1 -ne $(grep -c " Test passed" "${QA_LOG}"))
-        || (1 -ne $(grep -c " All ok " "${QA_LOG}")) ]]; then
-    printf "\nFull QA for %s failed, stopping there\n" "${TSA_INP}"
+  
+  if [[ ${DISABLE_LOGS} -eq 1 ]]; then
+    root -b -l -q ${MACRO_QA}"(${PARS})"
+  else
+    root -b -l -q ${MACRO_QA}"(${PARS})" &> ${QA_LOG}
+    cat ${QA_LOG}
+
+    if [[ (1 -eq $(grep -c " QA checks failed" "${QA_LOG}")) || (1 -ne $(grep -c " Test passed" "${QA_LOG}"))
+          || (1 -ne $(grep -c " All ok " "${QA_LOG}")) ]]; then
+      printf "\nFull QA for %s failed, stopping there\n" "${TSA_INP}"
+      rm ${QA_LOG}
+      exit 9
+    fi
     rm ${QA_LOG}
-    exit 9
   fi
-  rm ${QA_LOG}
 fi
 
 # ----- Run Lambda reconstuction using the KFParticleFinder
diff --git a/macro/mcbm/mcbm_qa.C b/macro/mcbm/mcbm_qa.C
index 5310cba1e0..3025d5783c 100644
--- a/macro/mcbm/mcbm_qa.C
+++ b/macro/mcbm/mcbm_qa.C
@@ -227,7 +227,7 @@ void mcbm_qa(Int_t nEvents = 0,
   run->SetSink(sink);
 
   TString monitorFile{sinkFile};
-  monitorFile.ReplaceAll("qa", "qa.monitor");
+  monitorFile.ReplaceAll(".qa.root", ".qa.monitor.root");
   FairMonitor::GetMonitor()->EnableMonitor(kTRUE, monitorFile);
   // ------------------------------------------------------------------------
 
diff --git a/reco/L1/qa/CbmCaInputQaSetup.cxx b/reco/L1/qa/CbmCaInputQaSetup.cxx
index 5ef74c3bb8..ceaa683a71 100644
--- a/reco/L1/qa/CbmCaInputQaSetup.cxx
+++ b/reco/L1/qa/CbmCaInputQaSetup.cxx
@@ -13,6 +13,7 @@
 #include "CbmL1DetectorID.h"
 #include "CbmMCDataManager.h"
 #include "FairRootManager.h"
+#include "CbmSetup.h"
 #include "TAxis.h"
 
 #include <Logger.h>
@@ -49,6 +50,23 @@ void InputQaSetup::CheckInit() const
   }
 }
 
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void InputQaSetup::CheckoutDetectors()
+{
+  auto CheckDetector = [&] (ca::EDetectorID detID) {
+    if (CbmSetup::Instance()->IsActive(ToCbmModuleId(detID))) {
+      fvbUseDet[detID] = true;
+    }
+    L_(info) << fName << ": " << ToString(ToCbmModuleId(detID)) << " " << fvbUseDet[detID];
+  };
+  CheckDetector(ca::EDetectorID::kMvd);
+  CheckDetector(ca::EDetectorID::kSts);
+  CheckDetector(ca::EDetectorID::kMuch);
+  CheckDetector(ca::EDetectorID::kTrd);
+  CheckDetector(ca::EDetectorID::kTof);
+}
+
 // ---------------------------------------------------------------------------------------------------------------------
 //
 void InputQaSetup::CreateSummary()
@@ -252,6 +270,7 @@ void InputQaSetup::ExecQa()
 InitStatus InputQaSetup::InitQa()
 try {
   LOG(info) << fName << ": initializing... ";
+  CheckoutDetectors();
 
   // Tracking parameters
   fpParameters = cbm::ca::ParametersHandler::Instance()->Get(fsParametersFilename);
diff --git a/reco/L1/qa/CbmCaInputQaSetup.h b/reco/L1/qa/CbmCaInputQaSetup.h
index 3cf3ad887a..2196339f45 100644
--- a/reco/L1/qa/CbmCaInputQaSetup.h
+++ b/reco/L1/qa/CbmCaInputQaSetup.h
@@ -64,6 +64,9 @@ namespace cbm::ca
 
 
    private:
+    /// \brief Check out initialized detectors
+    void CheckoutDetectors();
+
     /// \brief Checks branches initialization
     void CheckInit() const;
 
-- 
GitLab


From 9cafccf2a681a715d2e9d6069cea0fefc55e5347 Mon Sep 17 00:00:00 2001
From: "s.zharko@gsi.de" <s.zharko@gsi.de>
Date: Fri, 14 Feb 2025 04:38:38 +0100
Subject: [PATCH 2/4] CA: disabling stations from yaml config iin online

---
 algo/ca/TrackingChain.cxx            | 35 +++++++++++++++++++++++++---
 algo/ca/core/pars/CaConfigReader.cxx | 10 +++++---
 algo/ca/core/pars/CaConfigReader.h   |  5 ++--
 algo/ca/core/pars/CaInitManager.cxx  | 25 ++++++++++++++++++++
 algo/ca/core/pars/CaInitManager.h    | 10 ++++++++
 reco/L1/qa/CbmCaInputQaSetup.cxx     |  7 ++++--
 6 files changed, 82 insertions(+), 10 deletions(-)

diff --git a/algo/ca/TrackingChain.cxx b/algo/ca/TrackingChain.cxx
index 3810670e9f..1d481261a1 100644
--- a/algo/ca/TrackingChain.cxx
+++ b/algo/ca/TrackingChain.cxx
@@ -13,6 +13,7 @@
 #include "CaHit.h"
 #include "CaInitManager.h"
 #include "CaParameters.h"
+#include "KfSetupBuilder.h"
 #include "ParFiles.h"
 #include "compat/OpenMP.h"
 #include "yaml/Yaml.h"
@@ -66,6 +67,8 @@ void TrackingChain::Init()
   L_(info) << "Tracking Chain: reading geometry from CA parameters file " << GNb << geomCfgFile << CL << '\n';
   L_(info) << "Tracking Chain: reading geometry setup file " << GNb << setupCfgFile << CL << '\n';
   L_(info) << "Tracking Chain: reading parameters from CA main config " << GNb << mainCfgFile << CL << '\n';
+
+  //* InitManager instantiation
   auto manager = InitManager{};
   manager.SetDetectorNames(ca::kDetName);
   manager.SetConfigMain(mainCfgFile);
@@ -73,10 +76,36 @@ void TrackingChain::Init()
     L_(info) << "Tracking Chain: applying user configuration from " << GNb << userCfgFile << CL << '\n';
     manager.SetConfigUser(userCfgFile);
   }
-  manager.ReadParametersObject(geomCfgFile);  // geometry setup
-  manager.ReadInputConfigs();
-  manager.ReadGeometrySetup(setupCfgFile);
+
+  //* Read parameters object from the geomCfgFile to intialize tracking stations
+  {
+    manager.ReadParametersObject(geomCfgFile);  // geometry setup
+    auto paramIn = manager.TakeParameters();
+    manager.ClearSetupInfo();
+
+    //* Read setup
+    auto geoSetup = kf::SetupBuilder::Load<ca::fvec>(setupCfgFile);
+    kf::Target<double> target(geoSetup.GetTarget());
+
+    //* Initialize tracking parameters
+    manager.SetFieldFunction([](const double(&)[3], double(&outB)[3]) {
+      outB[0] = 0.;
+      outB[1] = 0.;
+      outB[2] = 0.;
+    });
+    manager.SetTargetPosition(target.GetX(), target.GetY(), target.GetZ());
+    manager.InitTargetField(2.5 /*cm*/);
+    manager.AddStations(paramIn);  // Initialize stations
+    manager.InitStationLayout();
+    manager.ReadInputConfigs();
+    manager.SetGeometrySetup(geoSetup);
+    manager.DevSetIsParSearchWUsed(false);
+    if (!manager.FormParametersContainer()) {
+      throw std::runtime_error("Initialization of CA parameters failed");
+    }
+  }
   auto parameters = manager.TakeParameters();
+
   L_(info) << "Tracking Chain: parameters object: \n" << parameters.ToString(1) << '\n';
 
   // ------ Used detector subsystem flags
diff --git a/algo/ca/core/pars/CaConfigReader.cxx b/algo/ca/core/pars/CaConfigReader.cxx
index 5df9fc277e..1c84cc1665 100644
--- a/algo/ca/core/pars/CaConfigReader.cxx
+++ b/algo/ca/core/pars/CaConfigReader.cxx
@@ -33,7 +33,8 @@ ConfigReader::ConfigReader(InitManager* pInitManager, int verbose) : fpInitManag
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-YAML::Node ConfigReader::GetNode(std::function<YAML::Node(YAML::Node)> fn) const
+// TODO: switch to the Yaml library by Felix
+YAML::Node ConfigReader::GetNode(std::function<YAML::Node(YAML::Node)> fn, bool optional) const
 {
   auto node = YAML::Node(YAML::NodeType::Undefined);
   if (fUserConfigNode) {
@@ -42,7 +43,7 @@ YAML::Node ConfigReader::GetNode(std::function<YAML::Node(YAML::Node)> fn) const
   if (!node) {
     node = fn(fMainConfigNode);
   }
-  if (!node) {
+  if (!node && !optional) {
     std::stringstream msg;
     msg << "requested node was not found ";
     if (fUserConfigNode) {
@@ -250,7 +251,10 @@ std::vector<std::set<int>> ConfigReader::ReadInactiveStationMap()
 {
   // Check, if the "skip_stations" branch exists either in the user config or in the main config
   std::string sNodePath = "ca/core/common/inactive_stations";
-  auto node             = this->GetNode([](YAML::Node n) { return n["core"]["common"]["inactive_stations"]; });
+  auto node             = GetNode([](YAML::Node n) { return n["core"]["common"]["inactive_stations"]; }, true);
+  if (!node) {
+    return std::vector<std::set<int>>{};
+  }
 
   // Fill map of inactive stations
   std::vector<std::set<int>> vGeoIdToTrackingStatus(constants::size::MaxNdetectors);
diff --git a/algo/ca/core/pars/CaConfigReader.h b/algo/ca/core/pars/CaConfigReader.h
index 9178f975c1..7729c9c36c 100644
--- a/algo/ca/core/pars/CaConfigReader.h
+++ b/algo/ca/core/pars/CaConfigReader.h
@@ -78,14 +78,15 @@ namespace cbm::algo::ca
     void ReadMisalignmentTolerance();
 
     /// \brief Accesses a node either from user config or from main config
-    /// \param fn  A function, which returns a YAML::Node reference object
+    /// \param fn        A function, which returns a YAML::Node reference object
+    /// \param optional  true: node is not mandatory
     /// \note      If the node is not found in both configs
     /// \throw     std::runtime_error, if the path does not exist in the config
     ///
     /// This function is to be used, if the desired node should exist either in main or in user config. Firstly,
     /// the user config is checked, if it is provided. If the node is not found in user config, the main config
     /// is checked. If the node does not exist in the main config as well, an exception will be thrown.
-    YAML::Node GetNode(std::function<YAML::Node(YAML::Node)> fn) const;
+    YAML::Node GetNode(std::function<YAML::Node(YAML::Node)> fn, bool optional = false) const;
 
     /// \brief Reads iteration from config file
     /// \param node         YAML node containing an iteration
diff --git a/algo/ca/core/pars/CaInitManager.cxx b/algo/ca/core/pars/CaInitManager.cxx
index 4bdf43f9e6..744709404d 100644
--- a/algo/ca/core/pars/CaInitManager.cxx
+++ b/algo/ca/core/pars/CaInitManager.cxx
@@ -26,6 +26,29 @@ namespace cbm::algo::ca
   //
   void InitManager::AddStation(const StationInitializer& inStation) { fvStationInfo.push_back(inStation); }
 
+  // --------------------------------------------------------------------------------------------------------------------
+  //
+  void InitManager::AddStations(const Parameters<fvec>& par)
+  {
+    const auto& stations = par.GetStations();
+    for (int iSt = 0; iSt < par.GetNstationsActive(); ++iSt) {
+      auto stationIn = Station<double>(stations[iSt]);
+      // Get detector ID of the station
+      auto [detId, locId] = par.GetStationIndexLocal(par.GetActiveToGeoMap()[iSt]);
+      auto stationInfo    = ca::StationInitializer(detId, locId);
+      stationInfo.SetStationType(stationIn.type);
+      stationInfo.SetZmin(0.);  // NOTE: Deprecated (not used)
+      stationInfo.SetZmax(0.);  // NOTE: Deprecated (not used)
+      stationInfo.SetZref(stationIn.fZ);
+      stationInfo.SetXmax(stationIn.Xmax);
+      stationInfo.SetYmax(stationIn.Ymax);
+      stationInfo.SetFieldStatus(stationIn.fieldStatus);
+      stationInfo.SetTimeInfo(stationIn.timeInfo);
+      stationInfo.SetTrackingStatus(true);
+      this->AddStation(stationInfo);
+    }
+  }
+
   // --------------------------------------------------------------------------------------------------------------------
   //
   void InitManager::CheckInit()
@@ -78,6 +101,8 @@ namespace cbm::algo::ca
     fParameters.fDevIsExtendTracksViaMc        = false;
     fParameters.fDevIsSuppressOverlapHitsViaMc = false;
     fParameters.fDevIsParSearchWUsed           = false;
+
+    fbGeometryConfigLock = false;
   }
 
   // --------------------------------------------------------------------------------------------------------------------
diff --git a/algo/ca/core/pars/CaInitManager.h b/algo/ca/core/pars/CaInitManager.h
index b1dc5118f1..4e00f26586 100644
--- a/algo/ca/core/pars/CaInitManager.h
+++ b/algo/ca/core/pars/CaInitManager.h
@@ -105,6 +105,16 @@ namespace cbm::algo::ca
     /// \note The added station stays uninitialized until the Parameters object is formed
     void AddStation(const StationInitializer& station);
 
+    /// \brief Adds tracking stations from the parameters file
+    /// \param par  A valid instance of parameters, created for ACTIVE + INACTIVE tracking stations
+    ///
+    // TODO: Probably, we have to remove stations from the parameters and place them into a class ca::Geometery
+    //       together with instances of active and geometry kf::Setup. ca::Parameters should contain only tracking
+    //       parameters, which should be fully defined from the config. Search windows should be stored as an
+    //       independent object, which depends on the ca::Parameters(iterations) and ca::Geometry(active station
+    //       layout).
+    void AddStations(const Parameters<fvec>& par);
+
     /// \brief Provides final checks of the parameters object
     void CheckInit();
 
diff --git a/reco/L1/qa/CbmCaInputQaSetup.cxx b/reco/L1/qa/CbmCaInputQaSetup.cxx
index ceaa683a71..3b1489087a 100644
--- a/reco/L1/qa/CbmCaInputQaSetup.cxx
+++ b/reco/L1/qa/CbmCaInputQaSetup.cxx
@@ -12,8 +12,8 @@
 #include "CbmCaParametersHandler.h"
 #include "CbmL1DetectorID.h"
 #include "CbmMCDataManager.h"
-#include "FairRootManager.h"
 #include "CbmSetup.h"
+#include "FairRootManager.h"
 #include "TAxis.h"
 
 #include <Logger.h>
@@ -54,7 +54,7 @@ void InputQaSetup::CheckInit() const
 //
 void InputQaSetup::CheckoutDetectors()
 {
-  auto CheckDetector = [&] (ca::EDetectorID detID) {
+  auto CheckDetector = [&](ca::EDetectorID detID) {
     if (CbmSetup::Instance()->IsActive(ToCbmModuleId(detID))) {
       fvbUseDet[detID] = true;
     }
@@ -304,6 +304,9 @@ try {
   auto InitHitBranch = [&](const char* brName, ca::EDetectorID detID) {
     if (fvbUseDet[detID]) {
       fvpBrHits[detID] = dynamic_cast<TClonesArray*>(pFairManager->GetObject(brName));
+      if (!fvpBrHits[detID]) {
+        fvbUseDet[detID] = false;  // Disable detectors without hits
+      }
     }
     return static_cast<bool>(fvpBrHits[detID]);
   };
-- 
GitLab


From 73a522eccafd9bb806df7627773b7f8018e8f1e5 Mon Sep 17 00:00:00 2001
From: Alexandru Bercuci <abercuci@niham.nipne.ro>
Date: Sat, 15 Feb 2025 19:27:36 +0100
Subject: [PATCH 3/4] Online TRD2D: shift a message from error to debug

---
 algo/detectors/trd/Cluster2D.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/algo/detectors/trd/Cluster2D.cxx b/algo/detectors/trd/Cluster2D.cxx
index 19d6d2dcec..b628531719 100644
--- a/algo/detectors/trd/Cluster2D.cxx
+++ b/algo/detectors/trd/Cluster2D.cxx
@@ -162,7 +162,7 @@ namespace cbm::algo::trd
 
       // check column order for cluster  /// TO DO: we can probably drop this check
       if (last_col >= 0 && colT != last_col + 1) {
-        L_(error) << "TrdModuleRec2D::LoadDigis : digis in cluster not in increasing order !";
+        L_(debug) << "TrdModuleRec2D::LoadDigis : digis in cluster not in increasing order !";
         return false;
       }
       last_col              = colT;
-- 
GitLab


From d6857fe59c83176da4cedd6e1c6a78b186f6b24f Mon Sep 17 00:00:00 2001
From: "P.-A. Loizeau" <p.-a.loizeau@gsi.de>
Date: Sat, 15 Feb 2025 19:28:44 +0100
Subject: [PATCH 4/4] Bump params hash to catch up with Virgo instance of
 online processing

---
 external/InstallParameter.cmake | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/external/InstallParameter.cmake b/external/InstallParameter.cmake
index c8f4d23f40..77e3f424dc 100644
--- a/external/InstallParameter.cmake
+++ b/external/InstallParameter.cmake
@@ -1,4 +1,4 @@
-set(PARAMETER_VERSION db53df993ef7b4b977bae554763ebff7f5bf84f7) # 2025/02/14
+set(PARAMETER_VERSION cf6a880a56a8695b485efe358231270e9179cb82) # 2025/02/15
 set(PARAMETER_SRC_URL "https://git.cbm.gsi.de/CbmSoft/cbmroot_parameter.git")
 
 download_project_if_needed(PROJECT         Parameter_source
-- 
GitLab