Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:55:23

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 #ifndef DDG4_GEANT4KERNEL_H
0014 #define DDG4_GEANT4KERNEL_H
0015 
0016 // Framework include files
0017 #include <DDG4/Geant4ActionContainer.h>
0018 
0019 // C/C++ include files
0020 #include <map>
0021 #include <typeinfo>
0022 #include <functional>
0023 
0024 class DD4hep_End_Of_File : public std::exception {
0025 public:
0026   DD4hep_End_Of_File() : std::exception() {}
0027   virtual const char* what() const noexcept { return "Reached end of input file"; }
0028 
0029 };
0030 
0031 // Forward declarations
0032 class G4RunManager;
0033 class G4UIdirectory;
0034 class G4VPhysicalVolume;
0035 
0036 /// Namespace for the AIDA detector description toolkit
0037 namespace dd4hep {
0038 
0039   /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
0040   namespace sim {
0041 
0042     // Forward declarations
0043     class Geant4ActionPhase;
0044 
0045     /// Class, which allows all Geant4Action derivatives to access the DDG4 kernel structures.
0046     /**
0047      *  To implement access to a user specified framework please see class Geant4Context.
0048      *
0049      *  \author  M.Frank
0050      *  \version 1.0
0051      *  \ingroup DD4HEP_SIMULATION
0052      */
0053     class Geant4Kernel : public Geant4ActionContainer  {
0054     public:
0055       typedef std::map<unsigned long, Geant4Kernel*>    Workers;
0056       typedef std::map<std::string, Geant4ActionPhase*> Phases;
0057       typedef std::map<std::string, Geant4Action*>      GlobalActions;
0058       typedef std::map<std::string,int>                 ClientOutputLevels;
0059       typedef std::pair<void*, const std::type_info*>   UserFramework;
0060       using UserCallbacks = std::vector<std::function<void()> >;
0061 
0062     protected:
0063       /// Reference to the run manager
0064       G4RunManager*      m_runManager  { nullptr };
0065       /// Top level control directory
0066       G4UIdirectory*     m_control     { nullptr };
0067       /// Reference to Geant4 track manager
0068       G4TrackingManager* m_trackMgr    { nullptr };
0069       /// Detector description object
0070       Detector*          m_detDesc     { nullptr };
0071       /// Property pool
0072       PropertyManager    m_properties          { };
0073       /// Reference to the user framework
0074       UserFramework      m_userFramework       { };
0075 
0076       /// Action phases
0077       Phases        m_phases                   { };
0078       /// Worker threads
0079       Workers       m_workers                  { };
0080       /// Globally registered actions
0081       GlobalActions m_globalActions            { };
0082       /// Globally registered filters of sensitive detectors
0083       GlobalActions m_globalFilters            { };
0084       /// Property: Client output levels
0085       ClientOutputLevels m_clientLevels        { };
0086       /// Property: Name of the G4UI command tree
0087       std::string   m_controlName              { };
0088       /// Property: Name of the UI action. Must be member of the global actions
0089       std::string   m_uiName                   { };
0090       /// Property: Name of the G4 run manager factory to be used. Default: Geant4RunManager
0091       std::string   m_runManagerType;
0092       /// Property: Name of the default factory to create G4VSensitiveDetector instances
0093       std::string   m_dfltSensitiveDetectorType;
0094       /// Property: Names with specialized factories to create G4VSensitiveDetector instances
0095       std::map<std::string, std::string> m_sensitiveDetectorTypes;
0096       /// Property: Number of events to be executed in batch mode
0097       long          m_numEvent = 10;
0098       /// Property: Output level
0099       int           m_outputLevel = 0;
0100 
0101       /// Master property: Number of execution threads in multi threaded mode.
0102       int           m_numThreads = 0;
0103       /// Master property: Instantiate the Geant4 scoring manager object
0104       int           m_haveScoringMgr = false;
0105       
0106       /// Registered action callbacks on configure
0107       UserCallbacks m_actionConfigure  { };
0108       /// Registered action callbacks on initialize
0109       UserCallbacks m_actionInitialize { };
0110       /// Registered action callbacks on terminate
0111       UserCallbacks m_actionTerminate  { };
0112 
0113 
0114       /// Flag: Master instance (id<0) or worker (id >= 0)
0115       unsigned long      m_id = 0, m_ident = 0;
0116       /// Access to geometry world
0117       G4VPhysicalVolume* m_world  = 0;
0118 
0119       /// Parent reference
0120       Geant4Kernel*      m_master         { nullptr };
0121       Geant4Kernel*      m_shared         { nullptr };
0122       Geant4Context*     m_threadContext  { nullptr };
0123 
0124       bool isMaster() const  { return this == m_master; }
0125       bool isWorker() const  { return this != m_master; }
0126 
0127 #ifndef __CINT__
0128       /// Standard constructor for workers
0129       Geant4Kernel(Geant4Kernel* m, unsigned long identifier);
0130 #endif
0131 
0132     public:
0133       /// Standard constructor for the master instance
0134       Geant4Kernel(Detector& description);
0135 
0136       /// Thread's master context
0137       Geant4Kernel& master()  const  { return *m_master; }
0138 
0139       /// Shared action context
0140       Geant4Kernel& shared()  const  { return *m_shared; }
0141 
0142       //bool isMultiThreaded() const { return m_multiThreaded; }
0143       bool isMultiThreaded() const { return m_numThreads > 0; }
0144 
0145       /// Access thread identifier
0146       static unsigned long int thread_self();
0147 
0148     public:
0149 
0150       /// Embedded helper class to facilitate map access to the phases.
0151       /** @class PhaseSelector Geant4Kernel.h DDG4/Geant4Kernel.h
0152        *
0153        * @author  M.Frank
0154        * @version 1.0
0155        */
0156       class PhaseSelector {
0157       public:
0158         /// Reference to embedding object
0159         Geant4Kernel* m_kernel;
0160         /// Standard constructor
0161         PhaseSelector(Geant4Kernel* kernel);
0162         /// Copy constructor
0163         PhaseSelector(const PhaseSelector& c);
0164         /// Assignment operator
0165         PhaseSelector& operator=(const PhaseSelector& c);
0166         /// Phase access to the map
0167         Geant4ActionPhase& operator[](const std::string& name) const;
0168       } phase;
0169 
0170       enum State {
0171         SETTING_UP, INITIALIZED
0172       };
0173       /// Default destructor
0174       virtual ~Geant4Kernel();
0175 
0176 #ifndef __CINT__
0177       /// Instance accessor
0178       static Geant4Kernel& instance(Detector& description);
0179 #endif
0180       /// Access phase phases
0181       const Phases& phases() const              {        return m_phases;          }
0182       /// Access to detector description
0183       Detector& detectorDescription() const     {        return *m_detDesc;        }
0184       /// Access the tracking manager
0185       G4TrackingManager* trackMgr() const       {        return m_trackMgr;        }
0186       /// Access the tracking manager
0187       void setTrackMgr(G4TrackingManager* mgr)  {        m_trackMgr = mgr;         }
0188       /// Access the command directory
0189       const std::string& directoryName() const  {        return m_controlName;     }
0190       /// Access worker identifier
0191       unsigned long id()  const                 {        return m_ident;           }
0192       /// Access to the Geant4 run manager
0193       G4RunManager& runManager();
0194       /// Generic framework access
0195       UserFramework& userFramework()            {        return m_userFramework;   }
0196       /// Set the framework context to the kernel object
0197       template <typename T> void setUserFramework(T* object)   {
0198         m_userFramework = UserFramework(object,&typeid(T));
0199       }
0200       /// Property access: Name of the default factory to create G4VSensitiveDetector instances
0201       const std::string defaultSensitiveDetectorType()  const  {
0202         return m_dfltSensitiveDetectorType;
0203       }
0204       /// Property access: Names with specialized factories to create G4VSensitiveDetector instances
0205       const std::map<std::string, std::string>& sensitiveDetectorTypes()  const   {
0206         return m_sensitiveDetectorTypes;
0207       }
0208       /// Add new sensitive type to factory list
0209       /** This is present mainly for debugging purposes and tests.
0210        * Never necessary in real life!
0211        * For all practical purpose the default type Geant4SensDet is sufficient.
0212        *
0213        */
0214       void defineSensitiveDetectorType(const std::string& type, const std::string& factory);
0215       /// Access to geometry world
0216       G4VPhysicalVolume* world()  const;
0217       /// Set the geometry world
0218       void setWorld(G4VPhysicalVolume* volume);
0219       
0220       /** Property access                            */
0221       /// Access to the properties of the object
0222       PropertyManager& properties()             {        return m_properties;      }
0223       /// Print the property values
0224       void printProperties() const;
0225       /// Declare property
0226       template <typename T> Geant4Kernel& declareProperty(const std::string& nam, T& val);
0227       /// Declare property
0228       template <typename T> Geant4Kernel& declareProperty(const char* nam, T& val);
0229       /// Check property for existence
0230       bool hasProperty(const std::string& name) const;
0231       /// Access single property
0232       Property& property(const std::string& name);
0233 
0234       /** Output level settings                       */
0235       /// Access the output level
0236       PrintLevel outputLevel() const  {        return (PrintLevel)m_outputLevel;    }
0237       /// Set the global output level of the kernel object; returns previous value
0238       PrintLevel setOutputLevel(PrintLevel new_level);
0239       /// Fill cache with the global output level of a named object. Must be set before instantiation
0240       void setOutputLevel(const std::string object, PrintLevel new_level);
0241       /// Retrieve the global output level of a named object.
0242       PrintLevel getOutputLevel(const std::string object) const;
0243 
0244       /// Register configure callback. Signature:   (function)()
0245       void register_configure(const std::function<void()>& callback);
0246       /// Register initialize callback. Signature:  (function)()
0247       void register_initialize(const std::function<void()>& callback);
0248       /// Register terminate callback. Signature:   (function)()
0249       void register_terminate(const std::function<void()>& callback);
0250 
0251       /// Register action by name to be retrieved when setting up and connecting action objects
0252       /** Note: registered actions MUST be unique.
0253        *  However, not all actions need to registered....
0254        *  Only register those, you later need to retrieve by name.
0255        */
0256       Geant4Kernel& registerGlobalAction(Geant4Action* action);
0257       /// Retrieve action from repository
0258       Geant4Action* globalAction(const std::string& action_name, bool throw_if_not_present = true);
0259       /// Register filter by name to be retrieved when setting up and connecting filter objects
0260       /** Note: registered filters MUST be unique.
0261        *  However, not all filters need to registered....
0262        *  Only register those, you later need to retrieve by name.
0263        */
0264       Geant4Kernel& registerGlobalFilter(Geant4Action* filter);
0265       /// Retrieve filter from repository
0266       Geant4Action* globalFilter(const std::string& filter_name, bool throw_if_not_present = true);
0267 
0268       /// Access phase by name
0269       Geant4ActionPhase* getPhase(const std::string& name);
0270 
0271       /// Add a new phase to the phase
0272       virtual Geant4ActionPhase* addSimplePhase(const std::string& name, bool throw_on_exist);
0273 
0274       /// Add a new phase to the phase
0275       virtual Geant4ActionPhase* addPhase(const std::string& name, const std::type_info& arg1, const std::type_info& arg2,
0276                                           const std::type_info& arg3, bool throw_on_exist);
0277       /// Add a new phase to the phase
0278       template <typename A0> Geant4ActionPhase* addPhase(const std::string& name, bool throw_on_exist = true) {
0279         return addPhase(name, typeid(A0), typeid(void), typeid(void), throw_on_exist);
0280       }
0281       /// Add a new phase to the phase
0282       template <typename A0, typename A1>
0283       Geant4ActionPhase* addPhase(const std::string& name, bool throw_on_exist = true) {
0284         return addPhase(name, typeid(A0), typeid(A1), typeid(void), throw_on_exist);
0285       }
0286       /// Add a new phase to the phase
0287       template <typename A0, typename A1, typename A2>
0288       Geant4ActionPhase* addPhase(const std::string& name, bool throw_on_exist = true) {
0289         return addPhase(name, typeid(A0), typeid(A1), typeid(A2), throw_on_exist);
0290       }
0291       /// Remove an existing phase from the phase. If not existing returns false
0292       virtual bool removePhase(const std::string& name);
0293       /// Destroy all phases. To be called only at shutdown.
0294       virtual void destroyPhases();
0295 
0296       /// Execute phase action if it exists
0297       virtual bool executePhase(const std::string& name, const void** args)  const;
0298 
0299       /// Construct detector geometry using description plugin
0300       virtual void loadGeometry(const std::string& compact_file);
0301       /// Load XML file 
0302       virtual void loadXML(const char* fname);
0303 
0304       /** Geant4 Multi threading support */
0305       /// Create identified worker instance
0306       virtual Geant4Kernel& createWorker();
0307       /// Access worker instance by its identifier
0308       Geant4Kernel& worker(unsigned long thread_identifier, bool create_if=false);
0309       /// Access number of workers
0310       int numWorkers() const;
0311 
0312       /// Run the simulation: Configure Geant4
0313       virtual int configure();
0314       /// Run the simulation: Initialize Geant4
0315       virtual int initialize();
0316       /// Run the simulation: Simulate the number of events given by the property "NumEvents"
0317       virtual int run();
0318       /// Run the simulation: Simulate the number of events "num_events" and modify the property "NumEvents"
0319       virtual int runEvents(int num_events);
0320       /// Run the simulation: Terminate Geant4
0321       virtual int terminate();
0322     };
0323     /// Declare property
0324     template <typename T> Geant4Kernel& Geant4Kernel::declareProperty(const std::string& nam, T& val) {
0325       m_properties.add(nam, val);
0326       return *this;
0327     }
0328 
0329     /// Declare property
0330     template <typename T> Geant4Kernel& Geant4Kernel::declareProperty(const char* nam, T& val) {
0331       m_properties.add(nam, val);
0332       return *this;
0333     }
0334 
0335     /// Main executor steering the Geant4 execution
0336     class Geant4Exec {
0337     public:
0338       /// Configure the application
0339       static int configure(Geant4Kernel& kernel);
0340       /// Initialize the application
0341       static int initialize(Geant4Kernel& kernel);
0342       /// Run the application and simulate events
0343       static int run(Geant4Kernel& kernel);
0344       /// Terminate the application
0345       static int terminate(Geant4Kernel& kernel);
0346     };
0347 
0348   }    // End namespace sim
0349 }      // End namespace dd4hep
0350 #endif // DDG4_GEANT4KERNEL_H