Skip to content
Snippets Groups Projects
Commit 5db8ef02 authored by Volker Friese's avatar Volker Friese Committed by Florian Uhlig
Browse files

Integrate reconstruction from timeslice data and from digi data (simulation).

parent 90ec7a7b
No related branches found
No related tags found
1 merge request!799Integrate reconstruction from timeslice data and from digi data (simulation).
Pipeline #17218 passed
......@@ -6,7 +6,7 @@
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)
GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/reco/reco_fairroot.C)
# ============================================================================
......@@ -85,7 +85,7 @@ foreach(setup IN LISTS cbm_setup)
RESOURCE_LOCK collParDb_${setup}
)
# --- Test run_tra_sign
# --- Test reco_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)
......@@ -100,7 +100,7 @@ foreach(setup IN LISTS cbm_setup)
RESOURCE_LOCK signParDb_${setup}
)
# --- Test run_tra_beam
# --- Test reco_tra_beam
# --- Transport run with beam events, using run_tra_beam.C
set(testname reco_tra_beam_${sname})
set(output ${datadir}/${sname}_beam)
......@@ -114,7 +114,7 @@ foreach(setup IN LISTS cbm_setup)
RESOURCE_LOCK beamParDb_${setup}
)
# --- Test run_digi_ts
# --- Test reco_digi
# --- Detector response simulation, time-based, using run_digi.C
set(testname reco_digi_${sname})
set(eventrate 1.e7)
......@@ -131,17 +131,16 @@ foreach(setup IN LISTS cbm_setup)
RESOURCE_LOCK collParDb_${setup}
)
# --- Test reco_digi
# --- Test reco_reco_sim
# --- 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(testname reco_reco_sim_${sname})
add_test(${testname} ${MACRODIR}/reco_fairroot.sh
\"${datadir}/${sname}.raw.root\" \"${datadir}/${sname}.reco.root\")
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}
FIXTURES_SETUP fixt_reco_sim_${setup}
RESOURCE_LOCK collParDb_${setup}
)
......@@ -150,7 +149,7 @@ endforeach(setup IN LISTS cbm_setup)
# ============================================================================
Install(FILES reco_digi.C
Install(FILES reco_fairroot.C reco_unpack.C
DESTINATION share/cbmroot/macro/reco
)
Install(CODE "FILE(MAKE_DIRECTORY \${CMAKE_INSTALL_PREFIX}/share/cbmroot/macro/reco/data)")
/* 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 "CbmTaskTriggerDigi.h"
#include <FairFileSource.h>
#include <FairMonitor.h>
#include <FairParAsciiFileIo.h>
#include <FairParRootFileIo.h>
#include <FairRunAna.h>
#include <FairRuntimeDb.h>
#include <FairSystemInfo.h>
#include <TStopwatch.h>
#include <memory>
#endif
#include <FairLogger.h>
/** @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 = "reco_digi"; // this macro's name for screen log
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 + ".events.root";
TString monFile = output + ".moni_reco.root";
if (paramFile.IsNull()) paramFile = input;
TString parFile = paramFile + ".par.root";
LOG(info) << myName << ": Input file is " << rawFile;
LOG(info) << myName << ": Output file is " << outFile;
LOG(info) << myName << ": Parameter file is " << parFile;
// ----- 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());
// ------------------------------------------------------------------------
// ----- Digi trigger -------------------------------------------------
auto trigger = std::make_unique<CbmTaskTriggerDigi>();
double triggerWindow = 10.; // Trigger window size in ns
int32_t minNumDigis = 100; // Trigger threshold in number of digis
double deadTime = 50.; // Minimum time between two triggers
trigger->SetAlgoParams(triggerWindow, minNumDigis, deadTime);
trigger->AddSystem(ECbmModuleId::kSts);
LOG(info) << myName << ": Added task " << trigger->GetName();
run->AddTask(trigger.release());
// ------------------------------------------------------------------------
// ----- Event building -----------------------------------------------
auto evtBuild = std::make_unique<CbmTaskBuildEvents>();
evtBuild->SetEventWindow(ECbmModuleId::kSts, -20., 30.); // event building time window for STS
LOG(info) << myName << ": Added task " << evtBuild->GetName();
run->AddTask(evtBuild.release());
// ------------------------------------------------------------------------
// ----- 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
......@@ -18,27 +18,25 @@
using std::string;
/** @brief Macro for CBM reconstruction from FLES timeslices
/** @brief Macro for CBM reconstruction from FLES timeslices or digi level
** @author Volker Friese <v.friese@gsi.de>
** @since 12 March 2022
** @param tsaFile Name of input file (w/o extension .tsa)
** @param outFile Name of output file (w/o extension .digi.root)
** @param tsaFile Name of input file (.tsa or .root)
** @param outFile Name of output file
** @param numTs Number of timeslices to process. If not specified, all available will be used.
** @param port Port of http server. If 0, server will not be activated.
**
** Reconstruction from timeslice level, making use of the steering class CbmReco.
** Reconstruction from timeslice level with FairRoot, making use of the steering class CbmReco.
** Currently included stages:
** - Unpacking (STS only)
** - Unpacking (STS only) (if from timeslice level)
** - Event trigger based on STS digis (CbmTaskDigiTrigger)
** - Event building (CbmTaskBuildEvents) (STS only)
**
** If the tsaFile name is not specified, a default file from the repository will be used.
** If the outFile name is not specified, the input file name will be used, replacing
** the extension .tsa by .digi.root
** If the input file name is left empty, a default file from the repository will be used.
**/
void reco_steer(TString tsaFile = "", TString outFile = "", int32_t numTs = std::numeric_limits<int32_t>::max(),
uint32_t port = 8080)
void reco_fairroot(TString tsaFile, TString outFile, int32_t numTs = std::numeric_limits<int32_t>::max(),
uint16_t port = 0)
{
// ========================================================================
......@@ -74,7 +72,7 @@ void reco_steer(TString tsaFile = "", TString outFile = "", int32_t numTs = std:
// ----- Environment --------------------------------------------------
TString myName = "reco_steer"; // this macro's name for screen output
TString myName = "reco_fairoot"; // this macro's name for screen output
TString srcDir = gSystem->Getenv("VMCWORKDIR"); // top source directory
// ------------------------------------------------------------------------
......@@ -83,14 +81,6 @@ void reco_steer(TString tsaFile = "", TString outFile = "", int32_t numTs = std:
// the code is outdated.
// ----- Default file names ---------------------------------------------
if (tsaFile.IsNull()) tsaFile = srcDir + "/input/mcbm_run399_first20Ts";
TString inFile = tsaFile + ".tsa";
if (outFile.IsNull()) outFile = tsaFile;
outFile += ".digi.root";
// ------------------------------------------------------------------------
// ----- Logger settings ----------------------------------------------
FairLogger::GetLogger()->SetLogScreenLevel(logLevel.Data());
FairLogger::GetLogger()->SetLogVerbosityLevel(logVerbosity.Data());
......@@ -100,7 +90,7 @@ void reco_steer(TString tsaFile = "", TString outFile = "", int32_t numTs = std:
// ----- Run reconstruction -------------------------------------------
TStopwatch timer;
timer.Start();
CbmReco run(inFile.Data(), outFile.Data(), numTs, config, port);
CbmReco run(tsaFile.Data(), outFile.Data(), numTs, config, port);
run.Run();
timer.Stop();
// ------------------------------------------------------------------------
......
/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: Volker Friese [committer] */
// --- Includes needed for IDE code analyser
#if !defined(__CLING__)
#include "CbmSourceTs.h"
#include "CbmTaskUnpack.h"
#include "CbmTsEventHeader.h"
#include <FairRootFileSink.h>
#include <FairRunOnline.h>
#include <TStopwatch.h>
#include <TSystem.h>
#include <iostream>
#include <memory>
#endif
#include <FairLogger.h>
using std::string;
/** @brief Macro for CBM reconstruction from FLES timeslices
** @author Volker Friese <v.friese@gsi.de>
** @since 12 March 2022
** @param tsaFile Name of input file (w/o extension .tsa)
** @param outFile Name of output file (w/o extension .digi.root)
**
** Reconstruction from timeslice level. Currently included stages:
** - Unpacking (STS only)
** - Event trigger based on STS digis (CbmTaskDigiTrigger)
** - Event building (CbmTaskBuildEvents) (STS only)
**
** TODO: To be expanded with the progress of the algo project.
**
** If the tsaFile name is not specified, a default file from the reporistory will be used.
** If the outFile name is not specified, the input file name will be used, replacing
** the extension .tsa by .digi.root
**/
void reco_ts(TString tsaFile = "", TString outFile = "")
{
// ========================================================================
// Adjust this part according to your requirements
// --- Logger settings ----------------------------------------------------
TString logLevel = "INFO";
TString logVerbosity = "LOW";
// ------------------------------------------------------------------------
// ----- Environment --------------------------------------------------
TString myName = "reco_ts"; // this macro's name for screen output
TString srcDir = gSystem->Getenv("VMCWORKDIR"); // top source directory
// ------------------------------------------------------------------------
// In general, the following parts need not be touched
// ========================================================================
// Tested with file 1588_node8_1_0000.tsa
// TODO: Would need a small up-to-date default input file; the one distributed with
// the code is outdated.
// ----- Default file names ---------------------------------------------
if (tsaFile.IsNull()) tsaFile = srcDir + "/input/mcbm_run399_first20Ts";
TString inFile = tsaFile + ".tsa";
if (outFile.IsNull()) outFile = tsaFile;
outFile += ".digi.root";
std::cout << std::endl << std::endl;
LOG(info) << myName << ": Using input file " << inFile;
LOG(info) << myName << ": Output file is " << outFile;
// ------------------------------------------------------------------------
// ----- Timer --------------------------------------------------------
TStopwatch timer;
timer.Start();
// ------------------------------------------------------------------------
// ---- Run configuration ---------------------------------------------
auto source = new CbmSourceTs(inFile.Data());
auto run = new FairRunOnline(source);
auto sink = new FairRootFileSink(outFile.Data());
run->SetSink(sink);
auto eventheader = new CbmTsEventHeader();
run->SetEventHeader(new CbmTsEventHeader());
// ------------------------------------------------------------------------
// ----- Unpacking ----------------------------------------------------
auto unpack = std::make_unique<CbmTaskUnpack>();
unpack->SetOutputBranchPersistent("DigiTimeslice.", kFALSE);
LOG(info) << myName << ": Added task " << unpack->GetName();
run->AddTask(unpack.release());
// ------------------------------------------------------------------------
// ----- Digi trigger -------------------------------------------------
auto trigger = std::make_unique<CbmTaskTriggerDigi>();
double triggerWindow = 10.; // Trigger window size in ns
int32_t minNumDigis = 100; // Trigger threshold in number of digis
double deadTime = 50.; // Minimum time between two triggers
trigger->SetAlgoParams(triggerWindow, minNumDigis, deadTime);
trigger->AddSystem(ECbmModuleId::kSts);
trigger->SetOutputBranchPersistent("Trigger", kFALSE);
LOG(info) << myName << ": Added task " << trigger->GetName();
run->AddTask(trigger.release());
// ------------------------------------------------------------------------
// ----- Event building -----------------------------------------------
auto evtBuild = std::make_unique<CbmTaskBuildEvents>();
evtBuild->SetEventWindow(ECbmModuleId::kSts, -20., 30.); // event building time window for STS
LOG(info) << myName << ": Added task " << evtBuild->GetName();
run->AddTask(evtBuild.release());
// ------------------------------------------------------------------------
// ----- Event QA -----------------------------------------------------
auto eventQa = std::make_unique<CbmTaskDigiEventQa>();
LOG(info) << myName << ": Added task " << eventQa->GetName();
run->AddTask(eventQa.release());
// ------------------------------------------------------------------------
// ----- Logger settings ----------------------------------------------
FairLogger::GetLogger()->SetLogScreenLevel(logLevel.Data());
FairLogger::GetLogger()->SetLogVerbosityLevel(logVerbosity.Data());
// ------------------------------------------------------------------------
// ----- Run initialisation -------------------------------------------
std::cout << std::endl;
LOG(info) << myName << ": Initialise run" << std::endl;
run->Init();
// ------------------------------------------------------------------------
// ----- Start run ----------------------------------------------------
std::cout << std::endl << std::endl;
LOG(info) << myName << ": Starting run" << std::endl;
run->Run(-1, 0);
// ------------------------------------------------------------------------
// ----- Finish -------------------------------------------------------
timer.Stop();
std::cout << std::endl << std::endl;
std::cout << "Macro finished successfully." << std::endl;
std::cout << "Output file: " << outFile << std::endl;
std::cout << "CPU time = " << timer.CpuTime() << " s, real time = " << timer.RealTime() << " s." << std::endl;
// ------------------------------------------------------------------------
} // End of main macro function
......@@ -11,8 +11,10 @@
#include "CbmTaskUnpack.h"
#include "CbmTsEventHeader.h"
#include <FairFileSource.h>
#include <FairLogger.h>
#include <FairRootFileSink.h>
#include <FairRunAna.h>
#include <FairRunOnline.h>
#include <THttpServer.h>
......@@ -130,12 +132,31 @@ int32_t CbmReco::Run()
TStopwatch timer;
timer.Start();
// --- Check if the input is a ROOT file. In that case, digis are already present and
// --- the unpacking stage must be skipped. The digis are in direct branches of the ROOT
// --- tree when coming from simulation, or in form of CbmDigiTimeslice if produced
// --- by a previous unpacking run. This variety is caught by the tasks and need not be
// --- considered here.
bool isRootInput =
fSourceNames.size() == 1 && fSourceNames.at(0).compare(fSourceNames.at(0).size() - 5, 5, ".root") == 0;
// --- Run instance
FairRunOnline run;
// --- Input source
auto source = make_unique<CbmSourceTs>(fSourceNames);
if (source) LOG(info) << "Reco: Using sources " << ListSources();
if (isRootInput) {
auto source = make_unique<FairFileSource>(fSourceNames.at(0));
LOG(info) << "Reco: Using ROOT input " << fSourceNames.at(0);
run.SetSource(source.release());
}
else {
LOG(error) << "Reco: Could not open sources " << ListSources() << "; aborting.";
return -1;
auto source = make_unique<CbmSourceTs>(fSourceNames);
if (source) LOG(info) << "Reco: Using sources " << ListSources();
else {
LOG(error) << "Reco: Could not open sources " << ListSources() << "; aborting.";
return -1;
}
run.SetSource(source.release());
}
// --- Output file
......@@ -145,37 +166,36 @@ int32_t CbmReco::Run()
LOG(error) << "Reco: Could not open output " << fOutputFileName.Data() << "; aborting.";
return -1;
}
run.SetSink(sink.release());
// --- Event header
auto header = make_unique<CbmTsEventHeader>();
run.SetEventHeader(header.release());
// --- Unpacking
auto unpack = make_unique<CbmTaskUnpack>();
unpack->SetOutputBranchPersistent("DigiTimeslice.", fConfig.fStoreTimeslice);
if (!isRootInput) {
auto unpack = make_unique<CbmTaskUnpack>();
unpack->SetOutputBranchPersistent("DigiTimeslice.", fConfig.fStoreTimeslice);
run.AddTask(unpack.release());
}
// --- Digi trigger
auto trigger = make_unique<CbmTaskTriggerDigi>();
trigger->AddSystem(fConfig.fTriggerDet);
trigger->SetAlgoParams(fConfig.fTriggerWin, fConfig.fTriggerThreshold, fConfig.fTriggerDeadTime);
trigger->SetOutputBranchPersistent("Trigger", fConfig.fStoreTrigger);
run.AddTask(trigger.release());
// --- Event building
auto evtBuild = make_unique<CbmTaskBuildEvents>();
for (auto& entry : fConfig.fEvtbuildWindows)
evtBuild->SetEventWindow(entry.first, entry.second.first, entry.second.second);
evtBuild->SetOutputBranchPersistent("DigiEvent", fConfig.fStoreEvents);
run.AddTask(evtBuild.release());
// --- Event QA
auto evtQa = make_unique<CbmTaskDigiEventQa>();
evtQa->Config(fConfig);
// --- Run configuration
FairRunOnline run(source.release());
run.SetSink(sink.release());
run.SetEventHeader(header.release());
run.AddTask(unpack.release());
run.AddTask(trigger.release());
run.AddTask(evtBuild.release());
run.AddTask(evtQa.release());
// ----- HttpServer for online monitoring
......@@ -204,9 +224,13 @@ int32_t CbmReco::Run()
// --- Run log
std::cout << std::endl;
auto src = dynamic_cast<CbmSourceTs*>(run.GetSource());
assert(src);
size_t numTs = src->GetNumTs();
size_t numTs = 1;
if (!isRootInput) {
auto src = dynamic_cast<CbmSourceTs*>(run.GetSource());
assert(src);
numTs = src->GetNumTs();
}
// TODO: Don't know how to get the number of processed timeslices for ROOT input.
double timeTotal = timeSetup + timeInit + timeRun;
LOG(info) << "=====================================";
LOG(info) << "Reco: Run summary";
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment