#ifndef _tls_Geant4Manager_h_ #define _tls_Geant4Manager_h_ class G4RunManager; class G4VUserDetectorConstruction; class G4VUserPhysicsList; class G4VisManager; #include <vector> #include <utl/Singleton.h> #include <tls/Geant4Customization.h> #include <tls/GlobalPhysicsList.h> namespace tls{ class G4VPhysicsListCustomization; /** \class Geant4Manager \brief class that handles multiple Geant4 runs in one offline session \author Martin Maur \author Javier Gonzalez The Geant4Manager class is the main class in the Geant4 tools group. It handles (as best as we can) the switching between different sets of Geant4 configurations. It also initializes the run manager, sets the seed in CLHEPs random engine, and redirects Geant4 output through the framework's error logger. To run a Geant4 module in the same sequence as another Geant4 module, each module has to provide a class derived from Geant4Customization. This will contain a G4VPhysicsListCustomization, a G4VUserDetectorConstruction, a G4VUserPrimaryGeneratorAction, and optionally some user actions. An attempt was made to automate the memory handling. This did not work because the singleton instance is deleted at exit but it seems to happen _after_ something else in Geant4 is already deleted, giving a segmentation fault at exit. Haven't checked this further. As a result, each module that registers a customization has to call the NotifyDelete method. After this method is called as many times as the AddCustomization method, Geant4's run manager is deleted. \author Martin Maur \author Javier Gonzalez \date 04 May 2012 \ingroup geant4 */ class Geant4Manager: public utl::Singleton<Geant4Manager> { public: G4RunManager* GetRunManager(); /// Set the default physics list. This will throw an exception if the run manager has been initialized already. void SetDefaultPhysicsList(G4VUserPhysicsList* physicsList); /// Add a visualization manager. Only one visualization manager is accepted. void AddVisManager(G4VisManager* visManager); /// This is the main method a Geant4 module needs to call. It /// should be called in the module's Init method, to give chance /// to all modules to provide their own customization before doing /// any actual simulation. void AddCustomization(Geant4Customization& custom); /// Method to switch to one particular configuration. This method /// should be called from the Run method, right before calling /// beamOn. void Customize(const std::string& name); /// Undo the customizations introduced by the current configuration. void Reset(); /// Book-keeping method. Call this to let the manager know your module does not need Geant4 anymore. void NotifyDelete(); void DumpProcesses(); private: Geant4Manager(); ~Geant4Manager(); // disable these two Geant4Manager(const Geant4Manager&); Geant4Manager operator=(const Geant4Manager&); void InitPhysics(); void SetVerbosity(int verbosity); G4RunManager* fRunManager; GlobalPhysicsList* fMasterPhysicsList; G4VisManager* fVisManager; bool fPhysicsInitialized; unsigned int fClosedModules; unsigned int fVerboseLevel; std::map<std::string, Geant4Customization> fCustomizations; std::string fCurrentCustomization; friend class utl::Singleton<Geant4Manager>; }; } #endif