diff --git a/core/base/CbmDigiManager.h b/core/base/CbmDigiManager.h index e6e90578ca248aa8a1750872720acc09d5a5e407..29e8062610a33a123a86df21f69f326536d6ab1b 100644 --- a/core/base/CbmDigiManager.h +++ b/core/base/CbmDigiManager.h @@ -69,6 +69,16 @@ public: return nullptr; } + /** @brief Access to a digi branch + ** @param system System identifier + ** @return Digi branch + **/ + CbmDigiBranchBase* GetBranch(ECbmModuleId system) + { + auto it = fBranches.find(system); + return (it != fBranches.end() ? it->second : nullptr); + } + /** @brief Get a match object ** @param System identifier (ECbmModuleId) diff --git a/core/data/CMakeLists.txt b/core/data/CMakeLists.txt index 1180f46484d2618db05506edad90bd3fe23a694c..08fdae3eb5e4e54dbbdb57a4f9243fd80c5565bc 100644 --- a/core/data/CMakeLists.txt +++ b/core/data/CMakeLists.txt @@ -141,6 +141,11 @@ set(LINKDEF DataLinkDef.h) set(LIBRARY_NAME CbmData) set(DEPENDENCIES Base) +# Generate list of headers from the list of source files and add some extra header files +CHANGE_FILE_EXTENSION(*.cxx *.h HEADERS "${SRCS}") +list(APPEND HEADERS global/CbmDigiEvent.h) + + GENERATE_LIBRARY() # Install file which has no corresponding source file diff --git a/core/data/DataLinkDef.h b/core/data/DataLinkDef.h index 75ecb0560e8e03cac23ae9c9bcfffacda7a7011c..d9c23c0b51e3576b9ea9384992302f2c23d6d355 100644 --- a/core/data/DataLinkDef.h +++ b/core/data/DataLinkDef.h @@ -89,9 +89,11 @@ #pragma link C++ class CbmPsdAddress; #pragma link C++ class CbmPsdMCbmHit; +// --- data/global #pragma link C++ class CbmGlobalTrack + ; #pragma link C++ class CbmTofTrack + ; #pragma link C++ class CbmVertex + ; +#pragma link C++ class std::vector < CbmDigiEvent>; #pragma link C++ class stsxyter::Message; #pragma link C++ class gdpbv100::Message; @@ -131,6 +133,7 @@ #pragma link C++ class CbmDigiVector < CbmPsdDsp> + ; #pragma link C++ class vector < CbmEventStore> + ; +/* clang-format off */ #pragma read sourceClass="CbmStsDigi" version="[7]" targetClass="CbmStsDigi" \ source="Long64_t fTime; Int_t fAddress; UShort_t fChannel; UShort_t fCharge" \ target="" \ @@ -163,6 +166,8 @@ + ((chId & ((1 << 6) - 1)) << 22) \ + ((rpcType & ((1 << 4) - 1)) << 28); \ }" +/* clang-format on */ + #pragma read sourceClass = "CbmTofHit" version = "[1-4]" targetClass = "CbmTofHit" source = "" target = "" include = \ "Logger.h" code = "{ \ diff --git a/core/data/base/CbmDigiBranch.h b/core/data/base/CbmDigiBranch.h index 73c9ca535b485108fc79ee2af735e096ef55538e..3bcb83fde3877bf97d7eaa511daebe3b428806af 100644 --- a/core/data/base/CbmDigiBranch.h +++ b/core/data/base/CbmDigiBranch.h @@ -175,7 +175,7 @@ public: // ----------------------------------------------------------------------- /** @brief Get branch pointer - ** @return Pointer to the connected data container + ** @return Pointer to the connected data container (const) ** A std::vector is first looked for; if not found, a TClonesArray ** is looked for. ** Returns a null pointer if the branch is not present. diff --git a/macro/CMakeLists.txt b/macro/CMakeLists.txt index c6815af251db3a22346f1d7f5f087b97592bfeba..6173cf2321cfae8faf0fa473ed69e7899aba84f9 100644 --- a/macro/CMakeLists.txt +++ b/macro/CMakeLists.txt @@ -4,7 +4,9 @@ add_subdirectory(mcbm) add_subdirectory(mvd) add_subdirectory(much) add_subdirectory(include) - +if (${CMAKE_CXX_STANDARD} EQUAL 17) + add_subdirectory (reco) +endif() #--- Additional tests for nightly builds If(NOT ${CBM_TEST_MODEL} MATCHES Experimental) diff --git a/macro/reco/CMakeLists.txt b/macro/reco/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..852851e3ebb7965a7ebe56cc7fd3c1b43f1a0e0d --- /dev/null +++ b/macro/reco/CMakeLists.txt @@ -0,0 +1,157 @@ +# CMakeList.txt for macro/reco +# Defines regular tests +# V. Friese, November 2021 + +# ===== Generate the needed shell scripts ================================ +GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/run_tra_file.C) +GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/run_tra_beam.C) +GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/run_digi.C) +GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/reco/reco_digi.C) +# ============================================================================ + + +# ===== Copy the .rootrc file into the directory from which root is executed +# --- Otherwise the rootalias file is not loaded +file(COPY ${CBMROOT_SOURCE_DIR}/macro/include/.rootrc + DESTINATION ${CBMROOT_BINARY_DIR}/macro/reco) +# ============================================================================ + + +# ===== Define variables for tests ======================================= +Set(randomSeed 1) +if(${CBM_TEST_MODEL} MATCHES Weekly) + Set(nEvents 100) +else() + Set(nEvents 3) +endIf() + +math(EXPR timeOutTime "${nEvents} * 200") +math(EXPR nBeam "${nEvents} * 3") + +set(datadir ${CBMROOT_BINARY_DIR}/macro/reco/data) +# ============================================================================ + + +# ===== Define the different setups to be tested with ==================== +if(NOT ${CBM_TEST_MODEL} MATCHES Experimental ) + List(APPEND cbm_setup sis100_hadron sis100_electron sis100_muon_lmvm + sis100_muon_jpsi sis300_electron) +else() + List(APPEND cbm_setup sis100_hadron) +endif() +# ============================================================================ + + +# ===== Cleanup the data directory ======================================= +add_test(reco_cleanup ${CMAKE_COMMAND} + -P ${CMAKE_SOURCE_DIR}/cmake/scripts/cleanmacrodir.cmake) +set_tests_properties(reco_cleanup PROPERTIES + TIMEOUT ${timeOutTime} + FIXTURES_SETUP reco_cleanup +) +# ============================================================================ + + +# ===== Define tests for each setup ====================================== +foreach(setup IN LISTS cbm_setup) + + # --- Short name for setup + if(setup MATCHES sis100_hadron) + set(sname s100h) + elseif(setup MATCHES sis100_electron) + set(sname s100e) + elseif(setup MATCHES sis100_muon_lmvm) + set(sname s100m2) + elseif(setup MATCHES sis100_muon_jpsi) + set(sname s100m3) + elseif(setup MATCHES sis300_electron) + set(sname s300e) + else() + set(sname test) + endif() + + # --- Test reco_tra_coll + # --- Transport run with collision events, using run_tra_file.C + set(testname reco_tra_coll_${sname}) + set(input ${CBMROOT_SOURCE_DIR}/input/urqmd.auau.10gev.centr.root) + set(output ${datadir}/${sname}_coll) + add_test(${testname} ${CBMROOT_BINARY_DIR}/macro/run/run_tra_file.sh + \"${input}\" ${nEvents} \"${output}\" \"${setup}\" kGeant3 ${randomSeed}) + set_tests_properties(${testname} PROPERTIES + TIMEOUT ${timeOutTime} + PASS_REGULAR_EXPRESSION "Macro finished successfully" + FIXTURES_REQUIRED reco_cleanup + FIXTURES_SETUP fixt_tra_coll_${setup} + RESOURCE_LOCK collParDb_${setup} + ) + + # --- Test run_tra_sign + # --- Transport run with signal events, using run_tra_file.C + set(testname reco_tra_sign_${sname}) + set(input ${CBMROOT_SOURCE_DIR}/input/pluto.auau.8gev.omega.mpmm.0001.root) + set(output ${datadir}/${sname}_sign) + add_test(${testname} ${CBMROOT_BINARY_DIR}/macro/run/run_tra_file.sh + \"${input}\" ${nEvents} \"${output}\" \"${setup}\" kGeant3 ${randomSeed}) + set_tests_properties(${testname} PROPERTIES + TIMEOUT ${timeOutTime} + PASS_REGULAR_EXPRESSION "Macro finished successfully" + FIXTURES_REQUIRED reco_cleanup + FIXTURES_SETUP fixt_tra_sign_${setup} + RESOURCE_LOCK signParDb_${setup} + ) + + # --- Test run_tra_beam + # --- Transport run with beam events, using run_tra_beam.C + set(testname reco_tra_beam_${sname}) + set(output ${datadir}/${sname}_beam) + add_test(${testname} ${CBMROOT_BINARY_DIR}/macro/run/run_tra_beam.sh + ${nBeam} \"Au\" 10 -1 \"${output}\" \"${setup}\" kGeant3 ${randomSeed}) + set_tests_properties(${testname} PROPERTIES + TIMEOUT ${timeOutTime} + PASS_REGULAR_EXPRESSION "Macro finished successfully" + FIXTURES_REQUIRED reco_cleanup + FIXTURES_SETUP fixt_tra_beam_${setup} + RESOURCE_LOCK beamParDb_${setup} + ) + + # --- Test run_digi_ts + # --- Detector response simulation, time-based, using run_digi.C + set(testname reco_digi_${sname}) + set(eventrate 1.e7) + set(beamrate 1.e9) + set(tslength 1.e6) + add_test(${testname} ${CBMROOT_BINARY_DIR}/macro/run/run_digi.sh + \"${datadir}/${sname}_coll\" -1 \"${datadir}/${sname}\"\ ${eventrate} ${tslength} + \"${datadir}/${sname}_sign\" \"${datadir}/${sname}_beam\" ${beamrate}) + set_tests_properties(${testname} PROPERTIES + TIMEOUT ${timeOutTime} + PASS_REGULAR_EXPRESSION "Macro finished successfully" + FIXTURES_REQUIRED "fixt_tra_coll_${setup};fixt_tra_sign_${setup};fixt_tra_beam_${setup}" + FIXTURES_SETUP fixt_digi_ts_${setup} + RESOURCE_LOCK collParDb_${setup} + ) + + # --- Test reco_digi + # --- Reconstruction from time-based simulation + set(testname reco_reco_digi_${sname}) + add_test(${testname} ${MACRODIR}/reco_digi.sh + \"${datadir}/${sname}\" -1 0 \"${datadir}/${sname}\" \"${setup}\" + \"${datadir}/${sname}_coll\") + set_tests_properties(${testname} PROPERTIES + TIMEOUT ${timeOutTime} + PASS_REGULAR_EXPRESSION "Macro finished successfully" + FIXTURES_REQUIRED fixt_digi_ts_${setup} + FIXTURES_SETUP fixt_reco_digi_${setup} + RESOURCE_LOCK collParDb_${setup} + ) + +endforeach(setup IN LISTS cbm_setup) +# ============================================================================ + +# ============================================================================ + +Install(FILES .rootrc run_tra_file.C run_tra_beam.C + run_digi.C reco_digi.C + DESTINATION share/cbmroot/macro/reco + ) +Install(CODE "FILE(MAKE_DIRECTORY \${CMAKE_INSTALL_PREFIX}/share/cbmroot/macro/reco/data)") diff --git a/macro/reco/reco_digi.C b/macro/reco/reco_digi.C new file mode 100644 index 0000000000000000000000000000000000000000..88b993476beba6d0f0b729dd5cf857bf0e690c62 --- /dev/null +++ b/macro/reco/reco_digi.C @@ -0,0 +1,175 @@ +/* Copyright (C) 2020-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Volker Friese [committer], Dominik Smith */ + + +// --- Includes needed for IDE +#include <RtypesCore.h> +#if !defined(__CLING__) +#include "CbmDefs.h" +#include "CbmSetup.h" +#include "CbmTaskBuildEvents.h" + +#include <FairFileSource.h> +#include <FairLogger.h> +#include <FairMonitor.h> +#include <FairParAsciiFileIo.h> +#include <FairParRootFileIo.h> +#include <FairRunAna.h> +#include <FairRuntimeDb.h> +#include <FairSystemInfo.h> + +#include <TStopwatch.h> +#endif + + +/** @brief Macro for CBM reconstruction from digi level + ** @author Volker Friese <v.friese@gsi.de> + ** @since 15 November 2021 + ** @param input Name of input file (w/o extension .raw.root) + ** @param nTimeSlices Number of time-slices to process + ** @param firstTimeSlice First time-slice (entry) to be processed + ** @param output Name of output file (w/o extension .rec.root) + ** @param setup Name of predefined geometry setup + ** @param paramFile Parameter ROOT file (w/o extension .par.root) + ** + ** Reconstruction from digi level. Currently included stages: + ** - Event building (CbmTaskBuildEvents) (STS only) + ** + ** TODO: To be expanded with the progress of the algo project. + ** + ** The file names must be specified without extensions. The convention is + ** that the raw (input) file is [input].raw.root. The output file + ** will be [input].rec.root if not specified by the user. The parameter file + ** has the extension .par.root. It is assumed to be [input].par.root if + ** not specified by the user. + ** + ** If no argument is specified, the input will be set to "test". This allows + ** to execute the macro chain (run_tra_file.C, run_digi.C and run_reco.C) + ** from the ROOT prompt without user intervention. + ** + **/ +void reco_digi(TString input = "", Int_t nTimeSlices = -1, Int_t firstTimeSlice = 0, TString output = "", + TString setup = "sis100_electron", TString paramFile = "") +{ + + // ======================================================================== + // Adjust this part according to your requirements + + // --- Logger settings ---------------------------------------------------- + TString logLevel = "INFO"; + TString logVerbosity = "LOW"; + // ------------------------------------------------------------------------ + + // ----- Environment -------------------------------------------------- + TString myName = "run_reco_algo"; // this macro's name for screen output + TString srcDir = gSystem->Getenv("VMCWORKDIR"); // top source directory + // ------------------------------------------------------------------------ + + + // ----- In- and output file names ------------------------------------ + if (input.IsNull()) input = "test"; + TString rawFile = input + ".raw.root"; + TString traFile = input + ".tra.root"; + if (output.IsNull()) output = input; + TString outFile = output + ".reco.root"; + TString monFile = output + ".moni_reco.root"; + if (paramFile.IsNull()) paramFile = input; + TString parFile = paramFile + ".par.root"; + std::cout << "Inputfile " << rawFile << std::endl; + std::cout << "Outfile " << outFile << std::endl; + std::cout << "Parfile " << parFile << std::endl; + + // ----- Load the geometry setup ------------------------------------- + std::cout << std::endl; + std::cout << "-I- " << myName << ": Loading setup " << setup << std::endl; + CbmSetup* geo = CbmSetup::Instance(); + geo->LoadSetup(setup); + // ------------------------------------------------------------------------ + + + // ----- Timer -------------------------------------------------------- + TStopwatch timer; + timer.Start(); + // ------------------------------------------------------------------------ + + + // ----- FairRunAna --------------------------------------------------- + FairRunAna* run = new FairRunAna(); + FairFileSource* inputSource = new FairFileSource(rawFile); + run->SetSource(inputSource); + run->SetOutputFile(outFile); + run->SetGenerateRunInfo(kTRUE); + FairMonitor::GetMonitor()->EnableMonitor(kTRUE, monFile); + // ------------------------------------------------------------------------ + + + // ----- Logger settings ---------------------------------------------- + FairLogger::GetLogger()->SetLogScreenLevel(logLevel.Data()); + FairLogger::GetLogger()->SetLogVerbosityLevel(logVerbosity.Data()); + // ------------------------------------------------------------------------ + + + // ----- Event building ----------------------------------------------- + CbmTaskBuildEvents* evtBuild = new CbmTaskBuildEvents(); + evtBuild->SetTimeWindow(-20., 30.); // event build window for STS + run->AddTask(evtBuild); + LOG(info) << myName << ": Addes task " << evtBuild->GetName(); + // ------------------------------------------------------------------------ + + + // ----- Parameter database -------------------------------------------- + std::cout << std::endl << std::endl; + std::cout << "-I- " << myName << ": Set runtime DB" << std::endl; + FairRuntimeDb* rtdb = run->GetRuntimeDb(); + FairParRootFileIo* parIo = new FairParRootFileIo(); + parIo->open(parFile.Data(), "UPDATE"); + rtdb->setFirstInput(parIo); + // ------------------------------------------------------------------------ + + + // ----- Run initialisation ------------------------------------------- + std::cout << std::endl; + std::cout << "-I- " << myName << ": Initialise run" << std::endl; + run->Init(); + rtdb->setOutput(parIo); + rtdb->saveOutput(); + rtdb->print(); + // ------------------------------------------------------------------------ + + + // ----- Start run ---------------------------------------------------- + std::cout << std::endl << std::endl; + std::cout << "-I- " << myName << ": Starting run" << std::endl; + run->Run(firstTimeSlice, nTimeSlices); + // ------------------------------------------------------------------------ + + + // ----- Finish ------------------------------------------------------- + timer.Stop(); + FairMonitor::GetMonitor()->Print(); + Double_t rtime = timer.RealTime(); + Double_t ctime = timer.CpuTime(); + std::cout << std::endl << std::endl; + std::cout << "Macro finished successfully." << std::endl; + std::cout << "Output file is " << outFile << std::endl; + std::cout << "Parameter file is " << parFile << std::endl; + std::cout << "Real time " << rtime << " s, CPU time " << ctime << " s" << std::endl; + FairSystemInfo sysInfo; + Float_t maxMemory = sysInfo.GetMaxMemory(); + std::cout << "<DartMeasurement name=\"MaxMemory\" type=\"numeric/double\">"; + std::cout << maxMemory; + std::cout << "</DartMeasurement>" << std::endl; + Float_t cpuUsage = ctime / rtime; + std::cout << "<DartMeasurement name=\"CpuLoad\" type=\"numeric/double\">"; + std::cout << cpuUsage; + std::cout << "</DartMeasurement>" << std::endl; + // ------------------------------------------------------------------------ + + + // ----- This is to prevent a malloc error when exiting ROOT ---------- + // The source of the error is unknown. Related to TGeoManager. + RemoveGeoManager(); + // ------------------------------------------------------------------------ + +} // End of main macro function diff --git a/macro/run/CMakeLists.txt b/macro/run/CMakeLists.txt index f5ad10da585bcdfedd28d78c75eb5b664c7b4444..4823c6ec629aa57d88385d17783712e2845942b5 100644 --- a/macro/run/CMakeLists.txt +++ b/macro/run/CMakeLists.txt @@ -49,7 +49,7 @@ add_test(run_cleanup ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/cmake/scripts/cleanmacrodir.cmake) set_tests_properties(run_cleanup PROPERTIES TIMEOUT ${timeOutTime} - FIXTURES_SETUP cleanup + FIXTURES_SETUP run_cleanup ) # ============================================================================ @@ -79,7 +79,7 @@ foreach(setup IN LISTS cbm_setup) set_tests_properties(${testname} PROPERTIES TIMEOUT ${timeOutTime} PASS_REGULAR_EXPRESSION "Macro finished successfully" - FIXTURES_REQUIRED cleanup + FIXTURES_REQUIRED run_cleanup FIXTURES_SETUP fixt_tra_json_config RESOURCE_LOCK json_config_ParDb ) @@ -119,7 +119,7 @@ foreach(setup IN LISTS cbm_setup) set_tests_properties(${testname} PROPERTIES TIMEOUT ${timeOutTime} PASS_REGULAR_EXPRESSION "Macro finished successfully" - FIXTURES_REQUIRED cleanup + FIXTURES_REQUIRED run_cleanup FIXTURES_SETUP fixt_tra_sign_${setup} RESOURCE_LOCK signParDb_${setup} ) @@ -132,7 +132,7 @@ foreach(setup IN LISTS cbm_setup) set_tests_properties(${testname} PROPERTIES TIMEOUT ${timeOutTime} PASS_REGULAR_EXPRESSION "Macro finished successfully" - FIXTURES_REQUIRED cleanup + FIXTURES_REQUIRED run_cleanup FIXTURES_SETUP fixt_tra_beam_${setup} RESOURCE_LOCK beamParDb_${setup} ) diff --git a/reco/CMakeLists.txt b/reco/CMakeLists.txt index 68dcb85e80b53185df1137bf70a409656ca720b6..51754b710c8ea438c15f8875a585bc0524b710fe 100644 --- a/reco/CMakeLists.txt +++ b/reco/CMakeLists.txt @@ -12,3 +12,6 @@ add_subdirectory(littrack) add_subdirectory(steer) add_subdirectory(tracking) add_subdirectory(qa) +if (${CMAKE_CXX_STANDARD} EQUAL 17) + add_subdirectory (tasks) +endif() diff --git a/reco/tasks/CMakeLists.txt b/reco/tasks/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..310215ee90e1b7ec92168ca47fb04a26e9bbe266 --- /dev/null +++ b/reco/tasks/CMakeLists.txt @@ -0,0 +1,71 @@ +# CMakeList file for library libCbmRecoTasks +# V. Friese, 2 June 2021 + + + +# ----- Library name ---------------------------------- +Set(LIBRARY_NAME CbmRecoTasks) +# --------------------------------------------------------- + +# ----- Compilation sources ---------------------------- +set(SRCS +CbmTaskBuildEvents.cxx +) +# --------------------------------------------------------- + + + +# ---- Include directories ------------------------------- +set(INCLUDE_DIRECTORIES +${CMAKE_CURRENT_SOURCE_DIR} + +${CBMROOT_SOURCE_DIR}/core/base +${CBMROOT_SOURCE_DIR}/core/data +${CBMROOT_SOURCE_DIR}/core/data/base +${CBMROOT_SOURCE_DIR}/core/data/global +${CBMROOT_SOURCE_DIR}/core/data/sts + +${CBMROOT_SOURCE_DIR}/algo/evbuild + +) + +set(SYSTEM_INCLUDE_DIRECTORIES +${BASE_INCLUDE_DIRECTORIES} +${IPC_INCLUDE_DIRECTORY} +) +# --------------------------------------------------------- + + + +# ---- Link directories ---------------------------------- +set(LINK_DIRECTORIES +${FAIRROOT_LIBRARY_DIR} +${ROOT_LIBRARY_DIR} +${Boost_LIBRARY_DIRS} +) +# --------------------------------------------------------- + + + +# ----- Library dependences --------------------------- +Set(DEPENDENCIES +fles_ipc +Base +CbmBase +CbmData +Algo +) +# --------------------------------------------------------- + + +# ----- LinkDef file ----------------------------------- +set(LINKDEF ${LIBRARY_NAME}LinkDef.h) +# --------------------------------------------------------- + + +# ----- Let cmake do the job --------------------------- +include_directories( ${INCLUDE_DIRECTORIES}) +include_directories(SYSTEM ${SYSTEM_INCLUDE_DIRECTORIES}) +link_directories( ${LINK_DIRECTORIES}) +GENERATE_LIBRARY() +# --------------------------------------------------------- diff --git a/reco/tasks/CbmRecoTasksLinkDef.h b/reco/tasks/CbmRecoTasksLinkDef.h new file mode 100644 index 0000000000000000000000000000000000000000..8decde767c8703b2470edaf8eb8fd567fe2cd3af --- /dev/null +++ b/reco/tasks/CbmRecoTasksLinkDef.h @@ -0,0 +1,16 @@ +/* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Volker Friese [committer] */ + +// ===== LinkDef for reco/task ===== + +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +// --- Classes +#pragma link C++ class CbmTaskBuildEvents + ; + +#endif /* __CINT__ */ diff --git a/reco/tasks/CbmTaskBuildEvents.cxx b/reco/tasks/CbmTaskBuildEvents.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f5d3aa7a7f3c4f03d938620044888d86f3c58139 --- /dev/null +++ b/reco/tasks/CbmTaskBuildEvents.cxx @@ -0,0 +1,170 @@ +/* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Volker Friese [committer] */ + + +#include "CbmTaskBuildEvents.h" + +#include "CbmDefs.h" +#include "CbmDigiBranchBase.h" +#include "CbmDigiEvent.h" +#include "CbmDigiManager.h" +#include "CbmDigiTimeslice.h" + +#include <FairLogger.h> + +#include <TStopwatch.h> + +#include <cassert> +#include <iomanip> +#include <iostream> +#include <vector> + +#include "EventBuilder.h" + + +using namespace std; + + +// ----- Constructor ----------------------------------------------------- +CbmTaskBuildEvents::CbmTaskBuildEvents() : FairTask("BuildEvents") {} +// --------------------------------------------------------------------------- + + +// ----- Destructor ------------------------------------------------------ +CbmTaskBuildEvents::~CbmTaskBuildEvents() +{ + if (fEvents) delete fEvents; +} +// --------------------------------------------------------------------------- + + +// ----- Execution ------------------------------------------------------- +void CbmTaskBuildEvents::Exec(Option_t*) +{ + + // --- Timer and counters + TStopwatch timerStep; + TStopwatch timerTot; + timerTot.Start(); + + // --- Clear output vector + fEvents->clear(); + + // --- Construct a DigiTimeslice from the data in CbmDigiManager + timerStep.Start(); + CbmDigiTimeslice ts; + CbmDigiBranchBase* stsBranch = fDigiMan->GetBranch(ECbmModuleId::kSts); + const vector<CbmStsDigi>* digiVec = boost::any_cast<const vector<CbmStsDigi>*>(stsBranch->GetBranchContainer()); + assert(digiVec); + ts.fData.fSts.fDigis = *digiVec; + timerStep.Stop(); + fTimeFillTs += timerStep.RealTime(); + + // --- Construct an artificial trigger list (just preliminary) + vector<double> triggerVec {1000., 2000., 3000.}; + + // --- Call event builder algorithm + timerStep.Start(); + *fEvents = fAlgo(ts, triggerVec); + timerStep.Stop(); + fTimeBuildEvt += timerStep.RealTime(); + + // --- Timeslice statistics + size_t numTriggers = triggerVec.size(); + size_t numEvents = fEvents->size(); + size_t numDigisStsTs = ts.fData.fSts.fDigis.size(); + size_t numDigisStsEv = 0; + for (auto& event : (*fEvents)) + numDigisStsEv += event.fData.fSts.fDigis.size(); + + // --- Timeslice log + timerTot.Stop(); + fTimeTot += timerTot.RealTime(); + stringstream logOut; + logOut << setw(20) << left << GetName() << " ["; + logOut << fixed << setw(8) << setprecision(1) << right << timerTot.RealTime() * 1000. << " ms] "; + logOut << "TS " << fNumTs << ", triggers " << numTriggers << ", events " << numEvents; + logOut << ", frac digis " << 100. * double(numDigisStsEv) / double(numDigisStsTs) << " %"; + LOG(info) << logOut.str(); + + // --- Run statistics + fNumTs++; + fNumTriggers += numTriggers; + fNumEvents += numEvents; + fNumDigisStsTs += numDigisStsTs; + fNumDigisStsEv += numDigisStsEv; +} +// ---------------------------------------------------------------------------- + + +// ----- End-of-timeslice action ------------------------------------------ +void CbmTaskBuildEvents::Finish() +{ + + std::cout << std::endl; + LOG(info) << "====================================="; + LOG(info) << GetName() << ": Run summary"; + LOG(info) << "Timeslices : " << fNumTs; + LOG(info) << "Triggers : " << fNumTriggers; + LOG(info) << "Events : " << fNumEvents; + LOG(info) << "Digis in timeslice : " << fNumDigisStsTs; + LOG(info) << "Digis in events : " << fNumDigisStsEv << " = " << fixed << setprecision(2) + << 100. * double(fNumDigisStsEv) / double(fNumDigisStsTs) << " %"; + LOG(info) << "Time / TS : " << fixed << setprecision(2) << 1000. * fTimeTot / double(fNumTs) << " ms"; + LOG(info) << "Time fill TS : " << fixed << setprecision(2) << 1000. * fTimeFillTs / double(fNumTs) + << " ms = " << 100. * fTimeFillTs / fTimeTot << " %"; + LOG(info) << "Time build events : " << fixed << setprecision(2) << 1000. * fTimeBuildEvt / double(fNumTs) + << " ms = " << 100. * fTimeBuildEvt / fTimeTot << " %"; + LOG(info) << "====================================="; +} +// ---------------------------------------------------------------------------- + + +// ----- Initialisation --------------------------------------------------- +InitStatus CbmTaskBuildEvents::Init() +{ + + // --- Get FairRootManager instance + FairRootManager* ioman = FairRootManager::Instance(); + assert(ioman); + + // --- DigiManager instance + fDigiMan = CbmDigiManager::Instance(); + fDigiMan->Init(); + + std::cout << std::endl; + LOG(info) << "=================================================="; + LOG(info) << GetName() << ": Initialising..."; + + + // --- Check input data (STS only for the time being) + if (!fDigiMan->IsPresent(ECbmModuleId::kSts)) { + LOG(fatal) << GetName() << ": No digi branch for STS"; + return kFATAL; + } + + // --- Register output array (CbmDigiEvent) + if (ioman->GetObject("DigiEvent")) { + LOG(fatal) << GetName() << ": Branch DigiEvent already exists!"; + return kFATAL; + } + fEvents = new vector<CbmDigiEvent>; + ioman->RegisterAny("DigiEvent", fEvents, IsOutputBranchPersistent("DigiEvent")); + if (!fEvents) { + LOG(fatal) << GetName() << ": Output branch could not be created!"; + return kFATAL; + } + + // --- Configure algorithm + fAlgo.SetTriggerWindow(ECbmModuleId::kSts, fEvtTimeStsMin, fEvtTimeStsMax); + + + LOG(info) << "=================================================="; + std::cout << std::endl; + + return kSUCCESS; +} +// ---------------------------------------------------------------------------- + +ClassImp(CbmTaskBuildEvents) diff --git a/reco/tasks/CbmTaskBuildEvents.h b/reco/tasks/CbmTaskBuildEvents.h new file mode 100644 index 0000000000000000000000000000000000000000..8e7e588de436979dd83cf6eb34f2818840fbdb62 --- /dev/null +++ b/reco/tasks/CbmTaskBuildEvents.h @@ -0,0 +1,97 @@ +/* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Volker Friese [committer] */ + + +#ifndef CBMTASKBUILDEVENTS_H +#define CBMTASKBUILDEVENTS_H 1 + + +#include "CbmDefs.h" +#include "CbmDigiEvent.h" + +#include <FairTask.h> + +#include <vector> + +#include "EventBuilder.h" + +class CbmDigiManager; + + +/** @class CbmTaskBuildEvents + ** @brief Task class for associating digis to events + ** @author Volker Friese <v.friese@gsi.de> + ** @since 15.11.2021 + ** + ** Creates objects of class CbmDigiEvent and fills them with digi objects, + ** using the algorithm EventBuilder. + ** + ** TOFO: The current implementation is for STS only and with a dummy trigger list + ** just to establish the framework integration of algorithm and data interfaces. + **/ +class CbmTaskBuildEvents : public FairTask { + + +public: + /** @brief Constructor **/ + CbmTaskBuildEvents(); + + + /** @brief Copy constructor (disabled) **/ + CbmTaskBuildEvents(const CbmTaskBuildEvents&) = delete; + + + /** @brief Destructor **/ + virtual ~CbmTaskBuildEvents(); + + + /** @brief Task execution **/ + virtual void Exec(Option_t* opt); + + + /** @brief Finish timeslice **/ + virtual void Finish(); + + + /** @brief Assignment operator (disabled) **/ + CbmTaskBuildEvents& operator=(const CbmTaskBuildEvents&) = delete; + + + /** @brief Configure the event building time intervals + ** @param tMin Trigger window start time w.r.t. trigger time + ** @param tMax Trigger window end time w.r.t. trigger time + **/ + void SetTimeWindow(double tMin, double tMax) + { + fEvtTimeStsMin = tMin; + fEvtTimeStsMax = tMax; + } + + +private: // methods + /** @brief Task initialisation **/ + virtual InitStatus Init(); + + +private: // members + CbmDigiManager* fDigiMan = nullptr; //! Input data + std::vector<ECbmModuleId> fSystems {}; // List of detector systems + std::vector<CbmDigiEvent>* fEvents = nullptr; //! Output data + cbm::algo::EventBuilder fAlgo {}; //! Algorithm + double fEvtTimeStsMin = 0.; + double fEvtTimeStsMax = 0.; + size_t fNumTs = 0; // Number of processed time slices + size_t fNumTriggers = 0; // Number of triggers + size_t fNumEvents = 0; // Number of produced events + size_t fNumDigisStsTs = 0; // Number of digis in timeslices + size_t fNumDigisStsEv = 0; // Number of digis in events + double fTimeFillTs = 0.; + double fTimeBuildEvt = 0.; + double fTimeTot = 0.; + + + ClassDef(CbmTaskBuildEvents, 1); +}; + +#endif /* CBMTASKBUILDEVENTS_H */