From 8ef021ce8cc89005fe137b0fdbb3e6a1b6f089e4 Mon Sep 17 00:00:00 2001
From: "s.zharko@gsi.de" <s.zharko@gsi.de>
Date: Wed, 22 May 2024 16:34:08 +0200
Subject: [PATCH] [bugfix]: offline QA: ECbmRecoMode::Timeslice as a default
 for data processing in the CbmQaTask class

---
 core/qa/CbmQaTask.cxx        | 12 +++++++-----
 core/qa/CbmQaTask.h          | 20 ++++++++++++--------
 macro/run/run_qa.C           |  5 ++---
 reco/L1/qa/CbmCaOutputQa.cxx |  3 ++-
 reco/L1/qa/CbmCaOutputQa.h   |  3 ++-
 5 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/core/qa/CbmQaTask.cxx b/core/qa/CbmQaTask.cxx
index cf5943daee..7e90ccdf1d 100644
--- a/core/qa/CbmQaTask.cxx
+++ b/core/qa/CbmQaTask.cxx
@@ -29,10 +29,11 @@ ClassImp(CbmQaTask);
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-CbmQaTask::CbmQaTask(const char* name, int verbose, bool isMCUsed)
+CbmQaTask::CbmQaTask(const char* name, int verbose, bool isMCUsed, ECbmRecoMode recoMode)
   : FairTask(name, verbose)
   , CbmQaIO(name)
   , fbUseMC(isMCUsed)
