From c2e26cfb5e9120eb0e7d28eeee9db46b8c757aa2 Mon Sep 17 00:00:00 2001
From: Dominik Smith <smith@th.physik.uni-frankfurt.de>
Date: Fri, 18 Feb 2022 14:05:46 +0100
Subject: [PATCH] Cleaned up CbmDeviceEventBuilder. Made writing to file
 switchable.

---
 MQ/mcbm/CbmDeviceEventBuilder.cxx | 124 +++++++++++++-----------------
 MQ/mcbm/CbmDeviceEventBuilder.h   |  31 ++------
 MQ/mcbm/runEventBuilder.cxx       |   2 +-
 3 files changed, 63 insertions(+), 94 deletions(-)

diff --git a/MQ/mcbm/CbmDeviceEventBuilder.cxx b/MQ/mcbm/CbmDeviceEventBuilder.cxx
index c37787629f..878db861ef 100644
--- a/MQ/mcbm/CbmDeviceEventBuilder.cxx
+++ b/MQ/mcbm/CbmDeviceEventBuilder.cxx
@@ -1,13 +1,6 @@
-/* Copyright (C) 2021 Facility for Antiproton and Ion Research in Europe, Darmstadt
+/* Copyright (C) 2022 Facility for Antiproton and Ion Research in Europe, Darmstadt
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Pierre-Alain Loizeau[committer] */
-
-/**
- * CbmDeviceEventBuilder.cxx
- *
- * @since 2021-11-18
- * @author P.-A. Loizeau
- */
+   Authors: Pierre-Alain Loizeau[committer], Dominik Smith */
 
 #include "CbmDeviceEventBuilder.h"
 
@@ -87,33 +80,25 @@ try {
 
   /// Prepare root output
   if ("" != fsOutputFileName) {
-    fpRun         = new FairRunOnline();  // is this needed?
+    fpRun         = new FairRunOnline();
     fpFairRootMgr = FairRootManager::Instance();
     fpFairRootMgr->SetSink(new FairRootFileSink(fsOutputFileName));
-    if (nullptr == fpFairRootMgr->GetOutFile()) {
-      throw InitTaskError("Could not open root file");
-    }  // if( nullptr == fpFairRootMgr->GetOutFile() )
-  }    // if( "" != fsOutputFileName )
-  else {
-    throw InitTaskError("Empty output filename!");
-  }  // else of if( "" != fsOutputFileName )
-
-  LOG(info) << "Init Root Output to " << fsOutputFileName;
-  fpFairRootMgr->InitSink();
+    if (nullptr == fpFairRootMgr->GetOutFile()) { throw InitTaskError("Could not open root file"); }
+    LOG(info) << "Init Root Output to " << fsOutputFileName;
+    fpFairRootMgr->InitSink();
 
-  /// Create input vectors
-  fCbmTsEventHeader = new CbmTsEventHeader();
-  fpFairRootMgr->Register("EventHeader.", "Event", fCbmTsEventHeader, kTRUE);
+    /// Create storage objects
+    fCbmTsEventHeaderOut = new CbmTsEventHeader();
+    fpFairRootMgr->Register("EventHeader.", "Event", fCbmTsEventHeaderOut, kTRUE);
 
-  /// Create storage vector for events
-  fEventsSel = new std::vector<CbmDigiEvent>();
-  fpFairRootMgr->RegisterAny("DigiEvent", fEventsSel, kTRUE);
+    fEventsSelOut = new std::vector<CbmDigiEvent>();
+    fpFairRootMgr->RegisterAny("DigiEvent", fEventsSelOut, kTRUE);
 
-  fTimeSliceMetaDataArray = new TClonesArray("TimesliceMetaData", 1);
-  if (nullptr == fTimeSliceMetaDataArray) { throw InitTaskError("Failed creating the TS meta data TClonesarray "); }
-  fpFairRootMgr->Register("TimesliceMetaData", "TS Meta Data", fTimeSliceMetaDataArray, kTRUE);
+    fTimeSliceMetaDataArrayOut = new TClonesArray("TimesliceMetaData", 1);
+    fpFairRootMgr->Register("TimesliceMetaData", "TS Meta Data", fTimeSliceMetaDataArrayOut, kTRUE);
 
-  fpFairRootMgr->WriteFolder();
+    fpFairRootMgr->WriteFolder();
+  }  // if( "" != fsOutputFileName )
 
   // Get the information about created channels from the device
   // Check if the defined channels from the topology (by name)
@@ -305,14 +290,13 @@ bool CbmDeviceEventBuilder::HandleData(FairMQParts& parts, int /*index*/)
   ++uPartIdx;
 
   /// TS metadata
-  Deserialize<RootSerializer>(*parts.At(uPartIdx), fTsMetaData);
-  new ((*fTimeSliceMetaDataArray)[fTimeSliceMetaDataArray->GetEntriesFast()])
-    TimesliceMetaData(std::move(*fTsMetaData));
+  TimesliceMetaData* tsMetaData = new TimesliceMetaData();
+  Deserialize<RootSerializer>(*parts.At(uPartIdx), tsMetaData);
   ++uPartIdx;
 
   //if (1 == fulNumMessages) {
   /// First message received (do TS metadata stuff here)
