From 43a465972893ff9a75790b67b80f518584d3172d Mon Sep 17 00:00:00 2001 From: P-A Loizeau <p.-a.loizeau@gsi.de> Date: Wed, 18 Jan 2023 11:28:22 +0100 Subject: [PATCH] Add task to clone CbmEvent array if in input + rel. mCBM reco macro fix --- macro/beamtime/mcbm2022/mcbm_reco.C | 10 +- reco/tasks/CMakeLists.txt | 1 + reco/tasks/CbmRecoTasksLinkDef.h | 1 + reco/tasks/CbmTaskEventsCloneInToOut.cxx | 142 +++++++++++++++++++++++ reco/tasks/CbmTaskEventsCloneInToOut.h | 72 ++++++++++++ 5 files changed, 223 insertions(+), 3 deletions(-) create mode 100644 reco/tasks/CbmTaskEventsCloneInToOut.cxx create mode 100644 reco/tasks/CbmTaskEventsCloneInToOut.h diff --git a/macro/beamtime/mcbm2022/mcbm_reco.C b/macro/beamtime/mcbm2022/mcbm_reco.C index 4f128847f6..2e68005e6f 100644 --- a/macro/beamtime/mcbm2022/mcbm_reco.C +++ b/macro/beamtime/mcbm2022/mcbm_reco.C @@ -61,8 +61,8 @@ Bool_t mcbm_reco(UInt_t uRunId = 2391, TString cFileId = sRunId; //TString parFileIn = sInpDir + "/unp_mcbm_params_" + sRunId; - TString parFileOut = sOutDir + "/reco_event_mcbm_test_params_" + sRunId; - TString outFile = sOutDir + "/reco_event_mcbm_test" + sRunId; + TString parFileOut = sOutDir + "/reco_" + (bDigiEvtsInput ? "digievent" : "event") + "_mcbm_test_params_" + sRunId; + TString outFile = sOutDir + "/reco_" + (bDigiEvtsInput ? "digievent" : "event") + "_mcbm_test" + sRunId; // Your folder with the Tof Calibration files; TString TofFileFolder = ""; @@ -260,7 +260,7 @@ Bool_t mcbm_reco(UInt_t uRunId = 2391, // ----- DigiEvent compatibility task --------------------------------- if (bDigiEvtsInput) { - // ---- This is required if the input is in DigiEvent format + // ---- This is required if the input is in DigiEvent format to create CbmEvents + vectors of Digis in memory auto makeEvents = std::make_unique<CbmTaskMakeRecoEvents>(); run->AddTask(makeEvents.release()); std::cout << "-I- : Added task MakeRecoEvents" << std::endl; @@ -271,6 +271,10 @@ Bool_t mcbm_reco(UInt_t uRunId = 2391, << "\n Exiting"; return kFALSE; } + // ---- This is required if the input is in CbmEvent format to create a copy in memory for update (e.g. with hits) + auto cloneEventsInToOut = std::make_unique<CbmTaskEventsCloneInToOut>(); + run->AddTask(cloneEventsInToOut.release()); + std::cout << "-I- : Added task EventsCloneInToOut" << std::endl; } // ------------------------------------------------------------------------ diff --git a/reco/tasks/CMakeLists.txt b/reco/tasks/CMakeLists.txt index 80d8698852..49ea82ea73 100644 --- a/reco/tasks/CMakeLists.txt +++ b/reco/tasks/CMakeLists.txt @@ -11,6 +11,7 @@ set(SRCS CbmSourceTs.cxx CbmTaskBuildEvents.cxx CbmTaskDigiEventQa.cxx + CbmTaskEventsCloneInToOut.cxx CbmTaskMakeRecoEvents.cxx CbmTaskTriggerDigi.cxx CbmTaskUnpack.cxx diff --git a/reco/tasks/CbmRecoTasksLinkDef.h b/reco/tasks/CbmRecoTasksLinkDef.h index ac0ef94908..32def2aa29 100644 --- a/reco/tasks/CbmRecoTasksLinkDef.h +++ b/reco/tasks/CbmRecoTasksLinkDef.h @@ -16,6 +16,7 @@ #pragma link C++ class CbmSourceTs + ; #pragma link C++ class CbmTaskBuildEvents + ; #pragma link C++ class CbmTaskDigiEventQa + ; +#pragma link C++ class CbmTaskEventsCloneInToOut + ; #pragma link C++ class CbmTaskMakeRecoEvents + ; #pragma link C++ class CbmTaskTriggerDigi + ; #pragma link C++ class CbmTaskUnpack + ; diff --git a/reco/tasks/CbmTaskEventsCloneInToOut.cxx b/reco/tasks/CbmTaskEventsCloneInToOut.cxx new file mode 100644 index 0000000000..77df1c7824 --- /dev/null +++ b/reco/tasks/CbmTaskEventsCloneInToOut.cxx @@ -0,0 +1,142 @@ +/* Copyright (C) 2022 Facility for Antiproton and Ion Research in Europe, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Pierre-Alain Loizeau [committer] */ + + +#include "CbmTaskEventsCloneInToOut.h" + +#include "CbmDefs.h" +#include "CbmEvent.h" + +#include <FairFileSource.h> +#include <FairRootManager.h> +#include <Logger.h> + +#include <TClonesArray.h> +#include <TStopwatch.h> + +#include <algorithm> +#include <cassert> +#include <iomanip> + + +using namespace std; + + +// ----- Constructor ----------------------------------------------------- +CbmTaskEventsCloneInToOut::CbmTaskEventsCloneInToOut() : FairTask("EventsCloneInToOut") {} +// --------------------------------------------------------------------------- + + +// ----- Destructor ------------------------------------------------------ +CbmTaskEventsCloneInToOut::~CbmTaskEventsCloneInToOut() {} +// --------------------------------------------------------------------------- + + +// ----- Execution ------------------------------------------------------- +void CbmTaskEventsCloneInToOut::Exec(Option_t*) +{ + // --- Timer and counters + TStopwatch timer; + timer.Start(); + + // --- No action if no CbmEvents branch is present + if (!fRecoEventsIn) return; + + fRecoEventsOut->Delete(); // Bad way to do it according to ROOT docs, but memory leak otherwise + + // --- Copy all entries in input TClonesArray to output one + // => Event loop + for (Int_t eventNr = 0; eventNr < fRecoEventsIn->GetEntriesFast(); ++eventNr) { + const CbmEvent* pEventIn = dynamic_cast<const CbmEvent*>((*fRecoEventsIn)[eventNr]); + if (pEventIn) { + /// Explicit creation-copy as no ranged Copy method for TClonesArray + new ((*fRecoEventsOut)[eventNr]) CbmEvent(*pEventIn); + } + else { + LOG(fatal) << GetName() << ": Failed to get input event " << eventNr << " in TS " << fNumTs; + } + } + + if (fRecoEventsIn->GetEntriesFast() != fRecoEventsOut->GetEntriesFast()) { + LOG(fatal) << GetName() << ": Input size not matching output one: " << fRecoEventsIn->GetEntriesFast() << " VS " + << fRecoEventsOut->GetEntriesFast() << " in TS " << fNumTs; + } + + // --- Timeslice log + timer.Stop(); + stringstream logOut; + logOut << setw(20) << left << GetName() << " ["; + logOut << fixed << setw(8) << setprecision(1) << right << timer.RealTime() * 1000. << " ms] "; + logOut << "TS " << fNumTs << ", events In " << fRecoEventsIn->GetEntriesFast() << ", events Out " + << fRecoEventsOut->GetEntriesFast(); + LOG(info) << logOut.str(); + + // --- Run statistics + fNumTs++; + fTimeTot += timer.RealTime(); + fNumEvents += fRecoEventsOut->GetEntriesFast(); +} +// ---------------------------------------------------------------------------- + + +// ----- End-of-timeslice action ------------------------------------------ +void CbmTaskEventsCloneInToOut::Finish() +{ + LOG(info) << "====================================="; + LOG(info) << GetName() << ": Run summary"; + LOG(info) << "Timeslices : " << fNumTs; + LOG(info) << "Events : " << fNumEvents; + LOG(info) << "Time / TS : " << fixed << setprecision(2) << 1000. * fTimeTot / double(fNumTs) << " ms"; + LOG(info) << "====================================="; + fRecoEventsOut->Delete(); +} +// ---------------------------------------------------------------------------- + + +// ----- Initialisation --------------------------------------------------- +InitStatus CbmTaskEventsCloneInToOut::Init() +{ + + LOG(info) << "=================================================="; + LOG(info) << GetName() << ": Initialising "; + + // --- Get FairRootManager instance + FairRootManager* frm = FairRootManager::Instance(); + if (nullptr == frm) { + LOG(error) << GetName() << ": Failed to get FairRootManager! Aborting..."; + return kFATAL; + } + + // --- Try to get input vector (CbmDigiEvent) + fpFileIn = dynamic_cast<FairFileSource*>(frm->GetSource()); + if (nullptr == fpFileIn) { + LOG(error) << GetName() << ": Failed to get Fair file interface object! Aborting..."; + return kFATAL; + } + + TTree* pTree = fpFileIn->GetInTree(); + if (pTree->GetBranch("CbmEvent")) { + fRecoEventsIn = new TClonesArray("CbmEvent", 100); + pTree->SetBranchAddress("CbmEvent", &fRecoEventsIn); + pTree->SetBranchStatus("CbmEvent", 1); + + LOG(info) << GetName() << ": Found branch CbmEvent in input"; + + // --- Event + fRecoEventsOut = new TClonesArray("CbmEvent", 1); + frm->Register("CbmEvent", "Reco events", fRecoEventsOut, kTRUE); + LOG(info) << GetName() << ": created branch CbmEvent in output"; + } + else { + LOG(error) << GetName() << ": No CbmEvent branch found in file! Aborting..."; + return kFATAL; + } + + LOG(info) << "=================================================="; + + return kSUCCESS; +} +// ---------------------------------------------------------------------------- + +ClassImp(CbmTaskEventsCloneInToOut) diff --git a/reco/tasks/CbmTaskEventsCloneInToOut.h b/reco/tasks/CbmTaskEventsCloneInToOut.h new file mode 100644 index 0000000000..fbb87a7105 --- /dev/null +++ b/reco/tasks/CbmTaskEventsCloneInToOut.h @@ -0,0 +1,72 @@ +/* Copyright (C) 2023 Facility for Antiproton and Ion Research in Europe, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Pierre-Alain Loizeau [committer] */ + + +#ifndef CbmTaskEventsCloneInToOut_H +#define CbmTaskEventsCloneInToOut_H 1 + +#include <FairTask.h> + +class TClonesArray; +class FairFileSource; + +/** @class CbmTaskEventsCloneInToOut + ** @brief Task class for clone CbmEvent objects from the Input to the output to allow their update, e.g. due to new + ** reconstruction steps. + ** + ** @author Pierre-Alain Loizeau <v.friese@gsi.de> + ** @since 17.01.2023 + ** + ** This tasks copies the existing CbmEvent from the input file to the memory with the persitency flag set, so that they + ** appear in the output file and can be updated (standard inputs are const). + ** + ** The task has to be run prior to any reconstruction task adding more information to the CbmEvent (e.g. hit or track + ** reconstruction), but only in case the event building was done in a previous run (thus saving the events to the file + ** used as input for this run) + ** + **/ +class CbmTaskEventsCloneInToOut : public FairTask { + + +public: + /** @brief Constructor **/ + CbmTaskEventsCloneInToOut(); + + + /** @brief Copy constructor (disabled) **/ + CbmTaskEventsCloneInToOut(const CbmTaskEventsCloneInToOut&) = delete; + + + /** @brief Destructor **/ + virtual ~CbmTaskEventsCloneInToOut(); + + + /** @brief Task execution **/ + virtual void Exec(Option_t* opt); + + + /** @brief Finish timeslice **/ + virtual void Finish(); + + + /** @brief Assignment operator (disabled) **/ + CbmTaskEventsCloneInToOut& operator=(const CbmTaskEventsCloneInToOut&) = delete; + + +private: // methods + /** @brief Task initialisation **/ + virtual InitStatus Init(); + +private: // members + FairFileSource* fpFileIn = nullptr; + const TClonesArray* fRecoEventsIn = nullptr; + TClonesArray* fRecoEventsOut = nullptr; + double fTimeTot = 0.; ///< Execution time + size_t fNumTs = 0; ///< Number of processed timeslices + size_t fNumEvents = 0; ///< Number of events + + ClassDef(CbmTaskEventsCloneInToOut, 1); +}; + +#endif /* CbmTaskEventsCloneInToOut_H */ -- GitLab