Skip to content

Commit

Permalink
o2-sim: Better VMC shutdown (via plugin code)
Browse files Browse the repository at this point in the history
Introducing the ability to close/terminate the
VMC simulation engines.

* for instance to print final statistics about
  steps, magnetic field calls etc.
  • Loading branch information
sawenzel committed Sep 25, 2023
1 parent b586c28 commit c5053d6
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 12 deletions.
14 changes: 14 additions & 0 deletions Detectors/gconfig/g4Config.C
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,17 @@ void Config()

std::cout << "g4Config.C finished" << std::endl;
}

void Terminate()
{
static bool terminated = false;
if (!terminated) {
std::cout << "Executing G4 terminate\n";
TGeant4* geant4 = dynamic_cast<TGeant4*>(TVirtualMC::GetMC());
if (geant4) {
// we need to call finish run for Geant4 ... Since we use ProcessEvent() interface;
geant4->FinishRun();
}
terminated = true;
}
}
4 changes: 4 additions & 0 deletions Detectors/gconfig/include/SimSetup/SimSetup.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@
// or submit itself to any jurisdiction.

#ifndef O2_SIMSETUP_H
#define O2_SIMSETUP_H

namespace o2
{
struct SimSetup {
static void setup(const char* engine);

// a static entrypoint to shutdown the VMC system
static void shutdown();
};
} // namespace o2

Expand Down
9 changes: 8 additions & 1 deletion Detectors/gconfig/src/G4Config.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,23 @@ using std::endl;
// these are used in commonConfig.C
using o2::eventgen::DecayerPythia8;

#include "../g4Config.C"

namespace o2
{
namespace g4config
{
#include "../g4Config.C"

void G4Config()
{
LOG(info) << "Setting up G4 sim from library code";
Config();
}

void G4Terminate()
{
Terminate();
}

} // namespace g4config
} // namespace o2
37 changes: 27 additions & 10 deletions Detectors/gconfig/src/SimSetup.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <cstring>
#include "SimSetup/SimSetup.h"
#include "TVirtualMC.h"
#include <fairlogger/Logger.h>
#include "SetCuts.h"
#include <dlfcn.h>
Expand All @@ -25,9 +26,8 @@ namespace o2

typedef void (*setup_fnc)();

void setupFromPlugin(const char* libname, const char* setupfuncname)
void execFromPlugin(const char* libname, const char* funcname)
{
LOG(info) << "Loading simulation plugin " << libname;
auto libHandle = dlopen(libname, RTLD_NOW);
// try to make the library loading a bit more portable:
if (!libHandle) {
Expand All @@ -43,26 +43,43 @@ void setupFromPlugin(const char* libname, const char* setupfuncname)
libHandle = dlopen(stream.str().c_str(), RTLD_NOW);
}
assert(libHandle);
auto setup = (setup_fnc)dlsym(libHandle, setupfuncname);
assert(setup);
setup();
auto func = (setup_fnc)dlsym(libHandle, funcname);
assert(func);
func();
}

void execSetupFromPlugin(const char* libname, const char* funcname)
{
LOG(info) << "Seting up transport engine from library " << libname;
execFromPlugin(libname, funcname);
}

void SimSetup::setup(const char* engine)
{
if (strcmp(engine, "TGeant3") == 0) {
setupFromPlugin("libO2G3Setup", "_ZN2o28g3config8G3ConfigEv");
execSetupFromPlugin("libO2G3Setup", "_ZN2o28g3config8G3ConfigEv");
} else if (strcmp(engine, "TGeant4") == 0) {
setupFromPlugin("libO2G4Setup", "_ZN2o28g4config8G4ConfigEv");
execSetupFromPlugin("libO2G4Setup", "_ZN2o28g4config8G4ConfigEv");
} else if (strcmp(engine, "TFluka") == 0) {
setupFromPlugin("libO2FLUKASetup", "_ZN2o211flukaconfig11FlukaConfigEv");
execSetupFromPlugin("libO2FLUKASetup", "_ZN2o211flukaconfig11FlukaConfigEv");
} else if (strcmp(engine, "MCReplay") == 0) {
setupFromPlugin("libO2MCReplaySetup", "_ZN2o214mcreplayconfig14MCReplayConfigEv");
execSetupFromPlugin("libO2MCReplaySetup", "_ZN2o214mcreplayconfig14MCReplayConfigEv");
} else if (strcmp(engine, "O2TrivialMCEngine") == 0) {
setupFromPlugin("libO2O2TrivialMCEngineSetup", "_ZN2o223o2trivialmcengineconfig23O2TrivialMCEngineConfigEv");
execSetupFromPlugin("libO2O2TrivialMCEngineSetup", "_ZN2o223o2trivialmcengineconfig23O2TrivialMCEngineConfigEv");
} else {
LOG(fatal) << "Unsupported engine " << engine;
}
o2::SetCuts();
}

// function to shutdown the engines and do some necessary
// finalisation work
void SimSetup::shutdown()
{
auto vmc = TVirtualMC::GetMC();
if (strcmp(vmc->GetName(), "TGeant4") == 0) {
execFromPlugin("libO2G4Setup", "_ZN2o28g4config11G4TerminateEv");
}
}

} // namespace o2
4 changes: 3 additions & 1 deletion run/O2SimDeviceRunner.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
/// @author Sandro Wenzel

#include "O2SimDevice.h"
#include "SimSetup/SimSetup.h"
#include <fairmq/DeviceRunner.h>
#include <boost/program_options.hpp>
#include <memory>
Expand Down Expand Up @@ -66,7 +67,7 @@ void sigaction_handler(int signal, siginfo_t* signal_info, void*)
break;
}
}

o2::SimSetup::shutdown();
_exit(0);
}

Expand Down Expand Up @@ -177,6 +178,7 @@ int runSim(KernelSetup setup)
while (setup.sim->Kernel(setup.workerID, *setup.primchannel, *setup.datachannel, setup.primstatuschannel)) {
}
doLogInfo(setup.workerID, "simulation is done");
o2::SimSetup::shutdown();
return 0;
}

Expand Down

0 comments on commit c5053d6

Please sign in to comment.