+  , fRecoMode(recoMode)
 {
   CbmQaIO::SetRootFolderName(name);
   fStoringMode = CbmQaIO::EStoringMode::kSUBDIR;  // mode of objects arrangement in the output file
@@ -103,17 +104,18 @@ InitStatus CbmQaTask::Init()
   res = std::max(res, InitHistograms());
 
   // ----- Initialize event branch
-  if (!fbProcessFullTs) {
+  if (ECbmRecoMode::EventByEvent == fRecoMode) {
     fpBrEvents = dynamic_cast<TClonesArray*>(FairRootManager::Instance()->GetObject("CbmEvent"));
     if (fpBrEvents) {
-      LOG_IF(info, fVerbose > 1) << fName << ": the routine will run on events";
+      LOG_IF(info, fVerbose > 1) << fName << ": the routine will run on reconstructed events";
     }
     else {
-      LOG_IF(info, fVerbose > 1) << fName << ": the routine will run on TS, the CbmEvent branch is undefined";
+      LOG_IF(info, fVerbose > 1) << fName << ": the routine will run on timeslices, the CbmEvent branch is undefined";
+      fRecoMode = ECbmRecoMode::Timeslice;
     }
   }
   else {
-    LOG_IF(info, fVerbose > 1) << fName << ": the routine will run on TS, the CbmEvent branch is disabled with flag";
+    LOG_IF(info, fVerbose > 1) << fName << ": the routine will run on timeslices";
   }
 
   fNofEvents.SetVal(0);
diff --git a/core/qa/CbmQaTask.h b/core/qa/CbmQaTask.h
index e2df685e05..8246629694 100644
--- a/core/qa/CbmQaTask.h
+++ b/core/qa/CbmQaTask.h
@@ -71,7 +71,8 @@ class CbmQaTask : public FairTask, public CbmQaIO {
   /// \param  name     Name of the task
   /// \param  verbose  Verbose level
   /// \param  isMCUsed Flag: true - MC information is used, false - only reconstructed data QA is processed
-  CbmQaTask(const char* name, int verbose, bool isMCUsed);
+  /// \param  recoMode Reconstruction mode (see documentation for the CbmQaTask::SetRecoMode function)
+  CbmQaTask(const char* name, int verbose, bool isMCUsed, ECbmRecoMode recoMode = ECbmRecoMode::Timeslice);
 
   /// \brief Default constructor
   CbmQaTask() = delete;  // TODO: Let's see, what can happen, if one deletes default constructor
@@ -150,12 +151,13 @@ class CbmQaTask : public FairTask, public CbmQaIO {
   /// \brief Sets default tag
   void SetDefaultTag(const TString& tag) { fsDefaultTag = tag; }
 
-  /// \brief Sets events suppression flag
+  /// \brief Sets data processing (reconstruction) mode
   ///
-  /// By default the QA task runs on the reconstructed events (CbmEvent objects), if the tree of the objects is
-  /// presented in the input. This flag disables the events-based routine, so the QA is executed over the whole
-  /// Time-slice.
-  void SetProcessFullTs(bool bProcessFullTs) { fbProcessFullTs = bProcessFullTs; }
+  /// The reconstruction mode can be either ECbmRecoMode::Timeslice or ECbmRecoMode::EventByEvent. The first
+  /// variant implies, that the data are processed within entire time-slice (in the event-by-event simulation within
+  /// the entire event). For the second variant the data are processed within a loop of CbmEvent objects, if the
+  /// branch of latter is accessible. By default the ECbmRecoMode::Timeslice is used.
+  void SetRecoMode(ECbmRecoMode recoMode) { fRecoMode = recoMode; }
 
   /// \brief Sets name of the setup
   void SetSetupName(const char* setup) { fsSetupName = setup; }
@@ -236,6 +238,10 @@ class CbmQaTask : public FairTask, public CbmQaIO {
   bool CompareTwoObjects(const TObject* pObjL, const TObject* pObjR, const TString& objName,
                          const ObjectComparisonConfig& cfg);
 
+  bool fbUseMC = false;  ///< Flag, if MC is used
+
+  ECbmRecoMode fRecoMode = ECbmRecoMode::Timeslice;  ///< Reconstruction mode
+
   /// \brief A QA check-list map
   ///
   /// The check list is updated with new entries with the StoreCheckResult(tag, result) function, which is to be called
@@ -249,8 +255,6 @@ class CbmQaTask : public FairTask, public CbmQaIO {
   CbmEvent* fpCurrentEvent = nullptr;  ///< Pointer to the current event
   std::string fsSetupName = "";  ///< Name of the setup (to draw on the canvases)
   TParameter<int> fNofEvents{"nEvents", 0};  ///< Number of processed events
-  bool fbUseMC         = false;              ///< Flag, if MC is used
-  bool fbProcessFullTs = false;              ///< If true, routine runs on the full TS even if the CbmEvent branch is in
 
   TString fsVersionTag = "";  ///< Version tag (git SHA etc.)
   TString fsDefaultTag = "";  ///< Default tag (git SHA etc.)
diff --git a/macro/run/run_qa.C b/macro/run/run_qa.C
index d1d613abf2..69d2fd2b6f 100644
--- a/macro/run/run_qa.C
+++ b/macro/run/run_qa.C
@@ -120,7 +120,7 @@ void run_qa(TString dataTraColl,
   // ------------------------------------------------------------------------
 
   // -----   Some global switches   -----------------------------------------
-  bool bEventBasedReco = !sEvBuildRaw.IsNull();
+  ECbmRecoMode recoMode = !sEvBuildRaw.IsNull() ? ECbmRecoMode::EventByEvent : ECbmRecoMode::Timeslice;
   bool bUseMvd  = geo->IsActive(ECbmModuleId::kMvd);
   bool bUseSts  = geo->IsActive(ECbmModuleId::kSts);
   bool bUseRich = geo->IsActive(ECbmModuleId::kRich);
@@ -303,8 +303,7 @@ void run_qa(TString dataTraColl,
   TString caParFile = recFile;
   caParFile.ReplaceAll(".root", ".ca.par");
 
-  auto* pCaOutputQa = new cbm::ca::OutputQa(verbose, bUseMC);
-  pCaOutputQa->SetProcessFullTs(!bEventBasedReco);
+  auto* pCaOutputQa = new cbm::ca::OutputQa(verbose, bUseMC, recoMode);
   pCaOutputQa->SetStsTrackingMode();
   pCaOutputQa->ReadParameters(caParFile.Data());
   if (config.Length() != 0) {
diff --git a/reco/L1/qa/CbmCaOutputQa.cxx b/reco/L1/qa/CbmCaOutputQa.cxx
index 52c2372af1..815754cd5c 100644
--- a/reco/L1/qa/CbmCaOutputQa.cxx
+++ b/reco/L1/qa/CbmCaOutputQa.cxx
@@ -29,7 +29,8 @@ using cbm::ca::tools::MCTrack;
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-OutputQa::OutputQa(int verbose, bool isMCUsed) : CbmQaTask("CbmCaOutputQa", verbose, isMCUsed)
+OutputQa::OutputQa(int verbose, bool isMCUsed, ECbmRecoMode recoMode)
+  : CbmQaTask("CbmCaOutputQa", verbose, isMCUsed, recoMode)
 {
   // Create TS reader
   fpTSReader = std::make_unique<TimeSliceReader>();
diff --git a/reco/L1/qa/CbmCaOutputQa.h b/reco/L1/qa/CbmCaOutputQa.h
index 6b1bdd3b62..48a40e06eb 100644
--- a/reco/L1/qa/CbmCaOutputQa.h
+++ b/reco/L1/qa/CbmCaOutputQa.h
@@ -116,7 +116,8 @@ namespace cbm::ca
     /// @brief  Constructor from parameters
     /// @param  verbose   Verbosity level
     /// @param  isMCUsed  Flag, if MC information is available for this task
-    OutputQa(int verbose, bool isMCUsed);
+    /// @param  recoMode  Reconstruction mode (see documentation for the CbmQaTask::SetRecoMode function)
+    OutputQa(int verbose, bool isMCUsed, ECbmRecoMode recoMode = ECbmRecoMode::EventByEvent);
 
     /// @brief Adds track type
     /// @param type  Track type
-- 
GitLab