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