Skip to content
Snippets Groups Projects
Geant4SensDet.cpp 7.57 KiB
Newer Older
//==========================================================================
Markus Frank's avatar
Markus Frank committed
//  AIDA Detector description implementation 
//--------------------------------------------------------------------------
Markus Frank's avatar
Markus Frank committed
// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
// For the licensing terms see $DD4hepINSTALL/LICENSE.
// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
// Author     : M.Frank
//
//==========================================================================

// Framework include files
#include <DD4hep/Printout.h>
#include <DD4hep/Primitives.h>
#include <DD4hep/InstanceCount.h>
#include <DDG4/Geant4Kernel.h>
#include <DDG4/Geant4Context.h>
#include <DDG4/Geant4HitCollection.h>
#include <DDG4/Geant4SensDetAction.h>
#include <G4VSensitiveDetector.hh>
#include <G4VGFlashSensitiveDetector.hh>
#include <G4VFastSimSensitiveDetector.hh>
#include <G4Event.hh>
#include <G4Run.hh>
/// Namespace for the AIDA detector description toolkit
Markus Frank's avatar
Markus Frank committed
namespace dd4hep {
  /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
Markus Frank's avatar
Markus Frank committed
  namespace sim {
    /// Private helper to support sequence reference counting
    /**
     *  \author  M.Frank
     *  \version 1.0
     *  \ingroup DD4HEP_SIMULATION
     */
    template <typename T> class RefCountedSequence  {
    public:
Markus Frank's avatar
Markus Frank committed
      T* m_sequence;
      /// Default constructor
Markus Frank's avatar
Markus Frank committed
      RefCountedSequence() : m_sequence(0) {                 }
      /// Initializing constructor
Markus Frank's avatar
Markus Frank committed
      RefCountedSequence(T* seq)           {   _aquire(seq); }
      /// Default destructor
Markus Frank's avatar
Markus Frank committed
      virtual ~RefCountedSequence()        { _release();     }
      void _aquire(T* s)  {
        InstanceCount::increment(this);
        m_sequence = s;
        m_sequence->addRef();
Markus Frank's avatar
Markus Frank committed
      }
      void _release()  {
Markus Frank's avatar
Markus Frank committed
        detail::releasePtr(m_sequence);
Markus Frank's avatar
Markus Frank committed
      }
    };
    /// Concrete implementation of the G4VSensitiveDetector calling the registered sequence object
    /**
     *  \author  M.Frank
     *  \version 1.0
     *  \ingroup DD4HEP_SIMULATION
     */
    class Geant4SensDet : virtual public G4VSensitiveDetector,
			  virtual public G4VGFlashSensitiveDetector,
			  virtual public G4VFastSimSensitiveDetector,
                          virtual public G4VSDFilter,
                          virtual public Geant4ActionSD,
                          virtual public RefCountedSequence<Geant4SensDetActionSequence>
    protected:
      /// Access to the geant4 sensitive detector handle
      SensitiveDetector m_sensitive;
    public:
      /// Constructor. The detector element is identified by the name
Markus Frank's avatar
Markus Frank committed
      Geant4SensDet(const std::string& nam, Detector& description)
        : G4VSensitiveDetector(nam),
	  G4VGFlashSensitiveDetector(),
	  G4VSDFilter(nam),
          Geant4Action(0,nam),
	  Geant4ActionSD(nam),
Markus Frank's avatar
Markus Frank committed
          RefCountedSequence<Geant4SensDetActionSequence>()
Markus Frank's avatar
Markus Frank committed
        Geant4Kernel& master = Geant4Kernel::instance(description);
        Geant4Kernel& kernel = master.worker(Geant4Kernel::thread_self());
Markus Frank's avatar
Markus Frank committed
        m_sensitive   = description.sensitiveDetector(nam);
        m_outputLevel = kernel.getOutputLevel(nam);
        _aquire(kernel.sensitiveAction(nam));
        m_sequence->defineCollections(this);
        this->G4VSensitiveDetector::SetFilter(this);
      virtual ~Geant4SensDet() = default;
      /// Overload to avoid ambiguity between G4VSensitiveDetector and G4VSDFilter
      {  return this->G4VSensitiveDetector::SensitiveDetectorName;      }
      /// G4VSensitiveDetector internals: Access to the detector path name
      virtual std::string path()  const  override  final
      {  return this->G4VSensitiveDetector::GetPathName();              }
      /// G4VSensitiveDetector internals: Access to the detector path name
      virtual std::string fullPath()  const  override  final
      {  return this->G4VSensitiveDetector::GetFullPathName();          }
      /// Is the detector active?
      virtual bool isActive() const  override
      {  return this->G4VSensitiveDetector::isActive();                 }
      /// This is a utility method which returns the hits collection ID
      virtual G4int GetCollectionID(G4int i)  override  final
      {  return this->G4VSensitiveDetector::GetCollectionID(i);         }
      /// Access to the readout geometry of the sensitive detector
      virtual G4VReadOutGeometry* readoutGeometry() const  override
      {  return this->G4VSensitiveDetector::GetROgeometry();            }
Markus Frank's avatar
Markus Frank committed
      /// Access to the Detector sensitive detector handle
      virtual SensitiveDetector sensitiveDetector() const  override  final
      {  return m_sensitive;                                            }
      /// Access to the sensitive type of the detector
      virtual const std::string& sensitiveType() const  override  final
      {  return m_sequence->sensitiveType();                            }
      /// Callback if the sequence should be accepted or filtered off
      virtual G4bool Accept(const G4Step* step) const  override  final
      {  return m_sequence->accept(step);                               }
      /// Method invoked at the begining of each event.
      virtual void Initialize(G4HCofThisEvent* hce)  override  final
      /// Method invoked at the end of each event.
      virtual void EndOfEvent(G4HCofThisEvent* hce)  override  final
      /// Method for generating hit(s) using the information of G4Step object.
      virtual G4bool ProcessHits(G4Step* step,
				 G4TouchableHistory* hist)   override  final
      {  return m_sequence->process(step,hist);                         }
Markus Frank's avatar
Markus Frank committed
      /// GFLASH interface
      virtual G4bool ProcessHits(G4GFlashSpot* sp,
				 G4TouchableHistory* hist)   override final
      {
	const GFlashEnergySpot* esp = sp->GetEnergySpot();
	G4FastHit         hit(esp->GetPosition(), esp->GetEnergy());
	Geant4FastSimSpot spot(&hit, sp->GetOriginatorTrack(), (sp->GetTouchableHandle())());
	return m_sequence->processFastSim(&spot, hist);
      }
      /// Geant4 Fast simulation interface
      virtual G4bool ProcessHits(const G4FastHit* hit,
				 const G4FastTrack* track,
				 G4TouchableHistory* hist)   override final
      {
	Geant4FastSimSpot spot(hit, track, hist);
	return m_sequence->processFastSim(&spot, hist);
      }
      /// G4VSensitiveDetector interface: Method invoked if the event was aborted.
      virtual void clear()  override
      {  m_sequence->clear();                                           }
      /// Initialize the usage of a hit collection. Returns the collection identifier
      virtual size_t defineCollection(const std::string& coll)   override  {
        if ( coll.empty() ) {
          except("Geant4Sensitive: No collection defined for %s [Invalid name]",c_name());
        }
        collectionName.emplace_back(coll);
Markus Frank's avatar
Markus Frank committed
  }    // End namespace sim
}      // End namespace dd4hep
#include <DDG4/Factories.h>
Markus Frank's avatar
Markus Frank committed
typedef dd4hep::sim::Geant4SensDet Geant4SensDet;
typedef dd4hep::sim::Geant4SensDet Geant4tracker;
typedef dd4hep::sim::Geant4SensDet Geant4calorimeter;

DECLARE_GEANT4SENSITIVEDETECTOR(Geant4SensDet)
DECLARE_GEANT4SENSITIVEDETECTOR(Geant4tracker)
DECLARE_GEANT4SENSITIVEDETECTOR(Geant4calorimeter)