From 9c8f9fa7083a48bad9448a442ca7f5be061b333f Mon Sep 17 00:00:00 2001
From: P-A Loizeau <p.-a.loizeau@gsi.de>
Date: Fri, 10 Feb 2023 17:56:57 +0100
Subject: [PATCH] [MQ] in DigiEvent Sink, re-add cleanly digi evt fill loop for
 TRD

---
 MQ/mcbm/CbmDeviceDigiEventSink.cxx | 32 ++++++++++++++++++++++--------
 MQ/mcbm/CbmDeviceDigiEventSink.h   |  7 ++++---
 MQ/mcbm/runDigiEventSink.cxx       |  2 ++
 3 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/MQ/mcbm/CbmDeviceDigiEventSink.cxx b/MQ/mcbm/CbmDeviceDigiEventSink.cxx
index ddedd7a31d..d365048651 100644
--- a/MQ/mcbm/CbmDeviceDigiEventSink.cxx
+++ b/MQ/mcbm/CbmDeviceDigiEventSink.cxx
@@ -75,6 +75,7 @@ try {
   fbDisableCompression  = fConfig->GetValue<bool>("DisableCompression");
   fiTreeFileMaxSize     = fConfig->GetValue<int64_t>("TreeFileMaxSize");
   fbDigiEventInput      = fConfig->GetValue<bool>("DigiEventInput");
+  fbExclusiveTrdExtract = fConfig->GetValue<bool>("ExclusiveTrdExtract");
 
   fbFillHistos             = fConfig->GetValue<bool>("FillHistos");
   fuPublishFreqTs          = fConfig->GetValue<uint32_t>("PubFreqTs");
@@ -623,7 +624,7 @@ void CbmDeviceDigiEventSink::PrepareTreeEntry(CbmEventTimeslice unpTs)
 
   /// Extract CbmEvent vector from input message
   // FU, 29.06.22 Remove std::move to allow copy ellision
-  (*fEventsSel) = unpTs.GetSelectedData();
+  (*fEventsSel) = unpTs.GetSelectedData(fbExclusiveTrdExtract);
   if (kTRUE == fbFillHistos) {
     /// Accumulated counts, will show rise + plateau pattern in spill
     fulProcessedEvents += fEventsSel->size();
@@ -966,7 +967,7 @@ CbmEventTimeslice::~CbmEventTimeslice()
   fvDigiEvents.clear();
 }
 
-void CbmEventTimeslice::ExtractSelectedData()
+void CbmEventTimeslice::ExtractSelectedData(bool bExclusiveTrdExtract)
 {
   fvDigiEvents.reserve(fvEvents.size());
 
@@ -979,8 +980,8 @@ void CbmEventTimeslice::ExtractSelectedData()
     /// For pure digi based event, we select "continuous slices of digis"
     ///        => Copy block of [First Digi index, last digi index] with assign(it_start, it_stop)
     ///        => No data increase for most detectors as we use time window selection
-    /// FIXME: Keep TRD1D + TRD2D support as single det, otherwise may lead to holes in the digi sequence!
-    ///        => Would need to keep the loop to avoid adding extra digis
+    /// Keep TRD1D + TRD2D support as single det, otherwise may lead to holes in the digi sequence!
+    ///        => Need option to keep the loop to avoid adding extra digis if comparison to CbmEvents wanted
 
     /// Get the proper order for block selection as TRD1D and TRD2D may insert indices in separate loops
     /// => Needed to ensure that the start and stop of the block copy do not trigger a vector size exception
@@ -1018,10 +1019,25 @@ void CbmEventTimeslice::ExtractSelectedData()
     /// ==> TRD + TRD2D
     uNbDigis = (0 < event.GetNofData(ECbmDataType::kTrdDigi) ? event.GetNofData(ECbmDataType::kTrdDigi) : 0);
     if (uNbDigis) {
-      auto startIt = fvDigiTrd.begin() + event.GetIndex(ECbmDataType::kTrdDigi, 0);
-      auto stopIt  = fvDigiTrd.begin() + event.GetIndex(ECbmDataType::kTrdDigi, uNbDigis - 1);
-      ++stopIt;
-      selEvent.fData.fTrd.fDigis.assign(startIt, stopIt);
+      if (bExclusiveTrdExtract) {
+        for (uint32_t uDigiInEvt = 0; uDigiInEvt < uNbDigis; ++uDigiInEvt) {
+          /// Copy each digi in the event by itself to make sure we skip ones outside their own selection window but
+          /// inside the selection window of the other TRD subsystem, effectively enforcing differetn windows:
+          /// [t, t+dt](TRD) = [t, t+dt](TRD1D) + [t, t+dt](TRD2D)
+          /// => Exclusive but slower
+          selEvent.fData.fTrd.fDigis.push_back(fvDigiTrd[event.GetIndex(ECbmDataType::kTrdDigi, uDigiInEvt)]);
+        }
+      }
+      else {
+        /// Block copy of all TRD digis, has feature that it may include digis which are not matching the selection
+        /// window of a given TRD subsystem, effectively making a larger selection window:
+        /// [t, t+dt](TRD) = [t, t+dt](TRD1D) U [t, t+dt](TRD2D)
+        /// => Faster but inclusive, will lead to more TRD hits and tracks than expected
+        auto startIt = fvDigiTrd.begin() + event.GetIndex(ECbmDataType::kTrdDigi, 0);
+        auto stopIt  = fvDigiTrd.begin() + event.GetIndex(ECbmDataType::kTrdDigi, uNbDigis - 1);
+        ++stopIt;
+        selEvent.fData.fTrd.fDigis.assign(startIt, stopIt);
+      }
     }
 
     /// ==> TOF
diff --git a/MQ/mcbm/CbmDeviceDigiEventSink.h b/MQ/mcbm/CbmDeviceDigiEventSink.h
index 8c016409bc..cd79f1fbd6 100644
--- a/MQ/mcbm/CbmDeviceDigiEventSink.h
+++ b/MQ/mcbm/CbmDeviceDigiEventSink.h
@@ -56,10 +56,10 @@ public:
   CbmEventTimeslice(FairMQParts& parts, bool bDigiEvtInput = false);
   ~CbmEventTimeslice();
 
-  void ExtractSelectedData();
-  std::vector<CbmDigiEvent>& GetSelectedData()
+  void ExtractSelectedData(bool bExclusiveTrdExtract = true);
+  std::vector<CbmDigiEvent>& GetSelectedData(bool bExclusiveTrdExtract = true)
   {
-    if (!fbDigiEvtInput) ExtractSelectedData();
+    if (!fbDigiEvtInput) ExtractSelectedData(bExclusiveTrdExtract);
     return fvDigiEvents;
   }
 
@@ -104,6 +104,7 @@ private:
   bool fbWriteMissingTs      = false;  //! Switch ON/OFF writing of empty TS to file for the missing ones (if no bypass)
   bool fbDisableCompression  = false;  //! Switch ON/OFF the ROOT file compression
   bool fbDigiEventInput      = false;  //! Switch ON/OFF the input of CbmDigiEvents instead of raw data + CbmEvents
+  bool fbExclusiveTrdExtract = true;   //! Switch ON/OFF loop based extraction of TRD digis due to 1D/2D
   bool fbFillHistos          = false;  //! Switch ON/OFF filling of histograms
   bool fbInitDone            = false;  //! Keep track of whether the Init was already fully completed
   bool fbFinishDone          = false;  //! Keep track of whether the Finish was already called
diff --git a/MQ/mcbm/runDigiEventSink.cxx b/MQ/mcbm/runDigiEventSink.cxx
index ade9d4a6e5..450a156b7d 100644
--- a/MQ/mcbm/runDigiEventSink.cxx
+++ b/MQ/mcbm/runDigiEventSink.cxx
@@ -33,6 +33,8 @@ void addCustomOptions(bpo::options_description& options)
 
   options.add_options()("DigiEventInput", bpo::value<bool>()->default_value(false),
                         "Enable the input of CbmDigiEvents instead of raw data + CbmEvents if true");
+  options.add_options()("ExclusiveTrdExtract", bpo::value<bool>()->default_value(true),
+                        "Enable loop based extraction of TRD digis to handle different 1D/2D sel windows if true");
 
   options.add_options()("FillHistos", bpo::value<bool>()->default_value(false),
                         "Fill histograms and send them to histo server if true");
-- 
GitLab