Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:12:40

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 
0014 #ifndef DDG4_GEANT4ACTION_H
0015 #define DDG4_GEANT4ACTION_H
0016 
0017 // Framework include files
0018 #include <DD4hep/Printout.h>
0019 #include <DD4hep/ComponentProperties.h>
0020 #include <DDG4/Geant4Context.h>
0021 #include <DDG4/Geant4Callback.h>
0022 
0023 // Geant4 forward declarations
0024 class G4Run;
0025 class G4Event;
0026 class G4Step;
0027 class G4Track;
0028 class G4TrackStack;
0029 class G4EventGenerator;
0030 class G4VTrajectory;
0031 class G4TrackingManager;
0032 class G4UIdirectory;
0033 
0034 // C/C++ include files
0035 #include <string>
0036 #include <cstdarg>
0037 
0038 #if defined(G__ROOT) || defined(__CLING__) || defined(__ROOTCLING__)
0039 #define DDG4_DEFINE_ACTION_DEFAULT_CTOR(action)  public: action() = default;
0040 #else
0041 #define DDG4_DEFINE_ACTION_DEFAULT_CTOR(action)  protected: action() = delete;
0042 #endif
0043 
0044 /// 1) Allow default constructor (necessary for ROOT)
0045 /// 2) Inhibit move constructor
0046 /// 3) Inhibit copy constructor
0047 /// 4) Inhibit move operator
0048 /// 5) Inhibit assignment operator
0049 #define DDG4_DEFINE_ACTION_CONSTRUCTORS(action)  \
0050   DDG4_DEFINE_ACTION_DEFAULT_CTOR(action)        \
0051   protected:                                     \
0052   action(action&& copy) = delete;                \
0053   action(const action& copy) = delete;           \
0054   action& operator=(action&& copy) = delete;     \
0055   action& operator=(const action& copy) = delete
0056 
0057 
0058 /// Namespace for the AIDA detector description toolkit
0059 namespace dd4hep {
0060 
0061   /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
0062   namespace sim {
0063 
0064     // Forward declarations
0065     class Geant4UIMessenger;
0066 
0067     /// Cast operator
0068     template <typename TO, typename FROM> TO fast_cast(FROM from) {
0069 #ifdef USE_FASTCAST
0070       return static_cast<TO>(from);
0071 #else
0072       return dynamic_cast<TO>(from);
0073 #endif
0074     }
0075 
0076     /// Helper class to handle strings of the format "type/name"
0077     /**
0078      *  \author  M.Frank
0079      *  \version 1.0
0080      *  \ingroup DD4HEP_SIMULATION
0081      */
0082     class TypeName {
0083     public:
0084       std::string first;
0085       std::string second;
0086       /// Default constructor
0087       TypeName() = default;
0088       /// Copy constructor
0089       TypeName(const TypeName& copy) = default;
0090       /// Copy constructor from pair
0091       TypeName(const std::pair<std::string, std::string>& c)
0092         : first(c.first), second(c.second) { }
0093       /// Initializing constructor
0094       TypeName(const std::string& typ, const std::string& nam)
0095         : first(typ), second(nam) { }
0096       /// Assignment operator
0097       TypeName& operator=(const TypeName& copy) = default;
0098       /// Split string pair according to default delimiter ('/')
0099       static TypeName split(const std::string& type_name);
0100       /// Split string pair according to custom delimiter
0101       static TypeName split(const std::string& type_name, const std::string& delim);
0102     };
0103 
0104     /// Default base class for all Geant 4 actions and derivates thereof.
0105     /**
0106      *  This is a utility class supporting properties, output and access to
0107      *  event and run objects through the context.
0108      *
0109      *  \author  M.Frank
0110      *  \version 1.0
0111      *  \ingroup DD4HEP_SIMULATION
0112      */
0113     class Geant4Action {
0114     protected:
0115       /// Reference to the Geant4 context
0116       Geant4Context*     m_context      { nullptr };
0117       /// Control directory of this action
0118       Geant4UIMessenger* m_control      { nullptr };
0119 
0120       /// Default property: Output level
0121       int                m_outputLevel  { 3 };
0122       /// Default property: Flag to create control instance
0123       bool               m_needsControl { false };
0124       /// Action name
0125       std::string        m_name         {   };
0126       /// Property pool
0127       PropertyManager    m_properties   {   };
0128       /// Reference count. Initial value: 1
0129       long               m_refCount     { 1 };
0130 
0131     public:
0132       /// Functor to update the context of a Geant4Action object
0133       /**
0134        *  \author  M.Frank
0135        *  \version 1.0
0136        *  \ingroup DD4HEP_SIMULATION
0137        */
0138       class ContextSwap   {
0139         /// reference to the context;
0140         Geant4Context* context { nullptr };
0141         Geant4Action*  action  { nullptr };
0142       public:
0143         /// Constructor
0144         ContextSwap(Geant4Action* a,Geant4Context* c) : action(a)  {
0145           context = action->context();
0146           action->updateContext(c);
0147         }
0148         /// Destructor
0149         ~ContextSwap()  { 
0150           action->updateContext(context);
0151         }
0152       };
0153 
0154     protected:
0155 
0156       /// Functor to access elements by name
0157       struct FindByName  {
0158         std::string _n;
0159         FindByName(const std::string& n) : _n(n) {}
0160         bool operator()(const Geant4Action* a) { return a->name() == _n; }
0161       };
0162       /// Actor class to manipulate action groups
0163       /**
0164        *  \author  M.Frank
0165        *  \version 1.0
0166        *  \ingroup DD4HEP_SIMULATION
0167        */
0168       template <typename T> class Actors {
0169       public:
0170         typedef typename std::vector<T*> _V;
0171         _V m_v;
0172         Actors() = default;
0173         ~Actors()  = default;
0174         void clear()                  { m_v.clear();                    }
0175         void add(T* obj)              { m_v.emplace_back(obj);          }
0176         void add_front(T* obj)        { m_v.insert(m_v.begin(), obj);   }
0177         operator const _V&() const    { return m_v;                     }
0178         operator _V&()                { return m_v;                     }
0179         const _V* operator->() const  { return &m_v;                    }
0180         _V* operator->()              { return &m_v;                    }
0181         typename _V::iterator begin() { return m_v.begin();             }
0182         typename _V::iterator end()   { return m_v.end();               }
0183         typename _V::const_iterator begin() const { return m_v.begin(); }
0184         typename _V::const_iterator end()   const { return m_v.end();   }
0185         
0186         /// Context updates
0187         void updateContext(Geant4Context* ctxt)  {
0188           (*this)(&T::updateContext,ctxt);
0189         }
0190         /// Element access by name
0191         template <typename F> typename _V::value_type get(const F& f)  const   {
0192           if (!m_v.empty())  {
0193             typename _V::const_iterator i=std::find_if(m_v.begin(),m_v.end(),f);
0194             return i==m_v.end() ? 0 : (*i);
0195           }
0196           return 0;
0197         }
0198         /// NON-CONST actions
0199         template <typename R, typename Q> void operator()(R (Q::*pmf)()) {
0200           if ( !m_v.empty() )
0201         for (const auto& o : m_v)
0202           (o->*pmf)();
0203         }
0204         template <typename R, typename Q, typename A0> void operator()(R (Q::*pmf)(A0), A0 a0) {
0205           if ( !m_v.empty() )
0206         for (const auto& o : m_v)
0207           (o->*pmf)(a0);
0208         }
0209         template <typename R, typename Q, typename A0, typename A1> void operator()(R (Q::*pmf)(A0, A1), A0 a0, A1 a1) {
0210           if ( !m_v.empty() )
0211         for (const auto& o : m_v)
0212           (o->*pmf)(a0, a1);
0213         }
0214         /// CONST actions
0215         template <typename R, typename Q> void operator()(R (Q::*pmf)() const) const {
0216           if ( !m_v.empty() )
0217         for (const auto& o : m_v)
0218           (o->*pmf)();
0219         }
0220         template <typename R, typename Q, typename A0> void operator()(R (Q::*pmf)(A0) const, A0 a0) const {
0221           if ( !m_v.empty() )
0222         for (const auto& o : m_v)
0223           (o->*pmf)(a0);
0224         }
0225         template <typename R, typename Q, typename A0, typename A1> void operator()(R (Q::*pmf)(A0, A1) const, A0 a0, A1 a1) const {
0226       if ( !m_v.empty() )
0227         for (const auto& o : m_v)
0228           (o->*pmf)(a0, a1);
0229         }
0230         /// CONST filters
0231         template <typename Q> bool filter(bool (Q::*pmf)() const) const {
0232           if ( !m_v.empty() )
0233         for (const auto& o : m_v)
0234           if ( !(o->*pmf)() )
0235         return false;
0236           return true;
0237         }
0238         template <typename Q, typename A0> bool filter(bool (Q::*pmf)(A0) const, A0 a0) const {
0239           if ( !m_v.empty() )
0240         for (const auto& o : m_v)
0241           if ( !(o->*pmf)(a0) )
0242         return false;
0243           return true;
0244         }
0245         template <typename Q, typename A0, typename A1> bool filter(bool (Q::*pmf)(A0, A1) const, A0 a0, A1 a1) const {
0246           if ( !m_v.empty() )
0247         for (const auto& o : m_v)
0248           if ( !(o->*pmf)(a0,a1) )
0249         return false;
0250           return true;
0251         }
0252       };
0253 
0254     protected:
0255       
0256       /// Define standard assignments and constructors
0257       DDG4_DEFINE_ACTION_CONSTRUCTORS(Geant4Action);
0258 
0259       /// Default destructor
0260       virtual ~Geant4Action();
0261 
0262     public:
0263       /// Standard constructor
0264       Geant4Action(Geant4Context* context, const std::string& nam);
0265       /// Increase reference count
0266       long addRef();
0267       /// Decrease reference count. Implicit destruction
0268       long release();
0269       /// Access the context
0270       Geant4Context* context()  const {
0271         return m_context;
0272       }
0273       /// Set or update client context
0274       virtual void updateContext(Geant4Context* ctxt)  {
0275         m_context = ctxt; 
0276       }
0277       /// Set or update client for the use in a new thread fiber
0278       virtual void configureFiber(Geant4Context* thread_context);
0279       /// Access name of the action
0280       const std::string& name() const {
0281         return m_name;
0282       }
0283       /// Access name of the action
0284       const char* c_name() const {
0285         return m_name.c_str();
0286       }
0287       /// Set the object name.
0288       void setName(const std::string& new_name) {
0289         m_name = new_name;
0290       }
0291       /// Access to the properties of the object
0292       PropertyManager& properties() {
0293         return m_properties;
0294       }
0295       /// Access the output level
0296       PrintLevel outputLevel() const  {
0297         return (PrintLevel)m_outputLevel;
0298       }
0299       /// Set the output level; returns previous value
0300       PrintLevel setOutputLevel(PrintLevel new_level);
0301       /// Access to the UI messenger
0302       Geant4UIMessenger* control() const;
0303       /// Enable and install UI messenger
0304       virtual void enableUI();
0305       /// Declare property
0306       template <typename T> Geant4Action& declareProperty(const std::string& nam, T& val);
0307       /// Declare property
0308       template <typename T> Geant4Action& declareProperty(const char* nam, T& val);
0309       /// Check property for existence
0310       bool hasProperty(const std::string& name) const;
0311       /// Access single property
0312       Property& property(const std::string& name);
0313       /// Install property control messenger if wanted
0314       virtual void installMessengers();
0315       /// Install command control messenger if wanted
0316       virtual void installCommandMessenger();
0317       /// Install property control messenger if wanted
0318       virtual void installPropertyMessenger();
0319 
0320       /// Support for messages with variable output level using output level
0321       void print(const char* fmt, ...) const;
0322       /// Support for messages with variable output level using output level-1
0323       void printM1(const char* fmt, ...) const;
0324       /// Support for messages with variable output level using output level-2
0325       void printM2(const char* fmt, ...) const;
0326       /// Support for messages with variable output level using output level+1
0327       void printP1(const char* fmt, ...) const;
0328       /// Support for messages with variable output level using output level+2
0329       void printP2(const char* fmt, ...) const;
0330 
0331       /// Support of always printed messages.
0332       void always(const char* fmt, ...) const;
0333       /// Support of debug messages.
0334       void debug(const char* fmt, ...) const;
0335       /// Support of info messages.
0336       void info(const char* fmt, ...) const;
0337       /// Support of warning messages.
0338       void warning(const char* fmt, ...) const;
0339       /// Support of error messages.
0340       void error(const char* fmt, ...) const;
0341       /// Action to support error messages.
0342       bool return_error(bool return_value, const char* fmt, ...) const;
0343       /// Support of fatal messages. Throws exception
0344       void fatal(const char* fmt, ...) const;
0345       /// Support of exceptions: Print fatal message and throw runtime_error.
0346       void except(const char* fmt, ...) const;
0347 
0348       /// Abort Geant4 Run by throwing a G4Exception with type RunMustBeAborted
0349       void abortRun(const std::string& exception, const char* fmt, ...) const;
0350 
0351       /// Access to the main run action sequence from the kernel object
0352       Geant4RunActionSequence& runAction() const;
0353       /// Access to the main event action sequence from the kernel object
0354       Geant4EventActionSequence& eventAction() const;
0355       /// Access to the main stepping action sequence from the kernel object
0356       Geant4SteppingActionSequence& steppingAction() const;
0357       /// Access to the main tracking action sequence from the kernel object
0358       Geant4TrackingActionSequence& trackingAction() const;
0359       /// Access to the main stacking action sequence from the kernel object
0360       Geant4StackingActionSequence& stackingAction() const;
0361       /// Access to the main generator action sequence from the kernel object
0362       Geant4GeneratorActionSequence& generatorAction() const;
0363     };
0364 
0365     /// Declare property
0366     template <typename T> Geant4Action& Geant4Action::declareProperty(const std::string& nam, T& val) {
0367       m_properties.add(nam, val);
0368       return *this;
0369     }
0370 
0371     /// Declare property
0372     template <typename T> Geant4Action& Geant4Action::declareProperty(const char* nam, T& val) {
0373       m_properties.add(nam, val);
0374       return *this;
0375     }
0376   }    // End namespace sim
0377 }      // End namespace dd4hep
0378 
0379 #endif // DDG4_GEANT4ACTION_H