Back to home page

EIC code displayed by LXR

 
 

    


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

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_GEANT4SENSDETACTION_H
0014 #define DDG4_GEANT4SENSDETACTION_H
0015 
0016 // Framework include files
0017 #include <DD4hep/Detector.h>
0018 #include <DDG4/Geant4Action.h>
0019 #include <DDG4/Geant4HitCollection.h>
0020 
0021 // Geant4 include files
0022 #include <G4ThreeVector.hh>
0023 #include <G4VTouchable.hh>
0024 
0025 // C/C++ include files
0026 #include <vector>
0027 
0028 // Forward declarations
0029 class G4HCofThisEvent;
0030 class G4Step;
0031 class G4Event;
0032 class G4TouchableHistory;
0033 class G4VHitsCollection;
0034 class G4VReadOutGeometry;
0035 
0036 /// Namespace for the AIDA detector description toolkit
0037 namespace dd4hep {
0038 
0039   // Forward declarations
0040   class Detector;
0041   class DetElement;
0042   class SensitiveDetector;
0043 
0044   /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
0045   namespace sim {
0046 
0047     // Forward declarations
0048     class Geant4Sensitive;
0049     class Geant4FastSimSpot;
0050     class Geant4StepHandler;
0051     class Geant4HitCollection;
0052     class Geant4SensDetActionSequence;
0053     class Geant4SensDetSequences;
0054 
0055     /// Interface class to access properties of the underlying Geant4 sensitive detector structure
0056     /**
0057      *  \author  M.Frank
0058      *  \version 1.0
0059      *  \ingroup DD4HEP_SIMULATION
0060      */
0061     class Geant4ActionSD: virtual public Geant4Action {
0062     protected:
0063       /// Define standard assignments and constructors
0064       DDG4_DEFINE_ACTION_CONSTRUCTORS(Geant4ActionSD);
0065       /// Standard action constructor
0066       Geant4ActionSD(const std::string& name);
0067       /// Default destructor
0068       virtual ~Geant4ActionSD();
0069     public:
0070       /// Initialize the usage of a hit collection. Returns the collection identifier
0071       virtual std::size_t defineCollection(const std::string& name) = 0;
0072       /// Access to the readout geometry of the sensitive detector
0073       virtual G4VReadOutGeometry* readoutGeometry() const = 0;
0074       /// This is a utility method which returns the hits collection ID
0075       virtual G4int GetCollectionID(G4int i) = 0;
0076       /// Is the detector active?
0077       virtual bool isActive() const = 0;
0078       /// Access to the Detector sensitive detector handle
0079       virtual SensitiveDetector sensitiveDetector() const = 0;
0080       /// G4VSensitiveDetector internals: Access to the detector path name
0081       virtual std::string path() const = 0;
0082       /// G4VSensitiveDetector internals: Access to the detector path name
0083       virtual std::string fullPath() const = 0;
0084       /// Access to the sensitive type of the detector
0085       virtual const std::string& sensitiveType() const = 0;
0086     };
0087 
0088     /// Base class to construct filters for Geant4 sensitive detectors
0089     /**
0090      *  \author  M.Frank
0091      *  \version 1.0
0092      *  \ingroup DD4HEP_SIMULATION
0093      */
0094     class Geant4Filter: public Geant4Action {
0095     protected:
0096       /// Define standard assignments and constructors
0097       DDG4_DEFINE_ACTION_CONSTRUCTORS(Geant4Filter);
0098 
0099     public:
0100       /// Standard constructor
0101       Geant4Filter(Geant4Context* context, const std::string& name);
0102       /// Standard destructor
0103       virtual ~Geant4Filter();
0104 
0105       /// Filter action. Return true if hits should be processed. Default returns true
0106       virtual bool operator()(const G4Step* step) const;
0107 
0108       /// GFLASH/FastSim interface: Filter action. Return true if hits should be processed.
0109       /** The default implementation throws an exception that the 
0110        *  GFLASH / FastSim interface is not implemented.
0111        */
0112       virtual bool operator()(const Geant4FastSimSpot* spot) const;
0113     };
0114 
0115     /// The base class for Geant4 sensitive detector actions implemented by users
0116     /**
0117      *  \author  M.Frank
0118      *  \version 1.0
0119      *  \ingroup DD4HEP_SIMULATION
0120      */
0121     class Geant4Sensitive: public Geant4Action {
0122     public:
0123       enum HitCreationFlags {
0124         SIMPLE_MODE = 0,
0125         MEDIUM_MODE = 1<<0,
0126         DETAILED_MODE = 1<<1
0127       };
0128 
0129     private:
0130       /// Reference to G4 sensitive detector
0131       Geant4ActionSD* m_sensitiveDetector     { nullptr };
0132       /// Reference to the containing action sequence
0133       Geant4SensDetActionSequence* m_sequence { nullptr };
0134 
0135     protected:
0136       /// Property: Hit creation mode. Maybe one of the enum HitCreationFlags
0137       int  m_hitCreationMode = 0;
0138 #if defined(G__ROOT) || defined(__CLING__) || defined(__ROOTCLING__)
0139       /// Reference to the detector description object
0140       Detector*            m_detDesc          { nullptr };
0141 #else
0142       /// Reference to the detector description object
0143       Detector&            m_detDesc;
0144 #endif
0145       /// Reference to the detector element describing this sensitive element
0146       DetElement           m_detector         {  };
0147       /// Reference to the sensitive detector element
0148       SensitiveDetector    m_sensitive        {  };
0149       /// Reference to the readout structure
0150       Readout              m_readout          {  };
0151       /// Reference to segmentation
0152       Segmentation         m_segmentation     {  };
0153       /// The list of sensitive detector filter objects
0154       Actors<Geant4Filter> m_filters;
0155 
0156       /// Define standard assignments and constructors
0157       DDG4_DEFINE_ACTION_CONSTRUCTORS(Geant4Sensitive);
0158 
0159     public:
0160       /// Constructor. The sensitive detector element is identified by the detector name
0161       Geant4Sensitive(Geant4Context* context, const std::string& name, DetElement det, Detector& description);
0162 
0163       /// Standard destructor
0164       virtual ~Geant4Sensitive();
0165 
0166       /// Access to the sensitive detector object
0167       Geant4ActionSD& detector() const;
0168 
0169       /// Access to the sensitive detector object
0170       void setDetector(Geant4ActionSD* sens_det);
0171 
0172       /// Property access to the hit creation mode
0173       int hitCreationMode() const  {
0174         return m_hitCreationMode;
0175       }
0176 
0177       /// G4VSensitiveDetector internals: Access to the detector name
0178       std::string detectorName() const {
0179         return detector().name();
0180       }
0181 
0182       /// G4VSensitiveDetector internals: Access to the detector path name
0183       std::string path() const {
0184         return detector().path();
0185       }
0186 
0187       /// G4VSensitiveDetector internals: Access to the detector path name
0188       std::string fullPath() const {
0189         return detector().fullPath();
0190       }
0191 
0192       /// G4VSensitiveDetector internals: Is the detector active?
0193       bool isActive() const {
0194         return detector().isActive();
0195       }
0196 
0197       /// Access the dd4hep sensitive detector
0198       SensitiveDetector sensitiveDetector() const  {
0199         return m_sensitive;
0200       }
0201 
0202       /// Access to the readout geometry of the sensitive detector
0203       G4VReadOutGeometry* readoutGeometry() const {
0204         return detector().readoutGeometry();
0205       }
0206 
0207       /// Access the detector desciption object
0208       Detector& detectorDescription()   const;
0209 
0210       /// Mark the track to be kept for MC truth propagation during hit processing
0211       void mark(const G4Track* track) const;
0212 
0213       /// Mark the track of this step to be kept for MC truth propagation during hit processing
0214       void mark(const G4Step* step) const;
0215 
0216       /// Access to the hosting sequence
0217       Geant4SensDetActionSequence& sequence() const;
0218 
0219       /// Add an actor responding to all callbacks. Sequence takes ownership.
0220       void adopt(Geant4Filter* filter);
0221 
0222       /// Add an actor responding to all callbacks to the sequence front. Sequence takes ownership.
0223       void adopt_front(Geant4Filter* filter);
0224 
0225       /// Add an actor responding to all callbacks. Sequence takes ownership.
0226       void adoptFilter(Geant4Action* filter);
0227 
0228       /// Add an actor responding to all callbacks to the sequence front. Sequence takes ownership.
0229       void adoptFilter_front(Geant4Action* filter);
0230 
0231       /// Callback before hit processing starts. Invoke all filters.
0232       /** Return false if any filter returns false
0233        */
0234       bool accept(const G4Step* step) const;
0235 
0236       /// GFLASH/FastSim interface: Callback before hit processing starts. Invoke all filters.
0237       /** Return false if any filter returns false
0238        */
0239       bool accept(const Geant4FastSimSpot* step) const;
0240 
0241       /// Initialize the usage of a single hit collection. Returns the collection ID
0242       template <typename TYPE> std::size_t defineCollection(const std::string& coll_name);
0243 
0244       /// Access HitCollection container names
0245       const std::string& hitCollectionName(std::size_t which) const;
0246 
0247       /// Retrieve the hits collection associated with this detector by its serial number
0248       Geant4HitCollection* collection(std::size_t which);
0249 
0250       /// Retrieve the hits collection associated with this detector by its collection identifier
0251       Geant4HitCollection* collectionByID(std::size_t id);
0252 
0253       /// Define collections created by this sensitivie action object
0254       virtual void defineCollections();
0255 
0256       /// G4VSensitiveDetector interface: Method invoked at the begining of each event.
0257       /** The hits collection(s) created by this sensitive detector must
0258        *  be set to the G4HCofThisEvent object at one of these two methods.
0259        */
0260       virtual void begin(G4HCofThisEvent* hce);
0261 
0262       /// G4VSensitiveDetector interface: Method invoked at the end of each event.
0263       virtual void end(G4HCofThisEvent* hce);
0264 
0265       /// G4VSensitiveDetector interface: Method invoked if the event was aborted.
0266       /** Hits collections created but not being set to G4HCofThisEvent
0267        *  at the event should be deleted.
0268        *  Collection(s) which have already set to G4HCofThisEvent
0269        *  will be deleted automatically.
0270        */
0271       virtual void clear(G4HCofThisEvent* hce);
0272 
0273       /// Returns the volumeID of the sensitive volume corresponding to the step
0274       /** Combining the VolIDS of the complete geometry path (Geant4TouchableHistory)
0275        * from the current sensitive volume to the world volume
0276        */
0277       long long int volumeID(const G4Step* step);
0278 
0279       /// Returns the volumeID of the sensitive volume corresponding to the G4VTouchable
0280       /** Combining the VolIDS of the complete geometry path (Geant4TouchableHistory)
0281        * from the current sensitive volume to the world volume
0282        */
0283       long long int volumeID(const G4VTouchable* touchable);
0284 
0285       /// Returns the cellID of the sensitive volume corresponding to the step
0286       /** The CellID is the VolumeID + the local coordinates of the sensitive area.
0287        *  Calculated by combining the VolIDS of the complete geometry path (Geant4TouchableHistory)
0288        *  from the current sensitive volume to the world volume
0289        */
0290       long long int cellID(const G4Step* step);
0291 
0292       /// Returns the cellID of the sensitive volume corresponding to the G4VTouchable
0293       /** The CellID is the VolumeID + the local coordinates of the sensitive area.
0294        *  Calculated by combining the VolIDS of the complete geometry path (Geant4TouchableHistory)
0295        *  from the current sensitive volume to the world volume
0296        */
0297       long long int cellID(const G4VTouchable* touchable, const G4ThreeVector& global);
0298 
0299       /// G4VSensitiveDetector interface: Method for generating hit(s) using the information of G4Step object.
0300       virtual bool process(const G4Step* step, G4TouchableHistory* history);
0301 
0302       /// GFLASH/FastSim interface: Method for generating hit(s) using the information of the fast simulation spot object.
0303       /** The default implementation throws an exception that the 
0304        *  GFLASH/FastSim interface is not implemented.
0305        */
0306       virtual bool processFastSim(const Geant4FastSimSpot* spot, G4TouchableHistory* history);
0307     };
0308 
0309     /// The sequencer to host Geant4 sensitive actions called if particles interact with sensitive elements
0310     /**
0311      * Concrete implementation of the sensitive detector action sequence
0312      *
0313      *  \author  M.Frank
0314      *  \version 1.0
0315      *  \ingroup DD4HEP_SIMULATION
0316      */
0317     class Geant4SensDetActionSequence: public Geant4Action {
0318     public:
0319       typedef Geant4HitCollection* (*create_t)(const std::string&, const std::string&, Geant4Sensitive*);
0320       typedef std::pair<std::string, std::pair<Geant4Sensitive*,create_t> > HitCollection;
0321       typedef std::vector<HitCollection> HitCollections;
0322 
0323     protected:
0324       /// Geant4 hit collection context
0325       G4HCofThisEvent* m_hce = 0;
0326       /// Callback sequence for event initialization action
0327       CallbackSequence m_begin;
0328       /// Callback sequence for event finalization action
0329       CallbackSequence m_end;
0330       /// Callback sequence for step processing
0331       CallbackSequence m_process;
0332       /// Callback sequence to invoke the event deletion
0333       CallbackSequence m_clear;
0334       /// The list of sensitive detector objects
0335       Actors<Geant4Sensitive> m_actors;
0336       /// The list of sensitive detector filter objects
0337       Actors<Geant4Filter>    m_filters;
0338 
0339       /// Hit collection creators
0340       HitCollections m_collections;
0341       /// Reference to the sensitive detector element
0342       SensitiveDetector m_sensitive;
0343       /// Reference to G4 sensitive detector
0344       Geant4ActionSD* m_detector;
0345       /// The true sensitive type of the detector
0346       std::string m_sensitiveType;
0347       /// Create a new typed hit collection
0348       template <typename TYPE> static 
0349       Geant4HitCollection* _create(const std::string& det, const std::string& coll, Geant4Sensitive* sd) {
0350         return new Geant4HitCollection(det, coll, sd, (TYPE*) 0);
0351       }
0352 
0353     protected:
0354       /// Define standard assignments and constructors
0355       DDG4_DEFINE_ACTION_CONSTRUCTORS(Geant4SensDetActionSequence);
0356 
0357     public:
0358       /// Standard constructor
0359       Geant4SensDetActionSequence(Geant4Context* context, const std::string& name);
0360 
0361       /// Default destructor
0362       virtual ~Geant4SensDetActionSequence();
0363 
0364       /// Access to the sensitive type of the detector
0365       virtual const std::string& sensitiveType() const   {
0366         return m_sensitiveType;
0367       }
0368 
0369       /// Set or update client context
0370       virtual void updateContext(Geant4Context* ctxt)  override;
0371 
0372       /// Called at construction time of the sensitive detector to declare all hit collections
0373       std::size_t defineCollections(Geant4ActionSD* sens_det);
0374 
0375       /// Initialize the usage of a hit collection. Returns the collection identifier
0376       std::size_t defineCollection(Geant4Sensitive* owner, const std::string& name, create_t func);
0377 
0378       /// Define a named collection containing hist of a specified type
0379       template <typename TYPE> std::size_t defineCollection(Geant4Sensitive* owner, const std::string& coll_name) {
0380         return defineCollection(owner, coll_name, Geant4SensDetActionSequence::_create<TYPE>);
0381       }
0382 
0383       /// Access HitCollection container names
0384       const std::string& hitCollectionName(std::size_t which) const;
0385 
0386       /// Retrieve the hits collection associated with this detector by its serial number
0387       Geant4HitCollection* collection(std::size_t which) const;
0388 
0389       /// Retrieve the hits collection associated with this detector by its collection identifier
0390       Geant4HitCollection* collectionByID(std::size_t id) const;
0391 
0392       /// Register begin-of-event callback
0393       template <typename T> void callAtBegin(T* p, void (T::*f)(G4HCofThisEvent*)) {
0394         m_begin.add(p, f);
0395       }
0396 
0397       /// Register end-of-event callback
0398       template <typename T> void callAtEnd(T* p, void (T::*f)(G4HCofThisEvent*)) {
0399         m_end.add(p, f);
0400       }
0401 
0402       /// Register process-hit callback
0403       template <typename T> void callAtProcess(T* p, void (T::*f)(G4Step*, G4TouchableHistory*)) {
0404         m_process.add(p, f);
0405       }
0406 
0407       /// Register clear callback
0408       template <typename T> void callAtClear(T* p, void (T::*f)(G4HCofThisEvent*)) {
0409         m_clear.add(p, f);
0410       }
0411 
0412       /// Add an actor responding to all callbacks. Sequence takes ownership.
0413       void adopt(Geant4Sensitive* sensitive);
0414 
0415       /// Add an actor responding to all callbacks. Sequence takes ownership.
0416       void adopt(Geant4Filter* filter);
0417 
0418       /// Add an actor responding to all callbacks. Sequence takes ownership.
0419       void adoptFilter(Geant4Action* filter);
0420 
0421       /// Callback before hit processing starts. Invoke all filters.
0422       bool accept(const G4Step* step) const;
0423 
0424       /// GFLASH/FastSim interface: Callback before hit processing starts. Invoke all filters.
0425       bool accept(const Geant4FastSimSpot* step) const;
0426 
0427       /// G4VSensitiveDetector interface: Method invoked at the begining of each event.
0428       /** The hits collection(s) created by this sensitive detector must
0429        *  be set to the G4HCofThisEvent object at one of these two methods.
0430        */
0431       virtual void begin(G4HCofThisEvent* hce);
0432 
0433       /// G4VSensitiveDetector interface: Method invoked at the end of each event.
0434 
0435       virtual void end(G4HCofThisEvent* hce);
0436       /// G4VSensitiveDetector interface: Method invoked if the event was aborted.
0437       /** Hits collections created but not beibg set to G4HCofThisEvent
0438        *  at the event should be deleted.
0439        *  Collection(s) which have already set to G4HCofThisEvent
0440        *  will be deleted automatically.
0441        */
0442       virtual void clear();
0443 
0444       /// G4VSensitiveDetector interface: Method for generating hit(s) using the information of G4Step object.
0445       virtual bool process(const G4Step* step, G4TouchableHistory* history);
0446 
0447       /// GFLASH/FastSim interface: Method for generating hit(s) using the information of the fast simulation spot object.
0448       virtual bool processFastSim(const Geant4FastSimSpot* spot, G4TouchableHistory* history);
0449     };
0450 
0451     /// Geant4SensDetSequences: class to access groups of sensitive actions
0452     /**
0453      * Concrete implementation of the sensitive detector action sequence
0454      *
0455      * Note Multi-Threading issue:
0456      * Neither callbacks not the action list is protected against multiple 
0457      * threads calling the Geant4 callbacks!
0458      * These must be protected in the user actions themselves.
0459      *
0460      *  \author  M.Frank
0461      *  \version 1.0
0462      *  \ingroup DD4HEP_SIMULATION
0463      */
0464     class Geant4SensDetSequences {
0465     public:
0466       friend class Geant4ActionContainer;
0467       friend class Geant4SensDetActionSequence;
0468       typedef std::map<std::string, Geant4SensDetActionSequence*> Members;
0469     private:
0470       Members m_sequences;
0471       /// Insert sequence member
0472       void insert(const std::string& name, Geant4SensDetActionSequence* seq);
0473 
0474     public:
0475       /// Default constructor
0476       Geant4SensDetSequences() = default;
0477       /// Default destructor
0478       virtual ~Geant4SensDetSequences();
0479       /// Access sequence member by name
0480       Geant4SensDetActionSequence* operator[](const std::string& name) const;
0481       /// Access sequence member by name
0482       Geant4SensDetActionSequence* find(const std::string& name) const;
0483       /// Access to the members
0484       Members& sequences() {
0485         return m_sequences;
0486       }
0487       /// Access to the members CONST
0488       const Members& sequences() const {
0489         return m_sequences;
0490       }
0491       /// Clear the sequence list
0492       void clear();
0493     };
0494 
0495     /// Initialize the usage of a single hit collection. Returns the collection ID
0496     template <typename TYPE> inline std::size_t Geant4Sensitive::defineCollection(const std::string& coll_name) {
0497       return sequence().defineCollection<TYPE>(this, coll_name);
0498     }
0499 
0500     /// Template class to ease the construction of sensitive detectors using particle template specialization
0501     /**
0502      * Templated implementation to realize sensitive detectors.
0503      * Default implementations for all functions are provided in the file
0504      * DDG4/Geant4SensDetAction.inl.
0505      *
0506      * Users may override any of the templated callbacks or the of the virtual functions
0507      * of the base class using explicit template specialization.
0508      * An example may be found in DDG4/plugins/Geant4SDActions.
0509      *
0510      *  \author  M.Frank
0511      *  \version 1.0
0512      *  \ingroup DD4HEP_SIMULATION
0513      */
0514     template <typename T> class Geant4SensitiveAction : public Geant4Sensitive  {
0515     public:
0516       typedef T UserData;
0517     protected:
0518       /// Property: collection name. If not set default is readout name!
0519       std::string m_collectionName    { };
0520       /// Property: segmentation name for parallel readouts. If not set readout segmentation is used!
0521       std::string m_readoutName       { };
0522 
0523       /// Collection identifier
0524       std::size_t m_collectionID    { 0 };
0525       /// User data block
0526       UserData    m_userData          { };
0527 
0528     protected:
0529       /// Define standard assignments and constructors
0530       DDG4_DEFINE_ACTION_CONSTRUCTORS(Geant4SensitiveAction);
0531 
0532     public:
0533       /// Standard , initializing constructor
0534       Geant4SensitiveAction(Geant4Context* context,
0535                             const std::string& name,
0536                             DetElement det,
0537                             Detector& description);
0538 
0539       /// Default destructor
0540       virtual ~Geant4SensitiveAction();
0541 
0542       /// Declare optional properties from embedded structure
0543       void declareOptionalProperties();
0544 
0545       /// Define collections created by this sensitivie action object
0546       virtual void defineCollections();
0547 
0548       /// Access the readout object. Note: if m_readoutName is set, the m_readout != m_sensitive.readout()
0549       Readout readout();
0550       
0551       /// Define readout specific hit collection with volume ID filtering
0552       /** 
0553        *  Convenience function. To be called by specialized sensitive actions inheriting this class.
0554        *
0555        *  - If the property CollectionName ist NOT set, one default collection is declared,
0556        *    with the readout name as the collection name.
0557        *  - If the property CollectionName is set, the readout structure is searched for
0558        *    the corresponding entry and a collection with the corrsponding name is declared.
0559        *    At the same time a VolumeID filter is injected at the front of the sensitive's 
0560        *    filter queue to ONLY act on volume IDs matching this criterium.
0561        */
0562       template <typename HIT> std::size_t declareReadoutFilteredCollection();
0563 
0564       /// Define readout specific hit collection. matching name must be present in readout structure
0565       template <typename HIT> 
0566       std::size_t defineReadoutCollection(const std::string collection_name);
0567 
0568       /// Initialization overload for specialization
0569       virtual void initialize()  final;
0570       /// Finalization overload for specialization
0571       virtual void finalize()  final;
0572 
0573       /// G4VSensitiveDetector interface: Method invoked at the begining of each event.
0574       virtual void begin(G4HCofThisEvent* hce)  final;
0575       /// G4VSensitiveDetector interface: Method invoked at the end of each event.
0576       virtual void end(G4HCofThisEvent* hce)  final;
0577       /// G4VSensitiveDetector interface: Method invoked if the event was aborted.
0578       virtual void clear(G4HCofThisEvent* hce)  final;
0579 
0580       /// G4VSensitiveDetector interface: Method for generating hit(s) using the G4Step object.
0581       virtual bool process(const G4Step* step,G4TouchableHistory* history)  final;
0582 
0583       /// GFLASH/FastSim interface: Method for generating hit(s) using the information of the fast simulation spot object.
0584       virtual bool processFastSim(const Geant4FastSimSpot* spot, G4TouchableHistory* history)  final;
0585     };
0586 
0587   }    // End namespace sim
0588 }      // End namespace dd4hep
0589 #endif // DDG4_GEANT4SENSDETACTION_H