From a732b835fa571ba5db47e29da7d05c2eea7339b2 Mon Sep 17 00:00:00 2001 From: Markus FRANK <Markus.Frank@cern.ch> Date: Thu, 15 Apr 2021 14:12:00 +0200 Subject: [PATCH] Prepare for GFlash parametrization. Remove DDG4 legacy stuff. --- DDG4/CMakeLists.txt | 6 +- DDG4/include/DDG4/Geant4Data.h | 9 +- DDG4/include/DDG4/Geant4GFlashSpotHandler.h | 179 +++++++++++++ DDG4/include/DDG4/Geant4ReadoutVolumeFilter.h | 2 + DDG4/include/DDG4/Geant4SensDetAction.h | 48 +++- DDG4/include/DDG4/Geant4SensDetAction.inl | 5 + DDG4/include/DDG4/Geant4SensitiveDetector.h | 177 ------------- .../DDG4/Geant4SensitiveDetector_inline.h | 59 ----- DDG4/legacy/Geant4CalorimeterSD.cpp | 132 ---------- DDG4/legacy/Geant4TrackerCombineSD.cpp | 127 ---------- DDG4/legacy/Geant4TrackerSD.cpp | 77 ------ DDG4/plugins/Geant4SDActions.cpp | 199 +++++++++++++-- DDG4/plugins/Geant4SensDetFilters.cpp | 68 +++-- DDG4/src/Geant4Converter.cpp | 5 +- DDG4/src/Geant4Data.cpp | 9 + DDG4/src/Geant4GFlashSpotHandler.cpp | 73 ++++++ DDG4/src/Geant4ReadoutVolumeFilter.cpp | 12 + DDG4/src/Geant4SensDetAction.cpp | 85 ++++++- DDG4/src/Geant4SensitiveDetector.cpp | 235 ------------------ 19 files changed, 626 insertions(+), 881 deletions(-) create mode 100644 DDG4/include/DDG4/Geant4GFlashSpotHandler.h delete mode 100644 DDG4/include/DDG4/Geant4SensitiveDetector.h delete mode 100644 DDG4/include/DDG4/Geant4SensitiveDetector_inline.h delete mode 100644 DDG4/legacy/Geant4CalorimeterSD.cpp delete mode 100644 DDG4/legacy/Geant4TrackerCombineSD.cpp delete mode 100644 DDG4/legacy/Geant4TrackerSD.cpp create mode 100644 DDG4/src/Geant4GFlashSpotHandler.cpp delete mode 100644 DDG4/src/Geant4SensitiveDetector.cpp diff --git a/DDG4/CMakeLists.txt b/DDG4/CMakeLists.txt index 9fdb47e48..adefddd4c 100644 --- a/DDG4/CMakeLists.txt +++ b/DDG4/CMakeLists.txt @@ -34,8 +34,6 @@ target_include_directories(DDG4 BEFORE $<INSTALL_INTERFACE:include> ) -#--------------------------- Legacy libraries (for Frank) ------------------------- -dd4hep_add_plugin(DDG4Legacy SOURCES legacy/*.cpp USES DDG4) #----------------------------------------------------------------------------------- dd4hep_add_dictionary( G__DDG4 SOURCES python/DDG4Dict.C @@ -163,10 +161,10 @@ install(DIRECTORY ${CMAKE_BINARY_DIR}/python/DDSim DESTINATION ${DD4HEP_PYTHON_I install(DIRECTORY examples DESTINATION examples/DDG4) -set_target_properties(DDG4 DDG4Plugins DDG4Legacy PROPERTIES VERSION ${DD4hep_VERSION} SOVERSION ${DD4hep_SOVERSION}) +set_target_properties(DDG4 DDG4Plugins PROPERTIES VERSION ${DD4hep_VERSION} SOVERSION ${DD4hep_SOVERSION}) -install(TARGETS DDG4 DDG4Plugins DDG4Legacy g4gdmlDisplay g4FromXML +install(TARGETS DDG4 DDG4Plugins g4gdmlDisplay g4FromXML EXPORT DD4hep ARCHIVE DESTINATION lib LIBRARY DESTINATION lib diff --git a/DDG4/include/DDG4/Geant4Data.h b/DDG4/include/DDG4/Geant4Data.h index c15d1bba5..699e1809b 100644 --- a/DDG4/include/DDG4/Geant4Data.h +++ b/DDG4/include/DDG4/Geant4Data.h @@ -25,6 +25,7 @@ // Forward declarations class G4Step; class G4StepPoint; +class G4GFlashSpot; /// Namespace for the AIDA detector description toolkit namespace dd4hep { @@ -189,9 +190,13 @@ namespace dd4hep { /// Clear data content void clear() { x = y = z = 0.0; - time = deposit = length = 0.0; + time = deposit = length = 0.0; pdgID = trackID = -1; } + /// Access position + Position position() const { + return Position(x, y, z); + } }; typedef MonteCarloContrib Contribution; typedef std::vector<MonteCarloContrib> Contributions; @@ -204,6 +209,8 @@ namespace dd4hep { static Contribution extractContribution(const G4Step* step); /// Extract the MC contribution for a given hit from the step information with BirksLaw option static Contribution extractContribution(const G4Step* step, bool ApplyBirksLaw); + /// Extract the MC contribution for a given hit from the GFlash spot information + static Contribution extractContribution(const G4GFlashSpot* spot); }; /// Helper class to define structures used by the generic DDG4 tracker sensitive detector diff --git a/DDG4/include/DDG4/Geant4GFlashSpotHandler.h b/DDG4/include/DDG4/Geant4GFlashSpotHandler.h new file mode 100644 index 000000000..548ae201d --- /dev/null +++ b/DDG4/include/DDG4/Geant4GFlashSpotHandler.h @@ -0,0 +1,179 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DDG4_GEANT4GFLASHSPOTHANDLER_H +#define DDG4_GEANT4GFLASHSPOTHANDLER_H + +// Framework include files +#include "DDG4/Defs.h" + +// Geant4 include files +#include "G4GFlashSpot.hh" +#include "G4VTouchable.hh" +#include "G4VSensitiveDetector.hh" +#include "G4EmSaturation.hh" +#include "G4Version.hh" + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit + namespace sim { + + // Forward declarations; + class Geant4GFlashSpotHandler; + + /// Helper class to ease the extraction of information from a G4GFlashSpot object. + /** + * + * Helper/utility class to easily access Geant4 gflashspot information. + * Born by lazyness: Avoid typing millions of statements! + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_SIMULATION + */ + class Geant4GFlashSpotHandler { + public: + const G4GFlashSpot* gflashspot; + const G4FastTrack* fast_track; + const G4Track* track; + /// Inhibit default constructor + Geant4GFlashSpotHandler() = delete; + /// Initializing constructor + Geant4GFlashSpotHandler(const G4GFlashSpot* s) : gflashspot(s) { + fast_track = gflashspot->GetOriginatorTrack(); + track = fast_track->GetPrimaryTrack(); + } + /// No copy constructor + Geant4GFlashSpotHandler(const Geant4GFlashSpotHandler& copy) = delete; + /// No move constructor + Geant4GFlashSpotHandler(Geant4GFlashSpotHandler&& copy) = delete; + /// Assignment operator inhibited. Should not be copied + Geant4GFlashSpotHandler& operator=(const Geant4GFlashSpotHandler& copy) = delete; + /// Move operator inhibited. Should not be copied + Geant4GFlashSpotHandler& operator=(Geant4GFlashSpotHandler&& copy) = delete; + + G4ParticleDefinition* trackDef() const { + return track->GetDefinition(); + } + int trkPdgID() const { + return track->GetDefinition()->GetPDGEncoding(); + } + /// Returns total energy deposit + double energy() const { + return gflashspot->GetEnergySpot()->GetEnergy(); + } + /// Returns the pre-gflashspot position + Position position() const { + const G4ThreeVector p = gflashspot->GetEnergySpot()->GetPosition(); + return Position(p.x(), p.y(), p.z()); + } + /// Direction calculated from the post- and pre-position ofthe gflashspot + Position direction() const { + const G4ThreeVector p = track->GetMomentumDirection(); + return Position(p.x(), p.y(), p.z()); + } + /// Return track momentum in DD4hep notation + Momentum momentum() const { + const G4ThreeVector& p = track->GetMomentum(); + return Momentum(p.x(), p.y(), p.z()); + } + /// Returns the post-step position as a G4ThreeVector + G4ThreeVector positionG4() const { + return gflashspot->GetEnergySpot()->GetPosition(); + } + /// Returns the track momentum as a G4ThreeVector + G4ThreeVector momentumG4() const { + return track->GetMomentum(); + } + /// Access the enery deposit of the energy spot + double deposit() const { + return gflashspot->GetEnergySpot()->GetEnergy(); + } + /// Access the G4 track ID + int trkID() const { + return track->GetTrackID(); + } + /// Access the G4 track ID of the parent track + int parentID() const { + return track->GetParentID(); + } + double trkTime() const { + return track->GetGlobalTime(); + } + double trkEnergy() const { + return track->GetTotalEnergy(); + } + double trkKineEnergy() const { + return track->GetKineticEnergy(); + } + int trkStatus() const { + return track->GetTrackStatus(); + } + bool trkAlive() const { + return track->GetTrackStatus() == fAlive; + } + const G4VProcess* trkProcess() const { + return track->GetCreatorProcess(); + } + const G4VTouchable* touchable() const { + return gflashspot->GetTouchableHandle().operator->(); + } + G4VPhysicalVolume* volume() const { + return touchable()->GetVolume(); + } + G4LogicalVolume* logvol() const { + return volume()->GetLogicalVolume(); + } + G4VSolid* solid() const { + return touchable()->GetSolid(); + } + G4VSensitiveDetector* sd() const { + G4LogicalVolume* lv = logvol(); + return lv ? lv->GetSensitiveDetector() : 0; + } + const char* sdName(const char* undefined = "") const { + G4VSensitiveDetector* s = sd(); + return s ? s->GetName().c_str() : undefined; + } + bool isSensitive() const { + G4LogicalVolume* lv = logvol(); + return lv ? (0 != lv->GetSensitiveDetector()) : false; + } + /// Coordinate transformation to global coordinates. + /** Note: Positions are in units of MM! */ + Position localToGlobal(const Position& local) const; + /// Coordinate transformation to global coordinates. + /** Note: DDSegmentation points are units in CM! Conversion done inside! */ + Position localToGlobal(const DDSegmentation::Vector3D& local) const; + /// Coordinate transformation to global coordinates in MM + Position localToGlobal(const G4ThreeVector& local) const; + /// Coordinate transformation to global coordinates in MM + Position localToGlobal(double x, double y, double z) const; + + /// Coordinate transformation to local coordinates + Position globalToLocal(double x, double y, double z) const; + /// Coordinate transformation to local coordinates + Position globalToLocal(const Position& global) const; + /// Coordinate transformation to local coordinates + Position globalToLocal(const G4ThreeVector& global) const; + /// Coordinate transformation to local coordinates + G4ThreeVector globalToLocalG4(double x, double y, double z) const; + /// Coordinate transformation to local coordinates with G4 objects + G4ThreeVector globalToLocalG4(const G4ThreeVector& loc) const; + }; + + } // End namespace sim +} // End namespace dd4hep + +#endif // DDG4_GEANT4GFLASHSPOTHANDLER_H diff --git a/DDG4/include/DDG4/Geant4ReadoutVolumeFilter.h b/DDG4/include/DDG4/Geant4ReadoutVolumeFilter.h index 8101385ae..cd68443dc 100644 --- a/DDG4/include/DDG4/Geant4ReadoutVolumeFilter.h +++ b/DDG4/include/DDG4/Geant4ReadoutVolumeFilter.h @@ -49,6 +49,8 @@ namespace dd4hep { virtual ~Geant4ReadoutVolumeFilter(); /// Filter action. Return true if hits should be processed virtual bool operator()(const G4Step* step) const; + /// GFLASH interface: Filter action. Return true if hits should be processed. + virtual bool operator()(const G4GFlashSpot* step) const; }; } // End namespace sim } // End namespace dd4hep diff --git a/DDG4/include/DDG4/Geant4SensDetAction.h b/DDG4/include/DDG4/Geant4SensDetAction.h index acdc33873..9ed4d1f76 100644 --- a/DDG4/include/DDG4/Geant4SensDetAction.h +++ b/DDG4/include/DDG4/Geant4SensDetAction.h @@ -26,6 +26,7 @@ class G4HCofThisEvent; class G4Step; class G4Event; +class G4GFlashSpot; class G4TouchableHistory; class G4VHitsCollection; class G4VReadOutGeometry; @@ -97,8 +98,13 @@ namespace dd4hep { Geant4Filter(Geant4Context* context, const std::string& name); /// Standard destructor virtual ~Geant4Filter(); - /// Filter action. Return true if hits should be processed + /// Filter action. Return true if hits should be processed. Default returns true virtual bool operator()(const G4Step* step) const; + /// GFLASH interface: Filter action. Return true if hits should be processed. + /** The default implementation throws an exception that the + * GFLASH interface is not implemented. + */ + virtual bool operator()(const G4GFlashSpot* step) const; }; /// The base class for Geant4 sensitive detector actions implemented by users @@ -215,10 +221,15 @@ namespace dd4hep { void adoptFilter_front(Geant4Action* filter); /// Callback before hit processing starts. Invoke all filters. - /** Return fals if any filter returns false + /** Return false if any filter returns false */ bool accept(const G4Step* step) const; + /// GFLASH interface: Callback before hit processing starts. Invoke all filters. + /** Return false if any filter returns false + */ + bool accept(const G4GFlashSpot* step) const; + /// Initialize the usage of a single hit collection. Returns the collection ID template <typename TYPE> size_t defineCollection(const std::string& coll_name); @@ -246,6 +257,12 @@ namespace dd4hep { /// G4VSensitiveDetector interface: Method for generating hit(s) using the information of G4Step object. virtual bool process(G4Step* step, G4TouchableHistory* history); + /// Separate GFLASH interface: Method for generating hit(s) using the information of the G4GFlashSpot object. + /** The default implementation throws an exception that the + * GFLASH interface is not implemented. + */ + virtual bool processGFlash(G4GFlashSpot* spot, G4TouchableHistory* history); + /// G4VSensitiveDetector interface: Method invoked if the event was aborted. /** Hits collections created but not being set to G4HCofThisEvent * at the event should be deleted. @@ -260,6 +277,12 @@ namespace dd4hep { */ long long int volumeID(const G4Step* step); + /// Returns the volumeID of the sensitive volume corresponding to the GFlash spot + /** Combining the VolIDS of the complete geometry path (Geant4TouchableHistory) + * from the current sensitive volume to the world volume + */ + long long int volumeID(const G4GFlashSpot* spot); + /// Returns the cellID of the sensitive volume corresponding to the step /** The CellID is the VolumeID + the local coordinates of the sensitive area. * Calculated by combining the VolIDS of the complete geometry path (Geant4TouchableHistory) @@ -267,6 +290,12 @@ namespace dd4hep { */ long long int cellID(const G4Step* step); + /// Returns the cellID of the sensitive volume corresponding to the GFlash spot + /** The CellID is the VolumeID + the local coordinates of the sensitive area. + * Calculated by combining the VolIDS of the complete geometry path (Geant4TouchableHistory) + * from the current sensitive volume to the world volume + */ + long long int cellID(const G4GFlashSpot* spot); }; /// The sequencer to host Geant4 sensitive actions called if particles interact with sensitive elements @@ -382,12 +411,16 @@ namespace dd4hep { void adoptFilter(Geant4Action* filter); /// Callback before hit processing starts. Invoke all filters. - /** Return fals if any filter returns false - */ bool accept(const G4Step* step) const; - /// Function to process hits - virtual bool process(G4Step* step, G4TouchableHistory* hist); + /// GFLASH interface: Callback before hit processing starts. Invoke all filters. + bool accept(const G4GFlashSpot* step) const; + + /// G4VSensitiveDetector interface: Method for generating hit(s) using the information of G4Step object. + virtual bool process(G4Step* step, G4TouchableHistory* history); + + /// Separate GFLASH interface: Method for generating hit(s) using the information of the G4GFlashSpot object. + virtual bool processGFlash(G4GFlashSpot* spot, G4TouchableHistory* history); /// G4VSensitiveDetector interface: Method invoked at the begining of each event. /** The hits collection(s) created by this sensitive detector must @@ -525,6 +558,9 @@ namespace dd4hep { virtual void end(G4HCofThisEvent* hce); /// G4VSensitiveDetector interface: Method for generating hit(s) using the G4Step object. virtual bool process(G4Step* step,G4TouchableHistory* history); + /// Separate GFLASH interface: Method for generating hit(s) using the information of the G4GFlashSpot object. + virtual bool processGFlash(G4GFlashSpot* spot, G4TouchableHistory* history); + /// G4VSensitiveDetector interface: Method invoked if the event was aborted. virtual void clear(G4HCofThisEvent* hce); }; diff --git a/DDG4/include/DDG4/Geant4SensDetAction.inl b/DDG4/include/DDG4/Geant4SensDetAction.inl index 8f57f4bce..79ee69084 100644 --- a/DDG4/include/DDG4/Geant4SensDetAction.inl +++ b/DDG4/include/DDG4/Geant4SensDetAction.inl @@ -66,6 +66,11 @@ namespace dd4hep { template <typename T> bool Geant4SensitiveAction<T>::process(G4Step* step,G4TouchableHistory* history) { return Geant4Sensitive::process(step,history); } + + /// Separate GFLASH interface: Method for generating hit(s) using the information of the G4GFlashSpot object. + template <typename T> bool Geant4SensitiveAction<T>::processGFlash(G4GFlashSpot* spot, G4TouchableHistory* history) { + return Geant4Sensitive::processGFlash(spot,history); + } /// G4VSensitiveDetector interface: Method invoked if the event was aborted. template <typename T> void Geant4SensitiveAction<T>::clear(G4HCofThisEvent* hce) { diff --git a/DDG4/include/DDG4/Geant4SensitiveDetector.h b/DDG4/include/DDG4/Geant4SensitiveDetector.h deleted file mode 100644 index 43224e9c6..000000000 --- a/DDG4/include/DDG4/Geant4SensitiveDetector.h +++ /dev/null @@ -1,177 +0,0 @@ -//========================================================================== -// AIDA Detector description implementation -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== -#ifndef DDG4_GEANT4SENSITIVEDETECTOR_H -#define DDG4_GEANT4SENSITIVEDETECTOR_H - -// Framework include files -#include "DD4hep/Detector.h" -#include "DDG4/Geant4Hits.h" - -// Geant 4 include files -#include "G4Step.hh" -#include "G4HCofThisEvent.hh" -#include "G4TouchableHistory.hh" -#include "G4VSensitiveDetector.hh" -#include "G4THitsCollection.hh" - -#include <algorithm> - -/// Namespace for the AIDA detector description toolkit -namespace dd4hep { - - /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit - namespace sim { - - // Forward declarations - class Geant4StepHandler; - class Geant4SensitiveDetector; - - /// Deprecated: Example G4VSensitiveDetector implementation. - /** \deprecated - * Deprecated class. Not supported by the DDG4 kernel. - * - * @author M.Frank - * @version 1.0 - */ - class Geant4SensitiveDetector : public G4VSensitiveDetector { - public: - typedef G4THitsCollection<Geant4Hit> HitCollection; - typedef Geant4Hit::Contribution HitContribution; - typedef Geant4StepHandler StepHandler; - - protected: - - /// Reference to the detector description object - Detector& m_detDesc; - /// Reference to the detector element describing this sensitive element - DetElement m_detector; - /// Reference to the sensitive detector element - SensitiveDetector m_sensitive; - /// Reference to the readout structure - Readout m_readout; - - /// Geant4 event context - G4HCofThisEvent* m_hce; - - /// Find hits by position in a collection - template <typename T> T* find(const HitCollection* c,const HitCompare<T>& cmp); - - /// Dump Step information (careful: very verbose) - void dumpStep(G4Step* step,G4TouchableHistory* history); - - public: - - /// Constructor. The sensitive detector element is identified by the detector name - Geant4SensitiveDetector(const std::string& name, Detector& description); - - /// Initialize the sensitive detector for the usage of a single hit collection - virtual bool defineCollection(const std::string& coll_name); - - /// Standard destructor - virtual ~Geant4SensitiveDetector(); - - /// Standard access to the name - std::string name() const { return GetName(); } - - /// Create single hits collection - virtual HitCollection* createCollection(const std::string& coll_name) const; - - /// Access HitCollection container names - const std::string& hitCollectionName(int which) const; - - /// Retrieve the hits collection associated with this detector by its serial number - HitCollection* collection(int id); - - /// Retrieve the hits collection associated with this detector by its collection identifier - HitCollection* collectionByID(int id); - - /// Method for generating hit(s) using the information of G4Step object. - virtual bool buildHits(G4Step* /* step */,G4TouchableHistory* /* history */) { return false; } - - - /// Returns the volumeID of the sensitive volume corresponding to the step - - /// combining the VolIDS of the complete geometry path (Geant4TouchableHistory) - // from the current sensitive volume to the world volume - long long getVolumeID(G4Step* step); - - /// Returns the volumeID of the sensitive volume corresponding to the step - - /// combining the VolIDS of the complete geometry path (Geant4TouchableHistory) - // from the current sensitive volume to the world volume - long long getCellID(G4Step* step); - - /** G4VSensitiveDetector interface: Method invoked at the begining of each event. - * The hits collection(s) created by this sensitive detector must - * be set to the G4HCofThisEvent object at one of these two methods. - */ - virtual void Initialize(G4HCofThisEvent* HCE); - - /// G4VSensitiveDetector interface: Method invoked at the end of each event. - virtual void EndOfEvent(G4HCofThisEvent* HCE); - - /// G4VSensitiveDetector interface: Method for generating hit(s) using the information of G4Step object. - virtual G4bool ProcessHits(G4Step* step,G4TouchableHistory* history); - - /// G4VSensitiveDetector interface: Method for generating hit(s) using the information of G4Step object. - virtual G4bool process(G4Step* step,G4TouchableHistory* history); - - /// G4VSensitiveDetector interface: Method invoked if the event was aborted. - /** Hits collections created but not beibg set to G4HCofThisEvent - * at the event should be deleted. - * Collection(s) which have already set to G4HCofThisEvent - * will be deleted automatically. - */ - virtual void clear(); - }; - - - /// Deprecated: Example G4VSensitiveDetector implementation. - /** \deprecated - * Deprecated class. Not supported by the DDG4 kernel. - */ - template <class T> class Geant4GenericSD : public Geant4SensitiveDetector { - T userData; - public: - /// Constructor. The sensitive detector element is identified by the detector name - Geant4GenericSD(const std::string& name, Detector& description); - - /// Initialize the sensitive detector for the usage of a single hit collection - virtual bool defineCollection(const std::string& coll_name); - - /// Method for generating hit(s) using the information of G4Step object. - virtual G4bool ProcessHits(G4Step* step,G4TouchableHistory* history); - - /** Method invoked at the begining of each event. - * The hits collection(s) created by this sensitive detector must - * be set to the G4HCofThisEvent object at one of these two methods. - */ - virtual void Initialize(G4HCofThisEvent* HCE); - - /// Method invoked at the end of each event. - virtual void EndOfEvent(G4HCofThisEvent* HCE); - - /// This method is invoked if the event abortion is occured. - /** Hits collections created but not beibg set to G4HCofThisEvent - * at the event should be deleted. - * Collection(s) which have already set to G4HCofThisEvent - * will be deleted automatically. - */ - virtual void clear(); - - /// Method for generating hit(s) using the information of G4Step object. - virtual bool buildHits(G4Step* step,G4TouchableHistory* history); - }; - - } // End namespace sim -} // End namespace dd4hep - -#endif // DDG4_GEANT4SENSITIVEDETECTOR_H diff --git a/DDG4/include/DDG4/Geant4SensitiveDetector_inline.h b/DDG4/include/DDG4/Geant4SensitiveDetector_inline.h deleted file mode 100644 index 22dada770..000000000 --- a/DDG4/include/DDG4/Geant4SensitiveDetector_inline.h +++ /dev/null @@ -1,59 +0,0 @@ -//========================================================================== -// AIDA Detector description implementation -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== - -#ifndef DDG4_GEANT4SENSITIVEDETECTOR_INLINE_H -#define DDG4_GEANT4SENSITIVEDETECTOR_INLINE_H - -// Framework include files -#include "DDG4/Geant4SensitiveDetector.h" - -/// Constructor. The sensitive detector element is identified by the detector name -template <class SD> dd4hep::sim::Geant4GenericSD<SD>::Geant4GenericSD(const std::string& nam, Detector& description_ref) - : Geant4SensitiveDetector(nam, description_ref) { - defineCollection(m_sensitive.hitsCollection()); -} - -/// Initialize the sensitive detector for the usage of a single hit collection -template <class SD> bool dd4hep::sim::Geant4GenericSD<SD>::defineCollection(const std::string& coll_name) { - return Geant4SensitiveDetector::defineCollection(coll_name); -} - -/** Method invoked at the begining of each event. - * The hits collection(s) created by this sensitive detector must - * be set to the G4HCofThisEvent object at one of these two methods. - */ -template <class SD> void dd4hep::sim::Geant4GenericSD<SD>::Initialize(G4HCofThisEvent* HCE) { - this->Geant4SensitiveDetector::Initialize(HCE); -} - -/// Method invoked at the end of each event. -template <class SD> void dd4hep::sim::Geant4GenericSD<SD>::EndOfEvent(G4HCofThisEvent* HCE) { - this->Geant4SensitiveDetector::EndOfEvent(HCE); -} - -/// Method invoked if the event was aborted. -template <class SD> void dd4hep::sim::Geant4GenericSD<SD>::clear() { - this->Geant4SensitiveDetector::clear(); -} - -/// Method for generating hit(s) using the information of G4Step object. -template <class SD> G4bool dd4hep::sim::Geant4GenericSD<SD>::ProcessHits(G4Step* step, G4TouchableHistory* history) { - return this->Geant4SensitiveDetector::ProcessHits(step, history); -} - -/// Method for generating hit(s) using the information of G4Step object. -template <class SD> bool dd4hep::sim::Geant4GenericSD<SD>::buildHits(G4Step*, G4TouchableHistory*) { - return true; -} - -#endif // DDG4_GEANT4SENSITIVEDETECTOR_INLINE_H diff --git a/DDG4/legacy/Geant4CalorimeterSD.cpp b/DDG4/legacy/Geant4CalorimeterSD.cpp deleted file mode 100644 index a6928b68a..000000000 --- a/DDG4/legacy/Geant4CalorimeterSD.cpp +++ /dev/null @@ -1,132 +0,0 @@ -//========================================================================== -// AIDA Detector description implementation -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== - -// Framework include files -#include "DDG4/Geant4SensitiveDetector_inline.h" -#include "DDG4/Factories.h" - -// Geant4 include files -#include "G4OpticalPhoton.hh" -#include "G4VProcess.hh" - -using namespace std; -using namespace dd4hep::detail; - -/* - * dd4hep::sim namespace declaration - */ -namespace dd4hep { namespace sim { - - /// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - /// Geant4GenericSD<Calorimeter> - /// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// Legacy class. Deprecated. Not supported! Not supported by the DDG4 kernel. - /** \deprecated - * - * @author M.Frank - * @version 1.0 - */ - struct Calorimeter {}; - /// Method for generating hit(s) using the information of G4Step object. - template <> bool Geant4GenericSD<Calorimeter>::buildHits(G4Step* step,G4TouchableHistory*) { - StepHandler h(step); - Position pos = 0.5 * (h.prePos() + h.postPos()); - HitContribution contrib = Geant4Hit::extractContribution(step); - Geant4CalorimeterHit* hit=find(collection(0),HitPositionCompare<Geant4CalorimeterHit>(pos)); - - // G4cout << "----------- Geant4GenericSD<Calorimeter>::buildHits : position : " << pos << G4endl; - if ( !hit ) { - hit = new Geant4CalorimeterHit(pos); - hit->cellID = getCellID( step ); - collection(0)->insert(hit); - } - hit->truth.push_back(contrib); - hit->energyDeposit += contrib.deposit; - - return true; - } - typedef Geant4GenericSD<Calorimeter> Geant4Calorimeter; - }} // End namespace dd4hep::sim - -DECLARE_GEANT4SENSITIVEDETECTOR_NS(dd4hep::sim,Geant4Calorimeter) - -/* - * dd4hep::sim namespace declaration - */ -namespace dd4hep { namespace sim { - - /// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - /// Geant4GenericSD<OpticalCalorimeter> - /// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - enum { Edep_type=0, Cerenkov_type=1 }; - - /// Legacy class. Deprecated. Not supported! Not supported by the DDG4 kernel. - /** \deprecated - * - * @author M.Frank - * @version 1.0 - */ - struct OpticalCalorimeter {}; - - /// Legacy class. Deprecated. Not supported! Not supported by the DDG4 kernel. - /** \deprecated - * - * @author M.Frank - * @version 1.0 - */ - template <> class Geant4GenericSD<OpticalCalorimeter> : public Geant4GenericSD<Calorimeter> { - public: - /// Constructor. The sensitive detector element is identified by the detector name - Geant4GenericSD(const string& nam, Detector& description_ref) - : Geant4GenericSD<Calorimeter>(nam,description_ref) { } - - /// Initialize the sensitive detector for the usage of a single hit collection - bool defineCollection(const string& coll_name) { - Geant4SensitiveDetector::defineCollection("Edep_" + coll_name); - Geant4SensitiveDetector::defineCollection("Ceren_" + coll_name); - return true; - } - - /// Method for generating hit(s) using the information of G4Step object. - virtual G4bool ProcessHits(G4Step* step,G4TouchableHistory* history) { - G4Track * track = step->GetTrack(); - - // check that particle is optical photon: - if( track->GetDefinition() != G4OpticalPhoton::OpticalPhotonDefinition() ) { - return this->Geant4GenericSD<Calorimeter>::ProcessHits(step,history); - } - else if ( track->GetCreatorProcess()->G4VProcess::GetProcessName() != "Cerenkov") { - track->SetTrackStatus(fStopAndKill); - return false; - } - else { - StepHandler h(step); - HitContribution contrib = Geant4Hit::extractContribution(step); - Position pos = h.prePos(); - Geant4CalorimeterHit* hit=find(collection(Cerenkov_type),HitPositionCompare<Geant4CalorimeterHit>(pos)); - if ( !hit ) { - collection(Cerenkov_type)->insert(hit=new Geant4CalorimeterHit(pos)); - hit->cellID = getCellID( step ) ; - } - hit->energyDeposit += contrib.deposit; - hit->truth.push_back(contrib); - track->SetTrackStatus(fStopAndKill); // don't step photon any further - return true; - } - } - }; - typedef Geant4GenericSD<OpticalCalorimeter> Geant4OpticalCalorimeter; - }} // End namespace dd4hep::sim - -DECLARE_GEANT4SENSITIVEDETECTOR_NS(dd4hep::sim,Geant4OpticalCalorimeter) diff --git a/DDG4/legacy/Geant4TrackerCombineSD.cpp b/DDG4/legacy/Geant4TrackerCombineSD.cpp deleted file mode 100644 index 815099a6a..000000000 --- a/DDG4/legacy/Geant4TrackerCombineSD.cpp +++ /dev/null @@ -1,127 +0,0 @@ -//========================================================================== -// AIDA Detector description implementation -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== - -// Framework include files -#include "DDG4/Geant4SensitiveDetector_inline.h" -#include "DDG4/Factories.h" - -/* - * dd4hep::sim namespace declaration - */ -namespace dd4hep { namespace sim { - - /// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - /// Geant4GenericSD<TrackerCombine> - /// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// Legacy class. Deprecated. Not supported! Not supported by the DDG4 kernel. - /** \deprecated - * - * @author M.Frank - * @version 1.0 - */ - struct TrackerCombine { - Geant4TrackerHit pre; - Geant4TrackerHit post; - G4Track* track; - double e_cut; - int current; - long long int cellID; - TrackerCombine() : pre(), post(), track(0), e_cut(0.0), current(-1), cellID(0) { - } - void start(long long int cell, G4Step* step, G4StepPoint* point) { - pre.storePoint(step,point); - current = pre.truth.trackID; - track = step->GetTrack(); - cellID = cell; - post = pre; - } - void update(G4Step* step) { - post.storePoint(step,step->GetPostStepPoint()); - pre.truth.deposit += post.truth.deposit; - } - void clear() { - pre.truth.clear(); - current = -1; - track = 0; - } - Geant4TrackerHit* extractHit(Geant4SensitiveDetector::HitCollection* c) { - if ( current == -1 || !track ) { - return 0; - } - else if ( pre.truth.deposit <= e_cut && !Geant4Hit::isGeantino(track) ) { - clear(); - return 0; - } - Position pos = 0.5 * (pre.position + post.position); - Momentum mom = 0.5 * (pre.momentum + post.momentum); - double path_len = (post.position - pre.position).R(); - Geant4TrackerHit* hit = new Geant4TrackerHit(pre.truth.trackID, - pre.truth.pdgID, - pre.truth.deposit, - pre.truth.time); - hit->cellID = cellID; - hit->position = pos; - hit->momentum = mom; - hit->length = path_len; - clear(); - c->insert(hit); - return hit; - } - }; - - /// Method invoked at the begining of each event. - template <> void Geant4GenericSD<TrackerCombine>::Initialize(G4HCofThisEvent* HCE) { - userData.e_cut = m_sensitive.energyCutoff(); - this->Geant4SensitiveDetector::Initialize(HCE); - } - - /// Method for generating hit(s) using the information of G4Step object. - template <> void Geant4GenericSD<TrackerCombine>::clear() { - userData.clear(); - this->Geant4SensitiveDetector::clear(); - } - - /// Method for generating hit(s) using the information of G4Step object. - template <> G4bool Geant4GenericSD<TrackerCombine>::ProcessHits(G4Step* step,G4TouchableHistory* ) { - StepHandler h(step); - bool return_code = false; - - if ( !userData.track || userData.current != h.track->GetTrackID() ) { - return_code = userData.extractHit(collection(0)) != 0; - userData.start(getCellID(step), step, h.pre); - } - - // ....update ..... - userData.update(step); - - void *prePV = h.volume(h.pre), *postPV = h.volume(h.post); - if ( prePV != postPV ) { - void* postSD = h.sd(h.post); - return_code = userData.extractHit(collection(0)) != 0; - if ( 0 != postSD ) { - void* preSD = h.sd(h.pre); - if ( preSD == postSD ) { - userData.start(getCellID(step), step,h.post); - } - } - } - else if ( userData.track->GetTrackStatus() == fStopAndKill ) { - return_code = userData.extractHit(collection(0)) != 0; - } - return return_code; - } - typedef Geant4GenericSD<TrackerCombine> Geant4TrackerCombine; - }} // End namespace dd4hep::sim - -DECLARE_GEANT4SENSITIVEDETECTOR_NS(dd4hep::sim,Geant4TrackerCombine) diff --git a/DDG4/legacy/Geant4TrackerSD.cpp b/DDG4/legacy/Geant4TrackerSD.cpp deleted file mode 100644 index 578ff482f..000000000 --- a/DDG4/legacy/Geant4TrackerSD.cpp +++ /dev/null @@ -1,77 +0,0 @@ -//========================================================================== -// AIDA Detector description implementation -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== - -// Framework include files -#include "DDG4/Geant4SensitiveDetector_inline.h" -#include "DDG4/Factories.h" -#include "DDG4/Geant4StepHandler.h" -#include "DDG4/Geant4Mapping.h" - -// C include files -#include <stdexcept> - -/* - * dd4hep::sim namespace declaration - */ -namespace dd4hep { namespace sim { - - /// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - /// Geant4GenericSD<Tracker> - /// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// Legacy class. Deprecated. Not supported! Not supported by the DDG4 kernel. - /** \deprecated - * - * @author M.Frank - * @version 1.0 - */ - struct Tracker {}; - - /// Method for generating hit(s) using the information of G4Step object. - template <> bool Geant4GenericSD<Tracker>::buildHits(G4Step* step,G4TouchableHistory* /*hist*/ ) { - - StepHandler h(step); - Position prePos = h.prePos(); - Position postPos = h.postPos(); - Position direction = postPos - prePos; - Position position = mean_direction(prePos,postPos); - double hit_len = direction.R(); - if (hit_len > 0) { - double new_len = mean_length(h.preMom(),h.postMom())/hit_len; - direction *= new_len/hit_len; - } - - // G4cout << "----------- Geant4GenericSD<Tracker>::buildHits : position : " << prePos << G4endl ; - - Geant4TrackerHit* hit = - new Geant4TrackerHit(h.track->GetTrackID(), - h.track->GetDefinition()->GetPDGEncoding(), - step->GetTotalEnergyDeposit(), - h.track->GetGlobalTime()); - - if ( hit ) { - HitContribution contrib = Geant4Hit::extractContribution(step); - hit->cellID = getCellID( step ) ; - hit->energyDeposit = contrib.deposit ; - hit->position = position; - hit->momentum = direction; - hit->length = hit_len; - collection(0)->insert(hit); - return 1; - } - throw std::runtime_error("new() failed: Cannot allocate hit object"); - } - typedef Geant4GenericSD<Tracker> Geant4Tracker; - }} // End namespace dd4hep::sim - -DECLARE_GEANT4SENSITIVEDETECTOR_NS(dd4hep::sim,Geant4Tracker) diff --git a/DDG4/plugins/Geant4SDActions.cpp b/DDG4/plugins/Geant4SDActions.cpp index e005f4829..a51a99b4c 100644 --- a/DDG4/plugins/Geant4SDActions.cpp +++ b/DDG4/plugins/Geant4SDActions.cpp @@ -13,6 +13,7 @@ // Framework include files #include "DDG4/Geant4SensDetAction.inl" +#include "DDG4/Geant4GFlashSpotHandler.h" #include "DDG4/Geant4EventAction.h" #include "G4OpticalPhoton.hh" #include "G4VProcess.hh" @@ -49,6 +50,11 @@ namespace dd4hep { template <> bool Geant4SensitiveAction<Geant4VoidSensitive>::process(G4Step* /*step*/,G4TouchableHistory* /*hist*/ ) { return true; } + + /// Method for generating hit(s) using the information of G4Step object. + template <> bool Geant4SensitiveAction<Geant4VoidSensitive>::processGFlash(G4GFlashSpot* /*spot*/,G4TouchableHistory* /*hist*/ ) { + return true; + } typedef Geant4SensitiveAction<Geant4VoidSensitive> Geant4VoidSensitiveAction; // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -103,6 +109,31 @@ namespace dd4hep { print(" Geant4 path:%s",handler.path().c_str()); return true; } + + /// Method for generating hit(s) using the information of G4Step object. + template <> bool Geant4SensitiveAction<Geant4Tracker>::processGFlash(G4GFlashSpot* spot, + G4TouchableHistory* /*hist*/ ) + { + typedef Geant4Tracker::Hit Hit; + Geant4GFlashSpotHandler h(spot); + Hit* hit = new Hit(h.trkID(), h.trkPdgID(), h.deposit(), h.track->GetGlobalTime()); + hit->cellID = cellID(spot); + hit->energyDeposit = h.deposit(); + hit->position = h.position(); + hit->momentum = h.momentum(); + hit->length = 0e0; + collection(m_collectionID)->add(hit); + mark(h.track); + if ( 0 == hit->cellID ) { + hit->cellID = volumeID( spot ) ; + except("+++ Invalid CELL ID for hit!"); + } + print("Hit with deposit:%f Pos:%f %f %f ID=%016X", + h.deposit(),hit->position.X(),hit->position.Y(),hit->position.Z(),(void*)hit->cellID); + Geant4TouchableHandler handler(h.touchable()); + print(" Geant4 path:%s",handler.path().c_str()); + return true; + } typedef Geant4SensitiveAction<Geant4Tracker> Geant4TrackerAction; // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -126,9 +157,9 @@ namespace dd4hep { /// Method for generating hit(s) using the information of G4Step object. template <> bool Geant4SensitiveAction<Geant4Calorimeter>::process(G4Step* step,G4TouchableHistory*) { typedef Geant4Calorimeter::Hit Hit; - Geant4StepHandler h(step); - HitContribution contrib = Hit::extractContribution(step); - Geant4HitCollection* coll = collection(m_collectionID); + Geant4StepHandler h(step); + HitContribution contrib = Hit::extractContribution(step); + Geant4HitCollection* coll = collection(m_collectionID); VolumeID cell = 0; try { @@ -145,9 +176,7 @@ namespace dd4hep { << " Pre (" <<std::setw(24) << step->GetPreStepPoint() ->GetMomentum() << ") " << " Post (" <<std::setw(24) << step->GetPostStepPoint()->GetMomentum() << ") " << std::endl; - std::cout << out.str(); - return true; } @@ -170,7 +199,49 @@ namespace dd4hep { } hit->truth.emplace_back(contrib); hit->energyDeposit += contrib.deposit; - mark(step); + mark(h.track); + return true; + } + /// Method for generating hit(s) using the information of the G4GFlashSpot object. + template <> bool Geant4SensitiveAction<Geant4Calorimeter>::processGFlash(G4GFlashSpot* spot, + G4TouchableHistory* /*hist*/ ) + { + typedef Geant4Calorimeter::Hit Hit; + Geant4GFlashSpotHandler h(spot); + HitContribution contrib = Hit::extractContribution(spot); + Geant4HitCollection* coll = collection(m_collectionID); + VolumeID cell = 0; + + try { + cell = cellID(spot); + } catch(std::runtime_error &e) { + std::stringstream out; + out << std::setprecision(20) << std::scientific; + out << "ERROR: " << e.what() << std::endl; + out << "Position: (" << std::setw(24) << h.positionG4() << ") " << std::endl; + out << "Momentum: (" << std::setw(24) << h.momentumG4() << ") " << std::endl; + std::cout << out.str(); + return true; + } + Hit* hit = coll->findByKey<Hit>(cell); + if ( !hit ) { + Geant4TouchableHandler handler(h.touchable()); + DDSegmentation::Vector3D pos = m_segmentation.position(cell); + Position global = h.localToGlobal(pos); + hit = new Hit(global); + hit->cellID = cell; + coll->add(cell, hit); + printM2("%s> CREATE hit with deposit:%e MeV Pos:%8.2f %8.2f %8.2f %s [%s]", + c_name(),contrib.deposit,pos.X,pos.Y,pos.Z,handler.path().c_str(), + coll->GetName().c_str()); + if ( 0 == hit->cellID ) { // for debugging only! + hit->cellID = cellID(spot); + except("+++ Invalid CELL ID for hit!"); + } + } + hit->truth.emplace_back(contrib); + hit->energyDeposit += contrib.deposit; + mark(h.track); return true; } typedef Geant4SensitiveAction<Geant4Calorimeter> Geant4CalorimeterAction; @@ -213,8 +284,8 @@ namespace dd4hep { typedef Geant4Calorimeter::Hit Hit; Geant4StepHandler h(step); Geant4HitCollection* coll = collection(m_collectionID); - HitContribution contrib = Hit::extractContribution(step); - Position pos = h.prePos(); + HitContribution contrib = Hit::extractContribution(step); + Position pos = h.prePos(); Hit* hit = coll->find<Hit>(PositionCompare<Hit,Position>(pos)); if ( !hit ) { hit = new Hit(pos); @@ -232,6 +303,39 @@ namespace dd4hep { return true; } } + /// Method for generating hit(s) using the information of the G4GFlashSpot object. + template <> bool Geant4SensitiveAction<Geant4OpticalCalorimeter>::processGFlash(G4GFlashSpot* spot, + G4TouchableHistory* /*hist*/ ) + { + typedef Geant4Calorimeter::Hit Hit; + Geant4GFlashSpotHandler h(spot); + const G4Track* track = h.track; + if( track->GetDefinition() != G4OpticalPhoton::OpticalPhotonDefinition() ) { + return false; + } + else if ( track->GetCreatorProcess()->G4VProcess::GetProcessName() != "Cerenkov") { + return false; + } + else { + Geant4HitCollection* coll = collection(m_collectionID); + HitContribution contrib = Hit::extractContribution(spot); + Position pos = h.position(); + Hit* hit = coll->find<Hit>(PositionCompare<Hit,Position>(pos)); + if ( !hit ) { + hit = new Hit(pos); + hit->cellID = volumeID(spot); + coll->add(hit); + if ( 0 == hit->cellID ) { + hit->cellID = volumeID(spot); + except("+++ Invalid CELL ID for hit!"); + } + } + hit->energyDeposit += contrib.deposit; + hit->truth.emplace_back(contrib); + mark(h.track); + return true; + } + } typedef Geant4SensitiveAction<Geant4OpticalCalorimeter> Geant4OpticalCalorimeterAction; @@ -261,9 +365,9 @@ namespace dd4hep { /// Method for generating hit(s) using the information of G4Step object. template <> bool Geant4SensitiveAction<Geant4ScintillatorCalorimeter>::process(G4Step* step,G4TouchableHistory*) { typedef Geant4Calorimeter::Hit Hit; - Geant4StepHandler h(step); - HitContribution contrib = Hit::extractContribution(step,true); - Geant4HitCollection* coll = collection(m_collectionID); + Geant4StepHandler h(step); + HitContribution contrib = Hit::extractContribution(step,true); + Geant4HitCollection* coll = collection(m_collectionID); VolumeID cell = 0; try { cell = cellID(step); @@ -279,13 +383,9 @@ namespace dd4hep { << " Pre (" <<std::setw(24) << step->GetPreStepPoint() ->GetMomentum() << ") " << " Post (" <<std::setw(24) << step->GetPostStepPoint()->GetMomentum() << ") " << std::endl; - std::cout << out.str(); - return true; } - - //Hit* hit = coll->find<Hit>(CellIDCompare<Hit>(cell)); Hit* hit = coll->findByKey<Hit>(cell); if ( !hit ) { Geant4TouchableHandler handler(step); @@ -303,7 +403,48 @@ namespace dd4hep { } hit->truth.emplace_back(contrib); hit->energyDeposit += contrib.deposit; - mark(step); + mark(h.track); + return true; + } + /// Method for generating hit(s) using the information of the G4GFlashSpot object. + template <> bool Geant4SensitiveAction<Geant4ScintillatorCalorimeter>::processGFlash(G4GFlashSpot* spot, + G4TouchableHistory* /*hist*/ ) + { + typedef Geant4Calorimeter::Hit Hit; + Geant4GFlashSpotHandler h(spot); + HitContribution contrib = Hit::extractContribution(spot); + Geant4HitCollection* coll = collection(m_collectionID); + VolumeID cell = 0; + + try { + cell = cellID(spot); + } catch(std::runtime_error &e) { + std::stringstream out; + out << std::setprecision(20) << std::scientific; + out << "ERROR: " << e.what() << std::endl; + out << "Position: (" << std::setw(24) << h.positionG4() << ") " << std::endl; + out << "Momentum: (" << std::setw(24) << h.momentumG4() << ") " << std::endl; + std::cout << out.str(); + return true; + } + Hit* hit = coll->findByKey<Hit>(cell); + if ( !hit ) { + Geant4TouchableHandler handler(h.touchable()); + DDSegmentation::Vector3D pos = m_segmentation.position(cell); + Position global = h.localToGlobal(pos); + hit = new Hit(global); + hit->cellID = cell; + coll->add(cell, hit); + printM2("CREATE hit with deposit:%e MeV Pos:%8.2f %8.2f %8.2f %s", + contrib.deposit,pos.X,pos.Y,pos.Z,handler.path().c_str()); + if ( 0 == hit->cellID ) { // for debugging only! + hit->cellID = cellID(spot); + except("+++ Invalid CELL ID for hit!"); + } + } + hit->truth.emplace_back(contrib); + hit->energyDeposit += contrib.deposit; + mark(h.track); return true; } typedef Geant4SensitiveAction<Geant4ScintillatorCalorimeter> Geant4ScintillatorCalorimeterAction; @@ -331,14 +472,14 @@ namespace dd4hep { * \ingroup DD4HEP_SIMULATION */ struct TrackerCombine { - Geant4Tracker::Hit pre, post; - Position mean_pos; - Geant4Sensitive* sensitive; - double mean_time; - double e_cut; - int current; - int combined; - long long int cell; + Geant4Tracker::Hit pre, post; + Position mean_pos; + Geant4Sensitive* sensitive; + double mean_time; + double e_cut; + int current; + int combined; + long long int cell; TrackerCombine() : pre(), post(), sensitive(0), mean_time(0.0), e_cut(0.0), current(-1), combined(0), cell(0) @@ -454,6 +595,11 @@ namespace dd4hep { } return true; } + /// Method for generating hit(s) using the information of G4Step object. + G4bool process(G4GFlashSpot* , G4TouchableHistory* ) { + sensitive->except("GFlash action is not implemented for SD: %s", sensitive->c_name()); + return false; + } /// Post-event action callback void endEvent(const G4Event* /* event */) { @@ -492,6 +638,11 @@ namespace dd4hep { Geant4SensitiveAction<TrackerCombine>::process(G4Step* step, G4TouchableHistory* history) { return m_userData.process(step, history); } + /// Method for generating hit(s) using the information of the G4GFlashSpot object. + template <> bool + Geant4SensitiveAction<TrackerCombine>::processGFlash(G4GFlashSpot* spot,G4TouchableHistory* history) { + return m_userData.process(spot, history); + } typedef Geant4SensitiveAction<TrackerCombine> Geant4TrackerCombineAction; diff --git a/DDG4/plugins/Geant4SensDetFilters.cpp b/DDG4/plugins/Geant4SensDetFilters.cpp index 5ba9fbd71..07b30699a 100644 --- a/DDG4/plugins/Geant4SensDetFilters.cpp +++ b/DDG4/plugins/Geant4SensDetFilters.cpp @@ -11,10 +11,14 @@ // //========================================================================== -// Framework include files +/// Framework include files #include "DDG4/Geant4SensDetAction.h" -// Forward declarations +/// Geant4 include files +#include "G4GFlashSpot.hh" + + +/// Forward declarations class G4ParticleDefinition; /// Namespace for the AIDA detector description toolkit @@ -46,6 +50,14 @@ namespace dd4hep { bool isSameType(const G4Track* track) const; /// Check if the particle is a geantino bool isGeantino(const G4Track* track) const; + /// Access to the track from step + const G4Track* getTrack(const G4Step* step) const { + return step->GetTrack(); + } + /// Access to the track from step + const G4Track* getTrack(const G4GFlashSpot* spot) const { + return spot->GetOriginatorTrack()->GetPrimaryTrack(); + } }; /// Geant4 sensitive detector filter implementing a particle rejector @@ -60,7 +72,13 @@ namespace dd4hep { /// Standard destructor virtual ~ParticleRejectFilter(); /// Filter action. Return true if hits should be processed - virtual bool operator()(const G4Step* step) const final; + virtual bool operator()(const G4Step* step) const final { + return !isSameType(getTrack(step)); + } + /// GFLASH interface: Filter action. Return true if hits should be processed + virtual bool operator()(const G4GFlashSpot* spot) const final { + return !isSameType(getTrack(spot)); + } }; /// Geant4 sensitive detector filter implementing a particle selector @@ -75,7 +93,13 @@ namespace dd4hep { /// Standard destructor virtual ~ParticleSelectFilter(); /// Filter action. Return true if hits should be processed - virtual bool operator()(const G4Step* step) const final; + virtual bool operator()(const G4Step* step) const final { + return isSameType(getTrack(step)); + } + /// GFLASH interface: Filter action. Return true if hits should be processed + virtual bool operator()(const G4GFlashSpot* spot) const final { + return isSameType(getTrack(spot)); + } }; /// Geant4 sensitive detector filter implementing a Geantino rejector @@ -90,7 +114,13 @@ namespace dd4hep { /// Standard destructor virtual ~GeantinoRejectFilter(); /// Filter action. Return true if hits should be processed - virtual bool operator()(const G4Step* step) const final; + virtual bool operator()(const G4Step* step) const final { + return !isGeantino(getTrack(step)); + } + /// GFLASH interface: Filter action. Return true if hits should be processed + virtual bool operator()(const G4GFlashSpot* spot) const final { + return !isGeantino(getTrack(spot)); + } }; /// Geant4 sensitive detector filter implementing an energy cut. @@ -108,7 +138,13 @@ namespace dd4hep { /// Standard destructor virtual ~EnergyDepositMinimumCut(); /// Filter action. Return true if hits should be processed - virtual bool operator()(const G4Step* step) const final; + virtual bool operator()(const G4Step* step) const final { + return step->GetTotalEnergyDeposit() > m_energyCut; + } + /// GFLASH interface: Filter action. Return true if hits should be processed + virtual bool operator()(const G4GFlashSpot* spot) const final { + return spot->GetEnergySpot()->GetEnergy() > m_energyCut; + } }; } } @@ -187,11 +223,6 @@ GeantinoRejectFilter::~GeantinoRejectFilter() { InstanceCount::decrement(this); } -/// Filter action. Return true if hits should be processed -bool GeantinoRejectFilter::operator()(const G4Step* step) const { - return !isGeantino(step->GetTrack()); -} - /// Constructor. ParticleRejectFilter::ParticleRejectFilter(Geant4Context* c, const std::string& n) : ParticleFilter(c,n) { @@ -203,11 +234,6 @@ ParticleRejectFilter::~ParticleRejectFilter() { InstanceCount::decrement(this); } -/// Filter action. Return true if hits should be processed -bool ParticleRejectFilter::operator()(const G4Step* step) const { - return !isSameType(step->GetTrack()); -} - /// Constructor. ParticleSelectFilter::ParticleSelectFilter(Geant4Context* c, const std::string& n) : ParticleFilter(c,n) { @@ -219,11 +245,6 @@ ParticleSelectFilter::~ParticleSelectFilter() { InstanceCount::decrement(this); } -/// Filter action. Return true if hits should be processed -bool ParticleSelectFilter::operator()(const G4Step* step) const { - return isSameType(step->GetTrack()); -} - /// Constructor. EnergyDepositMinimumCut::EnergyDepositMinimumCut(Geant4Context* c, const std::string& n) : Geant4Filter(c,n) { @@ -236,8 +257,3 @@ EnergyDepositMinimumCut::~EnergyDepositMinimumCut() { InstanceCount::decrement(this); } -/// Filter action. Return true if hits should be processed -bool EnergyDepositMinimumCut::operator()(const G4Step* step) const { - return step->GetTotalEnergyDeposit() > m_energyCut; -} - diff --git a/DDG4/src/Geant4Converter.cpp b/DDG4/src/Geant4Converter.cpp index 6adcf9d3b..98eb689bf 100644 --- a/DDG4/src/Geant4Converter.cpp +++ b/DDG4/src/Geant4Converter.cpp @@ -26,7 +26,6 @@ #include "DDG4/Geant4Field.h" #include "DDG4/Geant4Converter.h" #include "DDG4/Geant4UserLimits.h" -#include "DDG4/Geant4SensitiveDetector.h" #include "Geant4ShapeConverter.h" // ROOT includes @@ -48,6 +47,7 @@ #include "G4ReflectedSolid.hh" #include "G4SubtractionSolid.hh" #include "G4IntersectionSolid.hh" +#include "G4VSensitiveDetector.hh" #include "G4Region.hh" #include "G4Element.hh" @@ -56,6 +56,7 @@ #include "G4Material.hh" #include "G4UserLimits.hh" #include "G4FieldManager.hh" +#include "G4LogicalVolume.hh" #include "G4ReflectionFactory.hh" #include "G4OpticalSurface.hh" #include "G4LogicalSkinSurface.hh" @@ -463,8 +464,8 @@ void* Geant4Converter::handleSolid(const string& name, const TGeoShape* shape) c solid = convertShape<TGeoTessellated>(shape); #endif else if (isa == TGeoScaledShape::Class()) { - TGeoScaledShape* sh = (TGeoScaledShape*) shape; #if G4VERSION_NUMBER >= 1030 + TGeoScaledShape* sh = (TGeoScaledShape*) shape; TGeoShape* sol = sh->GetShape(); const double* vals = sh->GetScale()->GetScale(); G4Scale3D scal(vals[0], vals[1], vals[2]); diff --git a/DDG4/src/Geant4Data.cpp b/DDG4/src/Geant4Data.cpp index 794b6343e..9755692ac 100644 --- a/DDG4/src/Geant4Data.cpp +++ b/DDG4/src/Geant4Data.cpp @@ -16,6 +16,7 @@ #include "DD4hep/InstanceCount.h" #include "DDG4/Geant4Data.h" #include "DDG4/Geant4StepHandler.h" +#include "DDG4/Geant4GFlashSpotHandler.h" // Geant4 include files #include "G4Step.hh" @@ -90,6 +91,14 @@ Geant4HitData::Contribution Geant4HitData::extractContribution(const G4Step* ste return contrib; } +/// Extract the MC contribution for a given hit from the GFlash spot information +Geant4HitData::Contribution Geant4HitData::extractContribution(const G4GFlashSpot* spot) { + Geant4GFlashSpotHandler h(spot); + G4ThreeVector p = h.positionG4(); + double position[3] = {p.x(), p.y(), p.z()}; + return Contribution(h.trkID(),h.trkPdgID(),h.energy(),h.trkTime(),0e0,position); +} + /// Default constructor Geant4Tracker::Hit::Hit() : Geant4HitData(), position(), momentum(), length(0.0), truth(), energyDeposit(0.0) diff --git a/DDG4/src/Geant4GFlashSpotHandler.cpp b/DDG4/src/Geant4GFlashSpotHandler.cpp new file mode 100644 index 000000000..04c8b6fa7 --- /dev/null +++ b/DDG4/src/Geant4GFlashSpotHandler.cpp @@ -0,0 +1,73 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "DDG4/Geant4GFlashSpotHandler.h" +#include "DDSegmentation/Segmentation.h" +#include "DD4hep/DD4hepUnits.h" +#include "CLHEP/Units/SystemOfUnits.h" + +namespace units = dd4hep; +using namespace dd4hep; +using namespace dd4hep::sim; + +/// Coordinate transformation to global coordinate. +Position Geant4GFlashSpotHandler::localToGlobal(const DDSegmentation::Vector3D& local) const { + return localToGlobal(G4ThreeVector(local.X / dd4hep::mm,local.Y / dd4hep::mm,local.Z / dd4hep::mm)); +} + +/// Coordinate transformation to global coordinates. +Position Geant4GFlashSpotHandler::localToGlobal(const Position& local) const { + return localToGlobal(G4ThreeVector(local.X(),local.Y(),local.Z())); +} + +/// Coordinate transformation to global coordinates +Position Geant4GFlashSpotHandler::localToGlobal(double x, double y, double z) const { + return localToGlobal(G4ThreeVector(x,y,z)); +} + +/// Coordinate transformation to global coordinates +Position Geant4GFlashSpotHandler::localToGlobal(const G4ThreeVector& loc) const { + G4TouchableHandle t = gflashspot->GetTouchableHandle(); + G4ThreeVector p = t->GetHistory()->GetTopTransform().Inverse().TransformPoint(loc); + return Position(p.x(),p.y(),p.z()); +} + +/// Coordinate transformation to local coordinates +Position Geant4GFlashSpotHandler::globalToLocal(double x, double y, double z) const { + G4ThreeVector p = globalToLocalG4(G4ThreeVector(x,y,z)); + return Position(p.x(),p.y(),p.z()); +} + +/// Coordinate transformation to local coordinates +Position Geant4GFlashSpotHandler::globalToLocal(const Position& global) const { + G4ThreeVector p = globalToLocalG4(G4ThreeVector(global.X(),global.Y(),global.Z())); + return Position(p.x(),p.y(),p.z()); +} + +/// Coordinate transformation to local coordinates +Position Geant4GFlashSpotHandler::globalToLocal(const G4ThreeVector& global) const { + G4ThreeVector p = globalToLocalG4(global); + return Position(p.x(),p.y(),p.z()); +} + +/// Coordinate transformation to local coordinates +G4ThreeVector Geant4GFlashSpotHandler::globalToLocalG4(double x, double y, double z) const { + return globalToLocalG4(G4ThreeVector(x,y,z)); +} + +/// Coordinate transformation to local coordinates +G4ThreeVector Geant4GFlashSpotHandler::globalToLocalG4(const G4ThreeVector& global) const { + G4TouchableHandle t = gflashspot->GetTouchableHandle(); + return t->GetHistory()->GetTopTransform().TransformPoint(global); +} diff --git a/DDG4/src/Geant4ReadoutVolumeFilter.cpp b/DDG4/src/Geant4ReadoutVolumeFilter.cpp index 7423d5e6f..9b8816fda 100644 --- a/DDG4/src/Geant4ReadoutVolumeFilter.cpp +++ b/DDG4/src/Geant4ReadoutVolumeFilter.cpp @@ -18,6 +18,7 @@ #include "DDG4/Geant4Mapping.h" #include "DDG4/Geant4StepHandler.h" #include "DDG4/Geant4VolumeManager.h" +#include "DDG4/Geant4GFlashSpotHandler.h" #include "DDG4/Geant4ReadoutVolumeFilter.h" using namespace dd4hep::sim; @@ -57,3 +58,14 @@ bool Geant4ReadoutVolumeFilter::operator()(const G4Step* step) const { return true; return false; } + +/// Filter action. Return true if hits should be processed +bool Geant4ReadoutVolumeFilter::operator()(const G4GFlashSpot* spot) const { + Geant4GFlashSpotHandler spotH(spot); + Geant4VolumeManager volMgr = Geant4Mapping::instance().volumeManager(); + VolumeID id = volMgr.volumeID(spotH.touchable()); + long64 key = m_key->value(id); + if ( m_collection->key_min <= key && m_collection->key_max >= key ) + return true; + return false; +} diff --git a/DDG4/src/Geant4SensDetAction.cpp b/DDG4/src/Geant4SensDetAction.cpp index 088d0f32b..0899d601c 100644 --- a/DDG4/src/Geant4SensDetAction.cpp +++ b/DDG4/src/Geant4SensDetAction.cpp @@ -17,10 +17,11 @@ #include "DD4hep/InstanceCount.h" #include "DDG4/Geant4Kernel.h" #include "DDG4/Geant4Mapping.h" -#include "DDG4/Geant4SensDetAction.h" #include "DDG4/Geant4StepHandler.h" +#include "DDG4/Geant4SensDetAction.h" #include "DDG4/Geant4VolumeManager.h" #include "DDG4/Geant4MonteCarloTruth.h" +#include "DDG4/Geant4GFlashSpotHandler.h" // Geant4 include files #include <G4Step.hh> @@ -90,6 +91,12 @@ bool Geant4Filter::operator()(const G4Step*) const { return true; } +/// Filter action. Return true if hits should be processed +bool Geant4Filter::operator()(const G4GFlashSpot*) const { + except("The filter action %s does not support the GFLASH interface for Geant4.", c_name()); + return false; +} + /// Constructor. The detector element is identified by the name Geant4Sensitive::Geant4Sensitive(Geant4Context* ctxt, const string& nam, DetElement det, Detector& description_ref) : Geant4Action(ctxt, nam), m_sensitiveDetector(0), m_sequence(0), @@ -147,7 +154,15 @@ void Geant4Sensitive::adopt_front(Geant4Filter* filter) { /// Callback before hit processing starts. Invoke all filters. bool Geant4Sensitive::accept(const G4Step* step) const { - bool result = m_filters.filter(&Geant4Filter::operator(), step); + bool (Geant4Filter::*filter)(const G4Step*) const = &Geant4Filter::operator(); + bool result = m_filters.filter(filter, step); + return result; +} + +/// GFLASH interface: Callback before hit processing starts. Invoke all filters. +bool Geant4Sensitive::accept(const G4GFlashSpot* spot) const { + bool (Geant4Filter::*filter)(const G4GFlashSpot*) const = &Geant4Filter::operator(); + bool result = m_filters.filter(filter, spot); return result; } @@ -198,11 +213,17 @@ void Geant4Sensitive::begin(G4HCofThisEvent* /* HCE */) { void Geant4Sensitive::end(G4HCofThisEvent* /* HCE */) { } -/// Method for generating hit(s) using the information of G4Step object. +/// G4VSensitiveDetector interface: Method for generating hit(s) using the information of G4Step object. bool Geant4Sensitive::process(G4Step* /* step */, G4TouchableHistory* /* history */) { return false; } +/// Separate GFLASH interface: Method for generating hit(s) using the information of the G4GFlashSpot object. +bool Geant4Sensitive::processGFlash(G4GFlashSpot* /* spot */, G4TouchableHistory* /* history */) { + except("The sensitive action %s does not support the GFLASH interface for Geant4.", c_name()); + return false; +} + /// Method is invoked if the event abortion is occured. void Geant4Sensitive::clear(G4HCofThisEvent* /* HCE */) { } @@ -227,6 +248,14 @@ long long int Geant4Sensitive::volumeID(const G4Step* step) { return id; } +/// Returns the volumeID of the sensitive volume corresponding to the GFlash spot +long long int Geant4Sensitive::volumeID(const G4GFlashSpot* spot) { + Geant4GFlashSpotHandler h(spot); + Geant4VolumeManager volMgr = Geant4Mapping::instance().volumeManager(); + VolumeID id = volMgr.volumeID(h.touchable()); + return id; +} + /// Returns the cellID(volumeID+local coordinate encoding) of the sensitive volume corresponding to the step long long int Geant4Sensitive::cellID(const G4Step* step) { Geant4StepHandler h(step); @@ -243,6 +272,22 @@ long long int Geant4Sensitive::cellID(const G4Step* step) { return volID; } +/// Returns the cellID(volumeID+local coordinate encoding) of the sensitive volume corresponding to the GFlash spot +long long int Geant4Sensitive::cellID(const G4GFlashSpot* spot) { + Geant4GFlashSpotHandler h(spot); + Geant4VolumeManager volMgr = Geant4Mapping::instance().volumeManager(); + VolumeID volID = volMgr.volumeID(h.touchable()); + if ( m_segmentation.isValid() ) { + G4ThreeVector global = h.positionG4(); + G4ThreeVector local = h.touchable()->GetHistory()->GetTopTransform().TransformPoint(global); + Position loc (local.x()*MM_2_CM, local.y()*MM_2_CM, local.z()*MM_2_CM); + Position glob(global.x()*MM_2_CM, global.y()*MM_2_CM, global.z()*MM_2_CM); + VolumeID cID = m_segmentation.cellID(loc,glob,volID); + return cID; + } + return volID; +} + /// Standard constructor Geant4SensDetActionSequence::Geant4SensDetActionSequence(Geant4Context* ctxt, const string& nam) : Geant4Action(ctxt, nam), m_hce(0), m_detector(0) @@ -350,19 +395,37 @@ Geant4HitCollection* Geant4SensDetActionSequence::collectionByID(size_t id) cons /// Callback before hit processing starts. Invoke all filters. bool Geant4SensDetActionSequence::accept(const G4Step* step) const { - bool result = m_filters.filter(&Geant4Filter::operator(), step); + bool (Geant4Filter::*filter)(const G4Step*) const = &Geant4Filter::operator(); + bool result = m_filters.filter(filter, step); + return result; +} + +/// Callback before hit processing starts. Invoke all filters. +bool Geant4SensDetActionSequence::accept(const G4GFlashSpot* spot) const { + bool (Geant4Filter::*filter)(const G4GFlashSpot*) const = &Geant4Filter::operator(); + bool result = m_filters.filter(filter, spot); + return result; +} + +/// G4VSensitiveDetector interface: Method for generating hit(s) using the information of G4Step object. +bool Geant4SensDetActionSequence::process(G4Step* step, G4TouchableHistory* history) { + bool result = false; + for (Geant4Sensitive* sensitive : m_actors) { + if ( sensitive->accept(step) ) + result |= sensitive->process(step, history); + } + m_process(step, history); return result; } -/// Function to process hits -bool Geant4SensDetActionSequence::process(G4Step* step, G4TouchableHistory* hist) { +/// Separate GFLASH interface: Method for generating hit(s) using the information of the G4GFlashSpot object. +bool Geant4SensDetActionSequence::processGFlash(G4GFlashSpot* spot, G4TouchableHistory* history) { bool result = false; - for (vector<Geant4Sensitive*>::iterator i = m_actors->begin(); i != m_actors->end(); ++i) { - Geant4Sensitive* sensitive = *i; - if (sensitive->accept(step)) - result |= sensitive->process(step, hist); + for (Geant4Sensitive* sensitive : m_actors) { + if ( sensitive->accept(spot) ) + result |= sensitive->processGFlash(spot, history); } - m_process(step, hist); + m_process(spot, history); return result; } diff --git a/DDG4/src/Geant4SensitiveDetector.cpp b/DDG4/src/Geant4SensitiveDetector.cpp deleted file mode 100644 index 094aba3f7..000000000 --- a/DDG4/src/Geant4SensitiveDetector.cpp +++ /dev/null @@ -1,235 +0,0 @@ -//========================================================================== -// AIDA Detector description implementation -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== - -// Framework include files -#include "DDG4/Geant4SensitiveDetector.h" -#include "DDG4/Geant4Converter.h" -#include "DDG4/Geant4Hits.h" -#include "DD4hep/Segmentations.h" - -#include "DD4hep/Printout.h" -#include "DD4hep/Detector.h" - -// Geant4 include files -#include "G4Step.hh" -#include "G4PVPlacement.hh" - -// ROOT include files -#include "TGeoNode.h" - -#include "DD4hep/DD4hepUnits.h" -#include "CLHEP/Units/SystemOfUnits.h" - -static const double MM_2_CM = (dd4hep::millimeter/CLHEP::millimeter); - -#define DEBUG 0 - -// C/C++ include files -#include <iostream> -#include <stdexcept> - -using namespace std; -using namespace dd4hep; -using namespace dd4hep::sim; - -/// Constructor. The detector element is identified by the name -Geant4SensitiveDetector::Geant4SensitiveDetector(const string& nam, Detector& description) - : G4VSensitiveDetector(nam), m_detDesc(description), m_detector(), m_sensitive(), m_readout(), m_hce(0) { - m_sensitive = description.sensitiveDetector(nam); - m_detector = description.detector(nam); - m_readout = m_sensitive.readout(); -} - -/// Standard destructor -Geant4SensitiveDetector::~Geant4SensitiveDetector() { -} - -/// Initialize the sensitive detector for the usage of a single hit collection -bool Geant4SensitiveDetector::defineCollection(const string& coll_name) { - if (coll_name.empty()) { - throw runtime_error("Geant4SensitiveDetector: No collection defined for "+name()+" of type "+string(m_sensitive.type())); - } - collectionName.insert(coll_name); - return true; -} - -/// Access HitCollection container names -const string& Geant4SensitiveDetector::hitCollectionName(int which) const { - size_t w = which; - if (w >= collectionName.size()) { - throw runtime_error("The collection name index for subdetector " + name() + " is out of range!"); - } - return collectionName[which]; -} - -/// Create single hits collection -Geant4SensitiveDetector::HitCollection* Geant4SensitiveDetector::createCollection(const string& coll_name) const { - return new G4THitsCollection<Geant4Hit>(GetName(), coll_name); -} -namespace dd4hep { - namespace sim { - template <> Geant4CalorimeterHit* - Geant4SensitiveDetector::find<Geant4CalorimeterHit>(const HitCollection* c, const HitCompare<Geant4CalorimeterHit>& cmp) { - typedef vector<Geant4CalorimeterHit*> _V; - const _V* v = (const _V*) c->GetVector(); - for (_V::const_iterator i = v->begin(); i != v->end(); ++i) - if (cmp(*i)) - return *i; - return 0; - } - } -} - -/// Method invoked at the begining of each event. -void Geant4SensitiveDetector::Initialize(G4HCofThisEvent* HCE) { - int count = 0; - m_hce = HCE; - for (G4CollectionNameVector::const_iterator i = collectionName.begin(); i != collectionName.end(); ++i, ++count) { - G4VHitsCollection* c = createCollection(*i); - m_hce->AddHitsCollection(GetCollectionID(count), c); - } -} - -/// Method invoked at the end of each event. -void Geant4SensitiveDetector::EndOfEvent(G4HCofThisEvent* /* HCE */) { - m_hce = 0; - // Eventuall print event summary -} - -/// Method for generating hit(s) using the information of G4Step object. -G4bool Geant4SensitiveDetector::ProcessHits(G4Step* step, G4TouchableHistory* hist) { - return process(step, hist); -} - -/// Method for generating hit(s) using the information of G4Step object. -G4bool Geant4SensitiveDetector::process(G4Step* step, G4TouchableHistory* hist) { - double ene_cut = m_sensitive.energyCutoff(); - if (step->GetTotalEnergyDeposit() > ene_cut) { - if (!Geant4Hit::isGeantino(step->GetTrack())) { -#if DEBUG - dumpStep(step, hist); -#endif - return buildHits(step, hist); - } - } -#if DEBUG - std::cout << " *** too small energy deposit : " << step->GetTotalEnergyDeposit() - << " < " << ene_cut << " at " << step->GetPreStepPoint()->GetPosition() << std::endl; -#endif - return false; -} - -/// Retrieve the hits collection associated with this detector by its collection identifier -Geant4SensitiveDetector::HitCollection* Geant4SensitiveDetector::collectionByID(int id) { - HitCollection* hc = (HitCollection*) m_hce->GetHC(id); - if (hc) - return hc; - throw runtime_error("The collection index for subdetector " + name() + " is wrong!"); -} - -/// Retrieve the hits collection associated with this detector by its serial number -Geant4SensitiveDetector::HitCollection* Geant4SensitiveDetector::collection(int which) { - size_t w = which; - if (w < collectionName.size()) { - HitCollection* hc = (HitCollection*) m_hce->GetHC(GetCollectionID(which)); - if (hc) - return hc; - throw runtime_error("The collection index for subdetector " + name() + " is wrong!"); - } - throw runtime_error("The collection name index for subdetector " + name() + " is out of range!"); -} - -/// Method is invoked if the event abortion is occured. -void Geant4SensitiveDetector::clear() { -} - -/// Dump Step information (careful: very verbose) -void Geant4SensitiveDetector::dumpStep(G4Step* st, G4TouchableHistory* /* history */) { - Geant4StepHandler step(st); - Geant4Mapping& cnv = Geant4Mapping::instance(); - Position pos1 = step.prePos(); - Position pos2 = step.postPos(); - Momentum mom = step.postMom(); - - printout(INFO, "G4Step", " Track:%08ld Pos:(%8f %8f %8f) -> (%f %f %f) Mom:%7.0f %7.0f %7.0f", - long(step.track), pos1.X(), - pos1.Y(), pos1.Z(), pos2.X(), pos2.Y(), pos2.Z(), mom.X(), mom.Y(), mom.Z()); - printout(INFO, "G4Step", " pre-Vol: %s Status:%s", - step.preVolume()->GetName().c_str(), step.preStepStatus()); - printout(INFO, "G4Step", " post-Vol:%s Status:%s", - step.postVolume()->GetName().c_str(), - step.postStepStatus()); - - const G4VPhysicalVolume* pv = step.volume(step.post); - - typedef Geant4GeometryMaps::PlacementMap Places; - const Places& places = cnv.data().g4Placements; - - for (const auto& i : places ) { - const G4VPhysicalVolume* pl = i.second; - const G4VPhysicalVolume* qv = pl; - if (qv == pv) { - const TGeoNode* tpv = i.first.ptr(); - printf(" Found TGeoNode:%s!\n", tpv->GetName()); - } - } -} - -long long Geant4SensitiveDetector::getVolumeID(G4Step* aStep) { - Geant4StepHandler step(aStep); - Geant4VolumeManager volMgr = Geant4Mapping::instance().volumeManager(); - VolumeID id = volMgr.volumeID(step.preTouchable()); - -#if 0 // additional checks ... - const G4VPhysicalVolume* g4v = step.volume( step.pre ); - - if ( id == Geant4VolumeManager::InvalidPath ) { - ::printf(" --> Severe ERROR: Invalid placement path: touchable corrupted?\n"); - } - else if ( id == Geant4VolumeManager::Insensitive ) { - ::printf(" --> WARNING: Only sensitive volumes may be decoded. %s\n" , g4v->GetName().c_str() ); - } - else if ( id == Geant4VolumeManager::NonExisting ) { - ::printf(" --> WARNING: non existing placement path.\n"); - } - else { - - std::stringstream str; - Geant4VolumeManager::VolIDDescriptor dsc; - Geant4VolumeManager::VolIDFields& fields = dsc.second; - volMgr.volumeDescriptor( step.preTouchable(), dsc ); - for(Geant4VolumeManager::VolIDFields::iterator i=fields.begin(); i!=fields.end();++i) { - str << (*i).first->name() << "=" << (*i).second << " "; - } - ::printf(" --> CellID: %X [%X] -> %s\n",id,dsc.first,str.str().c_str()); - } -#endif - return id; -} - - -long long Geant4SensitiveDetector::getCellID(G4Step* step) { - StepHandler h(step); - Geant4VolumeManager volMgr = Geant4Mapping::instance().volumeManager(); - VolumeID volID = volMgr.volumeID(h.preTouchable()); - Segmentation seg = m_readout.segmentation(); - if ( seg.isValid() ) { - G4ThreeVector global = 0.5 * ( h.prePosG4()+h.postPosG4()); - G4ThreeVector local = h.preTouchable()->GetHistory()->GetTopTransform().TransformPoint(global); - Position loc(local.x()*MM_2_CM, local.y()*MM_2_CM, local.z()*MM_2_CM); - Position glob(global.x()*MM_2_CM, global.y()*MM_2_CM, global.z()*MM_2_CM); - VolumeID cID = seg.cellID(loc,glob,volID); - return cID; - } - return volID; -} -- GitLab