-  //fpAlgo->SetTsParameters(0, fTsMetaData->GetDuration(), fTsMetaData->GetOverlapDuration());
+  //fpAlgo->SetTsParameters(0, fTsMetaDataOut->GetDuration(), fTsMetaDataOut->GetOverlapDuration());
   //}
 
   LOG(debug) << "T0 Vector size: " << ts.fData.fT0.fDigis.size();
@@ -330,27 +314,27 @@ bool CbmDeviceEventBuilder::HandleData(FairMQParts& parts, int /*index*/)
   std::vector<CbmDigiEvent> vEvents = fEvbuildAlgo(ts, triggers);
   LOG(debug) << "vEvents size: " << vEvents.size();
 
-  /// Send events vector to ouput
-  if (!SendEvents(vEvents)) {
-    fTimeSliceMetaDataArray->Clear();
-    return false;
-  }
+  /// Send output message
+  if (!SendEvents(vEvents, tsMetaData, evtHeader)) { return false; }
 
   /// Write events to file
-  (*fEventsSel) = std::move(vEvents);
-  LOG(debug) << "fEventSel size: " << fEventsSel->size();
-
   // FIXME: poor man solution with lots of data copy until we undertand how to properly deal
   /// with FairMq messages ownership and memory managment
-  (*fCbmTsEventHeader) = std::move(*evtHeader);
 
-  DumpTreeEntry();
+  if ("" != fsOutputFileName) {
+    (*fEventsSelOut) = std::move(vEvents);
+    LOG(debug) << "fEventSel size: " << fEventsSelOut->size();
+
+    (*fCbmTsEventHeaderOut) = std::move(*evtHeader);
 
-  /// Clear metadata
-  fTimeSliceMetaDataArray->Clear();
+    new ((*fTimeSliceMetaDataArrayOut)[fTimeSliceMetaDataArrayOut->GetEntriesFast()])
+      TimesliceMetaData(std::move(*tsMetaData));
 
-  /// Clear event vector
-  fEventsSel->clear();
+    DumpTreeEntry();
+
+    fTimeSliceMetaDataArrayOut->Clear();
+    fEventsSelOut->clear();
+  }
 
   return true;
 }
@@ -361,7 +345,7 @@ void CbmDeviceEventBuilder::DumpTreeEntry()
 
   /// FairRunOnline style
   fpFairRootMgr->StoreWriteoutBufferData(fpFairRootMgr->GetEventTime());
-  fpFairRootMgr->FillEventHeader(fCbmTsEventHeader);
+  fpFairRootMgr->FillEventHeader(fCbmTsEventHeaderOut);
   fpFairRootMgr->Fill();
   fpFairRootMgr->DeleteOldWriteoutBufferData();
 }
@@ -404,20 +388,29 @@ std::vector<double> CbmDeviceEventBuilder::GetTriggerTimes(const CbmDigiTimeslic
   return fTriggerAlgo(vDigiTimes, fTriggerWindow, fMinNumDigis, fDeadTime);
 }
 
