22#include "TLorentzVector.h"
24#include "TGeoBranchArray.h"
25#include "TGeoNavigator.h"
54 : fApplication(nullptr), fCurrentEngine(nullptr), fTotalNPrimaries(0), fTotalNTracks(0), fUserStack(nullptr),
55 fBranchArrayContainer(), fIsInitialized(kFALSE), fIsInitializedUser(kFALSE), fGeometryConstructed(kFALSE)
58 ::Fatal(
"TMCManager::TMCManager",
"Attempt to create two instances of singleton.");
98 ::Fatal(
"TMCManager::RegisterMC",
"This engine is already registered.");
105 if (!gGeoManager->IsClosed()) {
109 ::Fatal(
"TMCManager::Register",
"The TGeo geometry is not closed. Please check whether you just have to close "
110 "it or whether something was forgotten.");
134 ::Fatal(
"TMCManager::Register",
"The application is already registered.");
136 ::Info(
"TMCManager::Register",
"Register user application and construct geometry");
159 engines.resize(
fEngines.size(),
nullptr);
160 for (UInt_t i = 0; i <
fEngines.size(); i++) {
172 if (id < 0 || id >=
static_cast<Int_t
>(
fEngines.size())) {
173 ::Fatal(
"TMCManager::GetEngine",
"Unknown engine ID.");
185 for (UInt_t i = 0; i <
fEngines.size(); i++) {
186 if (strcmp(engineName,
fEngines[i]->GetName()) == 0) {
190 ::Warning(
"TMCManager::GetEngineId",
"Unknown engine %s.", engineName);
246 if (engineId < 0 || engineId >=
static_cast<Int_t
>(
fEngines.size())) {
247 ::Fatal(
"TMCManager::ForwardTrack",
"Engine ID %i out of bounds. Have %zu engines.", engineId,
fEngines.size());
249 if (trackId >=
static_cast<Int_t
>(
fParticles.size())) {
259 if (particle->IsPrimary()) {
264 if (particle->IsPrimary()) {
265 fStacks[engineId]->PushPrimaryTrackId(trackId);
267 fStacks[engineId]->PushSecondaryTrackId(trackId);
292 if (engineTargetId < 0 || engineTargetId >=
static_cast<Int_t
>(
fEngines.size())) {
293 ::Fatal(
"TMCManager::TransferTrack",
294 "Target engine ID out of bounds. Have %zu engines. Requested target ID was %i",
fEngines.size(),
326 geoState->InitFromNavigator(gGeoManager->GetCurrentNavigator());
344 if (checkTrackIdRange && (trackId < 0 || trackId >=
static_cast<Int_t
>(
fParticles.size()) || !
fParticles[trackId])) {
348 if (geoStateId == 0) {
352 branchArray->UpdateNavigator(gGeoManager->GetCurrentNavigator());
381 ::Fatal(
"TMCManager::Run",
"Missing user stack pointer.");
384 ::Fatal(
"TMCManager::Run",
"No engines registered");
389 if (!mc->IsRootGeometrySupported()) {
390 ::Fatal(
"TMCManager::Run",
"Engine %s does not support geometry built via ROOT's TGeoManager", mc->GetName());
392 Int_t currentEngineId = mc->GetId();
407 ::Warning(
"TMCManager::Run",
"Only one engine registered. That will lead to overhead in "
408 "the simulation run due to additional hooks and dispatches "
409 "to the TMCManager.");
421 ::Fatal(
"TMCManager::Run",
"Engines have not yet been initialized.");
428 ::Fatal(
"TMCManager::Run",
"Need at least one event to process but %i events specified.", nEvents);
432 for (Int_t i = 0; i < nEvents; i++) {
433 ::Info(
"TMCManager::Run",
"Start event %i", i + 1);
455 stack->ResetInternals();
457 for (UInt_t i = 0; i <
fParticles.size(); i++) {
475 for (UInt_t i = 0; i <
fStacks.size(); i++) {
476 if (
fStacks[i]->GetStackedNtrack() > 0) {
TGeoBranchArray * GetNewGeoState(UInt_t &userIndex)
Get a TGeoBranchArray to set to current geo state.
const TGeoBranchArray * GetGeoState(UInt_t userIndex)
Get a TGeoBranchArray to read the current state from.
void InitializeFromGeoManager(TGeoManager *man, UInt_t size=8)
Initialize from TGeoManager to extract maxlevels.
void FreeGeoStates()
Free all geo states at once but keep the container size.
void FreeGeoState(UInt_t userIndex)
Free the index of this geo state such that it can be re-used.
Concrete implementation of particles stack used by the TMCManager.
Singleton manager class for handling and steering a run with multiple TVirtualMC engines sharing even...
Int_t GetEngineId(const char *name) const
Get engine ID by its name.
Bool_t RestoreGeometryState()
Try to restore geometry for the track currently set.
TVirtualMC * GetCurrentEngine() const
Get the current engine pointer.
Bool_t fGeometryConstructed
void TerminateRun()
Terminate a run in all engines.
virtual ~TMCManager()
Destructor.
void ForwardTrack(Int_t toBeDone, Int_t trackId, Int_t parentId, TParticle *particle, Int_t engineId)
User interface to forward particle to specifiic engine.
std::vector< TParticle * > fParticles
All tracks (persistent)
std::vector< TVirtualMC ** > fConnectedEnginePointers
Connected engine pointers which will be updated everytime the current engine changes.
Int_t fTotalNPrimaries
Total number of primaries ever pushed.
void ConnectEnginePointer(TVirtualMC **mc)
Connect a pointer which is updated whenever the engine is changed.
void TransferTrack(Int_t engineTargetId)
Transfer track from current engine to engine with engineTargetId.
Bool_t GetNextEngine()
Find the next engine.
TVirtualMC * fCurrentEngine
Pointer to current engine.
TVirtualMC * GetEngine(Int_t id) const
Get an engine pointer by ID.
void UpdateEnginePointers(TVirtualMC *mc)
Update all engine pointers connected to the TMCManager.
void Init()
Initialize engines.
Bool_t fIsInitializedUser
Flag if specific initialization for engines was done.
TVirtualMCApplication * fApplication
Pointer to user application.
void PrepareNewEvent()
Do necessary steps before an event is triggered.
std::vector< std::unique_ptr< TMCManagerStack > > fStacks
Stacks connected to engines.
TVirtualMCStack * fUserStack
Pointer to user stack.
static TMCThreadLocal TMCManager * fgInstance
Singleton instance.
static TMCManager * Instance()
Static access method.
Int_t fTotalNTracks
Total number of tracks ever pushed.
TMCManager()
Default constructor.
std::vector< std::unique_ptr< TMCParticleStatus > > fParticlesStatus
All particles' status (persistent)
void Run(Int_t nEvents)
Run the event loop.
std::vector< TVirtualMC * > fEngines
Collecting pointers to all instanciated TVirtualMCs.
Bool_t fIsInitialized
Flag if engines are initilaized.
void SetUserStack(TVirtualMCStack *stack)
Set user stack.
Int_t NEngines() const
Return the number of registered engines.
TGeoMCBranchArrayContainer fBranchArrayContainer
Pointer to cache with geometry states.
void Register(TVirtualMC *engine)
A TVirtualMC will register itself via this method during construction if a TMCManager was instanciate...
void GetEngines(std::vector< TVirtualMC * > &engines) const
Get registered engine pointers.
Interface to a user Monte Carlo application.
virtual void GeneratePrimaries()=0
Generate primary particles.
virtual void ConstructGeometry()=0
Construct user geometry.
virtual Bool_t MisalignGeometry()
Misalign user geometry (optional)
virtual void ConstructOpGeometry()
Define parameters for optical processes (optional)
virtual void BeginEvent()=0
Define actions at the beginning of the event.
virtual void FinishEvent()=0
Define actions at the end of the event.
Interface to a user defined particles stack.
Abstract Monte Carlo interface.
virtual Int_t StepNumber() const =0
Return the current step number.
virtual void InterruptTrack()=0
That triggers stopping the transport of the current track without dispatching to common routines like...
virtual Double_t TrackLength() const =0
Return the length of the current track from its origin (in cm)
virtual void ProcessEvent()=0
Process one event.
void SetId(UInt_t id)
Set the VMC id.
virtual void TrackPolarization(Double_t &polX, Double_t &polY, Double_t &polZ) const =0
Get the current polarization.
virtual Double_t TrackWeight() const =0
Get the current weight.
virtual void TrackPosition(TLorentzVector &position) const =0
Return the current position in the master reference frame of the track being transported.
virtual void SetStack(TVirtualMCStack *stack)
Set the particle stack.
void SetManagerStack(TMCManagerStack *stack)
Set container holding additional information for transported TParticles.
static TMCThreadLocal TVirtualMC * fgMC
Static TVirtualMC pointer.
virtual void TrackMomentum(TLorentzVector &momentum) const =0
Return the direction and the momentum (GeV/c) of the track currently being transported.
Int_t GetId() const
Return the VMC's ID.