Newer
Older
Markus Frank
committed
//==========================================================================
Markus Frank
committed
//--------------------------------------------------------------------------
// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
Markus Frank
committed
// All rights reserved.
Markus Frank
committed
// For the licensing terms see $DD4hepINSTALL/LICENSE.
// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
Markus Frank
committed
// 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>
Markus Frank
committed
#include <DDG4/Geant4FastSimSpot.h>
#include <DDG4/Geant4HitCollection.h>
#include <DDG4/Geant4SensDetAction.h>
Markus Frank
committed
// Geant4 include files
Markus Frank
committed
#include <G4TouchableHistory.hh>
#include <G4VSensitiveDetector.hh>
#include <G4VGFlashSensitiveDetector.hh>
Markus Frank
committed
#include <G4VFastSimSensitiveDetector.hh>
#include <G4Event.hh>
#include <G4Run.hh>
/// Namespace for the AIDA detector description toolkit
/// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
/// Private helper to support sequence reference counting
/**
* \author M.Frank
* \version 1.0
* \ingroup DD4HEP_SIMULATION
*/
template <typename T> class RefCountedSequence {
public:
virtual ~RefCountedSequence() { _release(); }
void _aquire(T* s) {
Markus Frank
committed
InstanceCount::increment(this);
m_sequence = s;
m_sequence->addRef();
Markus Frank
committed
InstanceCount::decrement(this);
/// Concrete implementation of the G4VSensitiveDetector calling the registered sequence object
/**
* \author M.Frank
* \version 1.0
* \ingroup DD4HEP_SIMULATION
*/
Markus Frank
committed
class Geant4SensDet : virtual public G4VSensitiveDetector,
virtual public G4VGFlashSensitiveDetector,
Markus Frank
committed
virtual public G4VFastSimSensitiveDetector,
Markus Frank
committed
virtual public G4VSDFilter,
virtual public Geant4ActionSD,
virtual public RefCountedSequence<Geant4SensDetActionSequence>
protected:
/// Access to the geant4 sensitive detector handle
SensitiveDetector m_sensitive;
/// Constructor. The detector element is identified by the name
Geant4SensDet(const std::string& nam, Detector& description)
: G4VSensitiveDetector(nam),
G4VGFlashSensitiveDetector(),
Markus Frank
committed
G4VFastSimSensitiveDetector(),
G4VSDFilter(nam),
Geant4Action(0,nam),
Geant4ActionSD(nam),
RefCountedSequence<Geant4SensDetActionSequence>()
Geant4Kernel& master = Geant4Kernel::instance(description);
Geant4Kernel& kernel = master.worker(Geant4Kernel::thread_self());
m_sensitive = description.sensitiveDetector(nam);
Markus Frank
committed
m_context = kernel.workerContext();
Markus Frank
committed
m_outputLevel = kernel.getOutputLevel(nam);
_aquire(kernel.sensitiveAction(nam));
m_sequence->defineCollections(this);
Markus Frank
committed
m_sequence->updateContext(m_context);
Markus Frank
committed
this->G4VSensitiveDetector::SetFilter(this);
/// Overload to avoid ambiguity between G4VSensitiveDetector and G4VSDFilter
Markus Frank
committed
inline G4String GetName() const
{ return this->G4VSensitiveDetector::SensitiveDetectorName; }
/// G4VSensitiveDetector internals: Access to the detector path name
Markus Frank
committed
virtual std::string path() const override final
{ return this->G4VSensitiveDetector::GetPathName(); }
/// G4VSensitiveDetector internals: Access to the detector path name
Markus Frank
committed
virtual std::string fullPath() const override final
{ return this->G4VSensitiveDetector::GetFullPathName(); }
/// Is the detector active?
virtual bool isActive() const override
{ return this->G4VSensitiveDetector::isActive(); }
Markus Frank
committed
/// This is a utility method which returns the hits collection ID
Markus Frank
committed
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(); }
/// Access to the Detector sensitive detector handle
Markus Frank
committed
virtual SensitiveDetector sensitiveDetector() const override final
{ return m_sensitive; }
/// Access to the sensitive type of the detector
Markus Frank
committed
virtual const std::string& sensitiveType() const override final
{ return m_sequence->sensitiveType(); }
/// Callback if the sequence should be accepted or filtered off
Markus Frank
committed
virtual G4bool Accept(const G4Step* step) const override final
{ return m_sequence->accept(step); }
Markus Frank
committed
/// Method invoked at the begining of each event.
Markus Frank
committed
virtual void Initialize(G4HCofThisEvent* hce) override final
Markus Frank
committed
{ m_sequence->begin(hce); }
Markus Frank
committed
/// Method invoked at the end of each event.
Markus Frank
committed
virtual void EndOfEvent(G4HCofThisEvent* hce) override final
Markus Frank
committed
{ m_sequence->end(hce); }
/// Method for generating hit(s) using the information of G4Step object.
Markus Frank
committed
virtual G4bool ProcessHits(G4Step* step,
G4TouchableHistory* hist) override final
{ return m_sequence->process(step,hist); }
Markus Frank
committed
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.
{ m_sequence->clear(); }
/// Initialize the usage of a hit collection. Returns the collection identifier
virtual size_t defineCollection(const std::string& coll) override {
Markus Frank
committed
if ( coll.empty() ) {
except("Geant4Sensitive: No collection defined for %s [Invalid name]",c_name());
}
collectionName.emplace_back(coll);
Markus Frank
committed
return collectionName.size()-1;
} // End namespace sim
} // End namespace dd4hep
typedef dd4hep::sim::Geant4SensDet Geant4SensDet;
typedef dd4hep::sim::Geant4SensDet Geant4tracker;
typedef dd4hep::sim::Geant4SensDet Geant4calorimeter;
DECLARE_GEANT4SENSITIVEDETECTOR(Geant4SensDet)
DECLARE_GEANT4SENSITIVEDETECTOR(Geant4tracker)
DECLARE_GEANT4SENSITIVEDETECTOR(Geant4calorimeter)