-bool CbmDeviceEventBuilder::SendEvents(const std::vector<CbmDigiEvent>& vEvents)
+bool CbmDeviceEventBuilder::SendEvents(const std::vector<CbmDigiEvent>& vEvents, const TimesliceMetaData* tsMetaData,
+                                       const CbmTsEventHeader* eventHeader)
 {
   LOG(debug) << "Vector size: " << vEvents.size();
 
+  FairMQParts partsOut;
+
+  /// Prepare serialized versions of the TS Event header
+  FairMQMessagePtr messTsHeader(NewMessage());
+  Serialize<RootSerializer>(*messTsHeader, eventHeader);
+  partsOut.AddPart(std::move(messTsHeader));
+
+  // Prepare TS meta data
   FairMQMessagePtr messTsMeta(NewMessage());
-  Serialize<RootSerializer>(*messTsMeta, fTsMetaData);
+  Serialize<RootSerializer>(*messTsMeta, tsMetaData);
+  partsOut.AddPart(std::move(messTsMeta));
 
+  // Prepare event vector.
   std::stringstream ossEvt;
   boost::archive::binary_oarchive oaEvt(ossEvt);
   oaEvt << vEvents;
   std::string* strMsgEvt = new std::string(ossEvt.str());
 
-  FairMQParts partsOut(std::move(messTsMeta));
-
   partsOut.AddPart(NewMessage(
     const_cast<char*>(strMsgEvt->c_str()),  // data
     strMsgEvt->length(),                    // size
@@ -433,9 +426,11 @@ bool CbmDeviceEventBuilder::SendEvents(const std::vector<CbmDigiEvent>& vEvents)
 
 void CbmDeviceEventBuilder::Finish()
 {
-  // Clean closure of output to root file
-  fpFairRootMgr->Write();
-  fpFairRootMgr->CloseSink();
+  if ("" != fsOutputFileName) {
+    // Clean closure of output to root file
+    fpFairRootMgr->Write();
+    fpFairRootMgr->CloseSink();
+  }
   fbFinishDone = kTRUE;
 }
 
@@ -443,19 +438,8 @@ CbmDeviceEventBuilder::~CbmDeviceEventBuilder()
 {
   /// Close things properly if not alredy done
   if (!fbFinishDone) Finish();
-
-  /// Clear events vector
-  if (fEventsSel) {
-    fEventsSel->clear();
-    delete fEventsSel;
-  }
+  if (fEventsSelOut) { delete fEventsSelOut; }
   if (fpRun) { delete fpRun; }
-
-  /// Clear metadata
-  delete fCbmTsEventHeader;
-
-  /// Clear metadata
-  fTimeSliceMetaDataArray->Clear();
-  delete fTimeSliceMetaDataArray;
-  delete fTsMetaData;
+  if (fCbmTsEventHeaderOut) { delete fCbmTsEventHeaderOut; }
+  if (fTimeSliceMetaDataArrayOut) { delete fTimeSliceMetaDataArrayOut; }
 }
diff --git a/MQ/mcbm/CbmDeviceEventBuilder.h b/MQ/mcbm/CbmDeviceEventBuilder.h
index 450fe1dc57..2f4ee1be5e 100644
--- a/MQ/mcbm/CbmDeviceEventBuilder.h
+++ b/MQ/mcbm/CbmDeviceEventBuilder.h
@@ -59,7 +59,6 @@ private:
   /// Algo enum settings
   ECbmModuleId fTriggerDet = ECbmModuleId::kT0;
 
-  std::string fsOutputFileName = "";
   /// message queues
   std::string fsChannelNameDataInput   = "unpts_0";
   std::string fsChannelNameDataOutput  = "events";
@@ -87,31 +86,17 @@ private:
   int32_t fMinNumDigis  = 0;
   double fDeadTime      = 0.;
 
-  /// TS MetaData stable values storage
-  size_t fuNbCoreMsPerTs    = 0;        //!
-  size_t fuNbOverMsPerTs    = 0;        //!
-  Double_t fdMsSizeInNs     = 1280000;  //! Size of a single MS, [nanoseconds]
-  Double_t fdTsCoreSizeInNs = -1.0;     //! Total size of the core MS in a TS, [nanoseconds]
-  Double_t fdTsOverSizeInNs = -1.0;     //! Total size of the overlap MS in a TS, [nanoseconds]
-  Double_t fdTsFullSizeInNs = -1.0;     //! Total size of all MS in a TS, [nanoseconds]
-
-  /// Data reception
-  /// TS information in header
-  CbmTsEventHeader* fCbmTsEventHeader = nullptr;
-
-  /// TS MetaData storage
-  TClonesArray* fTimeSliceMetaDataArray = nullptr;
-  TimesliceMetaData* fTsMetaData        = nullptr;
-
   /// Data storage
-  FairRunOnline* fpRun           = nullptr;
-  FairRootManager* fpFairRootMgr = nullptr;
-
-  /// CbmEvents
-  std::vector<CbmDigiEvent>* fEventsSel = nullptr;  //! output container of CbmEvents
+  std::string fsOutputFileName             = "";
+  FairRunOnline* fpRun                     = nullptr;
+  FairRootManager* fpFairRootMgr           = nullptr;
+  CbmTsEventHeader* fCbmTsEventHeaderOut   = nullptr;  // output container for TS information in header
+  std::vector<CbmDigiEvent>* fEventsSelOut = nullptr;  // output container of CbmDigiEvents
+  TClonesArray* fTimeSliceMetaDataArrayOut = nullptr;  // output container of meta data
 
   bool IsChannelNameAllowed(std::string channelName);
-  bool SendEvents(const std::vector<CbmDigiEvent>& vEvents);
+  bool SendEvents(const std::vector<CbmDigiEvent>& vEvents, const TimesliceMetaData* tsMetaData,
+                  const CbmTsEventHeader* eventHeader);
 
   // --- Extract digi times into to a vector
   template<class TDigi>
diff --git a/MQ/mcbm/runEventBuilder.cxx b/MQ/mcbm/runEventBuilder.cxx
index 0323efc9d8..28c46e970f 100644
--- a/MQ/mcbm/runEventBuilder.cxx
+++ b/MQ/mcbm/runEventBuilder.cxx
@@ -21,7 +21,7 @@ void addCustomOptions(bpo::options_description& options)
   options.add_options()("FillHistos", bpo::value<bool>()->default_value(true),
                         "Fill histograms and send them to histo server if true");
   options.add_options()("IgnTsOver", bpo::value<bool>()->default_value(false), "Ignore TS overlap if true");
-  options.add_options()("OutFileName", bpo::value<std::string>()->default_value("events.root"),
+  options.add_options()("OutFileName", bpo::value<std::string>()->default_value(""),
                         "Name (full or relative path) of the output .root file ");
   options.add_options()("TriggerDet", bpo::value<std::string>()->default_value("kT0"),
                         "Set the trigger detector, use string matching an ECbmModuleId ");
-- 
GitLab