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