From 3e7e0095e07d08bea94e855c3dfc9c61d05ac7f6 Mon Sep 17 00:00:00 2001
From: Markus Frank <markus.frank@cern.ch>
Date: Fri, 17 Oct 2014 08:26:38 +0000
Subject: [PATCH] Improve DDG4 input handling. Add HepMC ascii reader.

---
 DDCore/include/DD4hep/Primitives.h            |  61 +-
 DDCore/src/XML/XMLElements.cpp                |   2 +-
 DDEve/lcio/LCIOEventHandler.cpp               |   2 -
 DDEve/src/HitActors.cpp                       |  32 +-
 DDG4/examples/readHEPMC.py                    |  32 +
 DDG4/include/DDG4/Factories.h                 |  19 +-
 .../include/DDG4/Geant4DetectorConstruction.h |  39 +-
 DDG4/include/DDG4/Geant4EventAction.h         |  15 +-
 DDG4/include/DDG4/Geant4GeneratorActionInit.h |   4 +-
 DDG4/include/DDG4/Geant4InputAction.h         |  58 +-
 DDG4/include/DDG4/Geant4InteractionMerger.h   |   5 +-
 DDG4/include/DDG4/Geant4Mapping.h             |   5 +
 DDG4/include/DDG4/Geant4ParticleGun.h         |  15 +
 DDG4/include/DDG4/Geant4ParticleHandler.h     |  17 +
 DDG4/include/DDG4/Geant4PrimaryHandler.h      |   5 +-
 DDG4/include/DDG4/Geant4SensDetAction.h       |  18 +-
 DDG4/include/DDG4/Geant4StepHandler.h         |   2 +-
 DDG4/include/DDG4/Geant4UIManager.h           |  11 +-
 DDG4/lcio/Geant4Output2LCIO.cpp               |   2 +-
 DDG4/lcio/HepEventReader.cpp                  | 232 -------
 DDG4/lcio/LCIOConversions.cpp                 |   3 +-
 DDG4/lcio/LCIOEventReader.cpp                 | 127 +++-
 DDG4/lcio/LCIOEventReader.h                   |  41 +-
 DDG4/lcio/LCIOFileReader.cpp                  |  29 +-
 DDG4/lcio/LCIOInputAction.cpp                 | 191 ------
 DDG4/lcio/LCIOStdHepReader.cpp                |  35 +-
 DDG4/plugins/Geant4EscapeCounter.cpp          |   5 +-
 ...Reader.cpp => Geant4EventReaderHepEvt.cpp} |  77 ++-
 DDG4/plugins/Geant4EventReaderHepMC.cpp       | 632 ++++++++++++++++++
 DDG4/plugins/Geant4SensDet.cpp                |  10 +
 DDG4/python/DDG4Dict.C                        |   5 +
 DDG4/src/Geant4Data.cpp                       |   2 +-
 DDG4/src/Geant4DetectorConstruction.cpp       |  98 ++-
 DDG4/src/Geant4Exec.cpp                       |   4 +-
 DDG4/src/Geant4InputAction.cpp                |  61 +-
 DDG4/src/Geant4InteractionVertexSmear.cpp     |   2 -
 DDG4/src/Geant4ParticleHandler.cpp            |  17 +-
 DDG4/src/Geant4SensDetAction.cpp              |   2 +-
 UtilityApps/src/teve_display.cpp              |   2 +-
 cmake/DD4hepConfig.cmake.in                   |   4 +-
 40 files changed, 1307 insertions(+), 616 deletions(-)
 create mode 100644 DDG4/examples/readHEPMC.py
 delete mode 100644 DDG4/lcio/HepEventReader.cpp
 delete mode 100644 DDG4/lcio/LCIOInputAction.cpp
 rename DDG4/plugins/{Geant4HepEventReader.cpp => Geant4EventReaderHepEvt.cpp} (75%)
 create mode 100644 DDG4/plugins/Geant4EventReaderHepMC.cpp

diff --git a/DDCore/include/DD4hep/Primitives.h b/DDCore/include/DD4hep/Primitives.h
index 18559678d..719de23fa 100644
--- a/DDCore/include/DD4hep/Primitives.h
+++ b/DDCore/include/DD4hep/Primitives.h
@@ -149,6 +149,29 @@ namespace DD4hep {
     }
   };
 
+  /// Operator to select second element of a pair
+  template <typename T> struct Select2nd  {
+    typedef T arg_t;
+    typedef typename T::second_type result_t;
+    /// Operator function
+    const result_t& operator()(const arg_t &p) const { return p.second; }
+  };
+  /// Generator to create Operator to select value elements of a map
+  template <typename T> Select2nd<typename T::value_type> select2nd(const T&)
+    { return Select2nd<typename T::value_type>(); }
+
+  /// Operator to select the first element of a pair
+  template <typename T> struct Select1st  {
+    typedef T arg_t;
+    typedef typename T::first_type result_t;
+    /// Operator function
+    const result_t& operator()(const arg_t &p) const { return p.first; }
+  };
+  /// Generator to create Operator to select key values of a map
+  template <typename T> Select1st<typename T::value_type> select1st(const T&) 
+    { return Select1st<typename T::value_type>(); }
+
+
   /// map Functor to delete objects from heap
   template <typename M> struct DestroyObjects {
     M& object;
@@ -168,6 +191,9 @@ namespace DD4hep {
   template <typename M> DestroyObjects<M> destroyObjects(M& m) {
     return DestroyObjects<M>(m);
   }
+  template <typename M> DestroyObjects<M> destroy2nd(M& m) {
+    return DestroyObjects<M>(m);
+  }
 
   /// map Functor to delete objects from heap
   template <typename M> struct DestroyFirst {
@@ -188,6 +214,9 @@ namespace DD4hep {
   template <typename M> DestroyFirst<M> destroyFirst(M& m) {
     return DestroyFirst<M>(m);
   }
+  template <typename M> DestroyFirst<M> destroy1st(M& m) {
+    return DestroyFirst<M>(m);
+  }
 
   /// Helper to delete objects from heap and reset the pointer. Saves many many lines of code
   template <typename T> inline void releasePtr(T*& p) {
@@ -196,13 +225,13 @@ namespace DD4hep {
     p = 0;
   }
 
-  /// Functor to delete objects from heap and reset the pointer
+  /// Functor to release objects from heap and reset the pointer
   template <typename T> struct ReleaseObject {
     void operator()(T& p) const {
       releasePtr(p);
     }
   };
-  /// map Functor to delete objects from heap
+  /// Map Functor to release objects from heap
   template <typename M> struct ReleaseObjects {
     M& object;
     ReleaseObjects(M& m)
@@ -218,9 +247,37 @@ namespace DD4hep {
       for_each(object.begin(),object.end(),(*this));
     }
   };
+  template <typename M> ReleaseObject<typename M::value_type> releaseObject(M&) {
+    return ReleaseObject<typename M::value_type>();
+  }
   template <typename M> ReleaseObjects<M> releaseObjects(M& m) {
     return ReleaseObjects<M>(m);
   }
+  template <typename M> ReleaseObjects<M> release2nd(M& m) {
+    return ReleaseObjects<M>(m);
+  }
+
+  /// Functor to delete objects from heap and reset the pointer
+  template <typename T> struct ReferenceObject {
+    typedef T arg_t;
+    T operator()(T p) const {
+      if ( p ) p->addRef();
+      return p;
+    }
+  };
+  /// Functor to delete objects from heap and reset the pointer
+  template <typename M> struct ReferenceObjects {
+    typedef typename M::second_type result_t;
+    result_t operator()(const M& p) const {
+      return ReferenceObject<result_t>()(p.second);
+    }
+  };
+  template <typename M> ReferenceObject<M> referenceObject(M&) {
+    return ReferenceObject<typename M::value_type>();
+  }
+  template <typename M> ReferenceObjects<typename M::value_type> reference2nd(M&) {
+    return ReferenceObjects<typename M::value_type>();
+  }
 
 
   /// Data structure to manipulate a bitmask held by reference and represented by an integer
diff --git a/DDCore/src/XML/XMLElements.cpp b/DDCore/src/XML/XMLElements.cpp
index 246c3a236..441d14853 100644
--- a/DDCore/src/XML/XMLElements.cpp
+++ b/DDCore/src/XML/XMLElements.cpp
@@ -889,8 +889,8 @@ static unsigned int adler32(unsigned int adler, const XmlChar* xml_buff, size_t
 /// Checksum (sub-)tree of a xml document/tree
 typedef unsigned int (fcn_t)(unsigned int, const XmlChar*, size_t);
 unsigned int Handle_t::checksum(unsigned int param, fcn_t fcn) const {
-  typedef std::map<std::string, std::string> StringMap;
 #ifdef DD4HEP_USE_TINYXML
+  typedef std::map<std::string, std::string> StringMap;
   TiXmlNode* n = Xml(m_node).n;
   if ( n ) {
     if ( 0 == fcn ) fcn = adler32;
diff --git a/DDEve/lcio/LCIOEventHandler.cpp b/DDEve/lcio/LCIOEventHandler.cpp
index d5a2c7e9c..bfee6b19f 100644
--- a/DDEve/lcio/LCIOEventHandler.cpp
+++ b/DDEve/lcio/LCIOEventHandler.cpp
@@ -99,7 +99,6 @@ EventHandler::CollectionType LCIOEventHandler::collectionType(const std::string&
 
 /// Call functor on hit collection
 size_t LCIOEventHandler::collectionLoop(const std::string& collection, DDEveHitActor& actor)   {
-  typedef std::vector<void*> _P;
   Branches::const_iterator i = m_branches.find(collection);
   if ( i != m_branches.end() )   {
     LCCollection* c = (*i).second;
@@ -121,7 +120,6 @@ size_t LCIOEventHandler::collectionLoop(const std::string& collection, DDEveHitA
 
 /// Loop over collection and extract particle data
 size_t LCIOEventHandler::collectionLoop(const std::string& collection, DDEveParticleActor& actor)    {
-  typedef std::vector<void*> _P;
   Branches::const_iterator i = m_branches.find(collection);
   if ( i != m_branches.end() )   {
     LCCollection* c = (*i).second;
diff --git a/DDEve/src/HitActors.cpp b/DDEve/src/HitActors.cpp
index 3b630850b..f76a48d95 100644
--- a/DDEve/src/HitActors.cpp
+++ b/DDEve/src/HitActors.cpp
@@ -122,14 +122,14 @@ void BoxsetCreator::operator()(const DDEveHit& hit)   {
   float s2Y =  0.5*(scale(0)*std::cos(phi)+scale(2)*std::sin(phi));
   float s1Z =  scale(1)/2.0;
   float s2Z = s1Z;
-  float coords[24]= { p.X()+s1X, p.Y()+s1Y, p.Z()-s1Z,
-		      p.X()+s1X, p.Y()+s1Y, p.Z()+s1Z,
-		      p.X()-s2X, p.Y()-s2Y, p.Z()+s2Z,
-		      p.X()-s2X, p.Y()-s2Y, p.Z()-s2Z,
-		      p.X()+s2X, p.Y()+s2Y, p.Z()-s2Z,
-		      p.X()+s2X, p.Y()+s2Y, p.Z()+s2Z,
-		      p.X()-s1X, p.Y()-s1Y, p.Z()+s1Z,
-		      p.X()-s1X, p.Y()-s1Y, p.Z()-s1Z};
+  float coords[24]= { float(p.X()+s1X), float(p.Y()+s1Y), float(p.Z()-s1Z),
+		      float(p.X()+s1X), float(p.Y()+s1Y), float(p.Z()+s1Z),
+		      float(p.X()-s2X), float(p.Y()-s2Y), float(p.Z()+s2Z),
+		      float(p.X()-s2X), float(p.Y()-s2Y), float(p.Z()-s2Z),
+		      float(p.X()+s2X), float(p.Y()+s2Y), float(p.Z()-s2Z),
+		      float(p.X()+s2X), float(p.Y()+s2Y), float(p.Z()+s2Z),
+		      float(p.X()-s1X), float(p.Y()-s1Y), float(p.Z()+s1Z),
+		      float(p.X()-s1X), float(p.Y()-s1Y), float(p.Z()-s1Z) };
   ++count;
   deposit += hit.deposit*MEV_2_GEV;
   boxset->AddBox(coords);
@@ -149,14 +149,14 @@ void TowersetCreator::operator()(const DDEveHit& hit)   {
   float s1Z =  scale(1)/2.0;
   float s2Z = s1Z;
   p = TVector3(hit.x*MM_2_CM-s1X, hit.y*MM_2_CM-s1Y, hit.z*MM_2_CM-s1Z);
-  float coords[24]= { p.X()+s1X, p.Y()+s1Y, p.Z()-s1Z,
-		      p.X()+s1X, p.Y()+s1Y, p.Z()+s1Z,
-		      p.X()-s2X, p.Y()-s2Y, p.Z()+s2Z,
-		      p.X()-s2X, p.Y()-s2Y, p.Z()-s2Z,
-		      p.X()+s2X, p.Y()+s2Y, p.Z()-s2Z,
-		      p.X()+s2X, p.Y()+s2Y, p.Z()+s2Z,
-		      p.X()-s1X, p.Y()-s1Y, p.Z()+s1Z,
-		      p.X()-s1X, p.Y()-s1Y, p.Z()-s1Z};
+  float coords[24]= { float(p.X()+s1X), float(p.Y()+s1Y), float(p.Z()-s1Z),
+		      float(p.X()+s1X), float(p.Y()+s1Y), float(p.Z()+s1Z),
+		      float(p.X()-s2X), float(p.Y()-s2Y), float(p.Z()+s2Z),
+		      float(p.X()-s2X), float(p.Y()-s2Y), float(p.Z()-s2Z),
+		      float(p.X()+s2X), float(p.Y()+s2Y), float(p.Z()-s2Z),
+		      float(p.X()+s2X), float(p.Y()+s2Y), float(p.Z()+s2Z),
+		      float(p.X()-s1X), float(p.Y()-s1Y), float(p.Z()+s1Z),
+		      float(p.X()-s1X), float(p.Y()-s1Y), float(p.Z()-s1Z) };
   ++count;
   deposit += hit.deposit*MEV_2_GEV;
   boxset->AddBox(coords);
diff --git a/DDG4/examples/readHEPMC.py b/DDG4/examples/readHEPMC.py
new file mode 100644
index 000000000..1098db629
--- /dev/null
+++ b/DDG4/examples/readHEPMC.py
@@ -0,0 +1,32 @@
+#
+#
+import os, time, DDG4
+from DDG4 import OutputLevel as Output
+from SystemOfUnits import *
+#
+#
+"""
+
+DD4hep simulation example setup using the python configuration
+
+@author  M.Frank
+@version 1.0
+
+"""
+def run():
+  kernel = DDG4.Kernel()
+  lcdd = kernel.lcdd()
+  simple = DDG4.Simple(kernel)
+
+  gen = DDG4.GeneratorAction(kernel,"Geant4InputAction/Input")
+  kernel.generatorAction().adopt(gen)
+  gen.Input = "Geant4EventReaderHepMC|/home/frankm/SW/data/data.hepmc.txt";
+  parts = gen.new_particles()
+  gen.readParticles(0,parts);
+  parts.clear()
+  print 132*'*'
+  print 132*'*'
+  gen.readParticles(1,parts);
+
+if __name__ == "__main__":
+  run()
diff --git a/DDG4/include/DDG4/Factories.h b/DDG4/include/DDG4/Factories.h
index 99fa0fdc7..200d7e501 100644
--- a/DDG4/include/DDG4/Factories.h
+++ b/DDG4/include/DDG4/Factories.h
@@ -9,9 +9,7 @@
 #ifndef DDG4_FACTORIES_H
 #define DDG4_FACTORIES_H
 
-#ifndef __CINT__
-#include "Reflex/PluginService.h"
-#endif
+#include "DD4hep/Plugins.h"
 #include "RVersion.h"
 
 // Framework include files
@@ -45,6 +43,7 @@ namespace DD4hep {
     class Geant4Converter;
     class Geant4Sensitive;
     class Geant4UserPhysics;
+    class Geant4EventReader;
     class Geant4PhysicsListActionSequence;
 
     /// Templated factory method to invoke setup action
@@ -162,6 +161,12 @@ namespace {
     }
   };
 
+  /// Factory template to create Geant4 event reader objects
+  template <typename P> class Factory<P, DD4hep::Simulation::Geant4EventReader*(std::string)> {  public:
+    static void Func(void *ret, void*, const std::vector<void*>& a, void*) 
+    { *(DD4hep::Simulation::Geant4EventReader**)ret = (DD4hep::Simulation::Geant4EventReader*)new P(*(std::string*)a[0]);}
+  };
+
 }
 
 #define DECLARE_EXTERNAL_GEANT4SENSITIVEDETECTOR(name,func) \
@@ -213,4 +218,12 @@ namespace {
   template <> long Geant4SetupAction<DD4hep::Simulation::xml_g4_setup_##name>::create(LCDD& l,const DD4hep::Simulation::Geant4Converter& e, const std::map<std::string,std::string>& a) {return func(l,e,a);} }} \
   PLUGINSVC_FACTORY_WITH_ID(xml_g4_setup_##name,std::string(#name "_Geant4_action"),long(DD4hep::Geometry::LCDD*,const DD4hep::Simulation::Geant4Converter*,const std::map<std::string,std::string>*))
 
+/// Plugin defintion to create event reader objects
+#define DECLARE_GEANT4_EVENT_READER(name)  \
+  PLUGINSVC_FACTORY_WITH_ID(name,std::string(#name),DD4hep::Simulation::Geant4EventReader*(std::string))
+
+/// Plugin defintion to create event reader objects
+#define DECLARE_GEANT4_EVENT_READER_NS(ns,name) typedef ns::name __##name##__; \
+  PLUGINSVC_FACTORY_WITH_ID(__##name##__,std::string(#name),DD4hep::Simulation::Geant4EventReader*(std::string))
+
 #endif // DDG4_FACTORIES_H
diff --git a/DDG4/include/DDG4/Geant4DetectorConstruction.h b/DDG4/include/DDG4/Geant4DetectorConstruction.h
index 0d127d732..61ada9413 100644
--- a/DDG4/include/DDG4/Geant4DetectorConstruction.h
+++ b/DDG4/include/DDG4/Geant4DetectorConstruction.h
@@ -8,7 +8,12 @@
 #ifndef DD4HEP_GEANT4DETECTORCONSTRUCTION_H
 #define DD4HEP_GEANT4DETECTORCONSTRUCTION_H
 
+// Framework include files
 #include "DD4hep/Printout.h"
+#include "DDG4/Geant4Action.h"
+#include "DDG4/Geant4GeometryInfo.h"
+
+// Geant4 include files
 #include "G4VUserDetectorConstruction.hh"
 
 /// Namespace for the AIDA detector description toolkit
@@ -27,21 +32,51 @@ namespace DD4hep {
 
     /// Class to create Geant4 detector geometry from TGeo representation in memory
     /**
+     *  On demand (ie. when calling "Construct") the DD4hep geometry is converted
+     *  to Geant4 with all volumes, assemblies, shapes, materials etc. 
+     *  The actuak work is performed by the Geant4Converter class called by this method.
+     *
      *  \author  M.Frank
      *  \version 1.0
      *  \ingroup DD4HEP_SIMULATION
      */
-    class Geant4DetectorConstruction : public G4VUserDetectorConstruction {
+    class Geant4DetectorConstruction : public Geant4Action, public G4VUserDetectorConstruction {
     public:
+      /// Instance accessor
+      static Geant4DetectorConstruction* instance(Geant4Kernel& kernel);
       /// Initializing constructor for DDG4
       Geant4DetectorConstruction(Geant4Kernel& kernel);
       /// Initializing constructor for other clients
       Geant4DetectorConstruction(Geometry::LCDD& lcdd);
       /// Default destructor
       virtual ~Geant4DetectorConstruction();
-      /// Geometry construction callback
+      /// Geometry construction callback: Invoke the conversion to Geant4
       G4VPhysicalVolume* Construct();
 
+      //@{ Accessor to the various geant4 maps after construction
+
+      /// Access to the converted materials
+      const Geant4GeometryMaps::MaterialMap& materials() const;
+      /// Access to the converted elements
+      const Geant4GeometryMaps::ElementMap& elements() const;
+      /// Access to the converted shapes
+      const Geant4GeometryMaps::SolidMap& shapes() const;
+      /// Access to the converted volumes
+      const Geant4GeometryMaps::VolumeMap& volumes() const;
+      /// Access to the converted placements
+      const Geant4GeometryMaps::PlacementMap& placements() const;
+      /// Access to the converted assemblys
+      const Geant4GeometryMaps::AssemblyMap& assemblies() const;
+
+      /// Access to the converted limit sets
+      const Geant4GeometryMaps::LimitMap& limits() const;
+      /// Access to the converted regions
+      const Geant4GeometryMaps::RegionMap& regions() const;
+      /// Access to the converted sensitive detectors
+      const Geant4GeometryMaps::SensDetMap& sensitives() const;
+
+      //@}
+
     private:
       /// Printlevel used for the geometry conversion
       PrintLevel m_outputLevel;
diff --git a/DDG4/include/DDG4/Geant4EventAction.h b/DDG4/include/DDG4/Geant4EventAction.h
index 071f8ba5b..f9866c3d7 100644
--- a/DDG4/include/DDG4/Geant4EventAction.h
+++ b/DDG4/include/DDG4/Geant4EventAction.h
@@ -24,10 +24,17 @@ namespace DD4hep {
     /// Concrete basic implementation of the Geant4 event action
     /**
      * The EventAction is called for every event.
-     * During the callback all particles are created which form the 
-     * microscopic kinematic action of the particle collision.
-     * This input may either origin directly from an event generator 
-     * program or come from file.
+     *
+     * This class is the base class for all user actions, which have
+     * to hook into the begin- and end-of-event actions.
+     * Typical use cases are the collection/computation of event
+     * related properties.
+     *
+     * Examples of this functionality may include for example:
+     * - Reset variables summing event related information in the
+     *   begin-event callback.
+     * - Monitoring activities such as filling histograms
+     *   from hits collected during the end-event action.
      *
      *  \author  M.Frank
      *  \version 1.0
diff --git a/DDG4/include/DDG4/Geant4GeneratorActionInit.h b/DDG4/include/DDG4/Geant4GeneratorActionInit.h
index dda4dc771..706c6b42b 100644
--- a/DDG4/include/DDG4/Geant4GeneratorActionInit.h
+++ b/DDG4/include/DDG4/Geant4GeneratorActionInit.h
@@ -36,9 +36,9 @@ namespace DD4hep {
      *  -- Geant4PrimaryInteraction containing the track/vertex information to create 
      *     the primary particles for Geant4. This record is build from the Geant4PrimaryEvent
      *     information.
-     *  -- Geant4PrimaryMap a map of the GEant4Particles converted to G4PrimaryParticles
+     *  -- Geant4PrimaryMap a map of the Geant4Particles converted to G4PrimaryParticles
      *     to ease particle handling later.
-     *  -- Geant4ParticleMap the map of partcles created during the event simulation.
+     *  -- Geant4ParticleMap the map of particles created during the event simulation.
      *     This map has directly the correct particle offsets, so that the merging of
      *     Geant4PrimaryInteraction particles and the simulation particles is easy....
      *    
diff --git a/DDG4/include/DDG4/Geant4InputAction.h b/DDG4/include/DDG4/Geant4InputAction.h
index faa7ef808..ba4912828 100644
--- a/DDG4/include/DDG4/Geant4InputAction.h
+++ b/DDG4/include/DDG4/Geant4InputAction.h
@@ -13,6 +13,7 @@
 
 // C/C++ include files
 #include <vector>
+#include <memory>
 
 // Forward declarations
 class G4Event;
@@ -36,12 +37,23 @@ namespace DD4hep  {
 
     public:
       typedef Geant4Particle Particle;
+      typedef std::vector<Particle*> Particles;
+      /// Status codes of the event reader object. Anything with NOT low-bit set is an error.
+      enum EventReaderStatus { 
+	EVENT_READER_ERROR=0,
+	EVENT_READER_OK=1,
+	EVENT_READER_NO_DIRECT=2,
+	EVENT_READER_NO_PRIMARIES=4,
+	EVENT_READER_NO_FACTORY=6,
+	EVENT_READER_IO_ERROR=8
+      };
     protected:
-      /// File name
+      /// File name to be opened and read
       std::string m_name;
-      /// Flag if direct event access is supported
+      /// Flag if direct event access is supported. To be explicitly set by subclass constructors
       bool m_directAccess;
-
+      /// Current event number
+      int  m_currEvent;
     public:
       /// Initializing constructor
       Geant4EventReader(const std::string& nam);
@@ -51,8 +63,21 @@ namespace DD4hep  {
       const std::string& name()  const   {  return m_name;   }
       /// Flag if direct event access (by event sequence number) is supported (Default: false)
       bool hasDirectAccess() const  {  return m_directAccess; }
+      /// Move to the indicated event number.
+      /** For pure sequential access, the default implementation 
+       *  will skip events one by one.
+       *  For technologies supporting direct event access the default
+       *  implementation will be empty.
+       *
+       *  @return 
+       */
+      virtual EventReaderStatus moveToEvent(int event_number);
+      /// Skip event. To be implemented for sequential sources
+      virtual EventReaderStatus skipEvent();
       /// Read an event and fill a vector of MCParticles.
-      virtual int readParticles(int event_number, std::vector<Particle*>& particles) = 0;
+      /** The additional argument 
+       */
+      virtual EventReaderStatus readParticles(int event_number, Particles& particles) = 0;
     };
 
     /// Generic input action capable of using the Geant4EventReader class.
@@ -69,7 +94,7 @@ namespace DD4hep  {
 
     public:
       typedef Geant4Particle Particle;
-
+      typedef std::vector<Particle*> Particles;
     protected:
       /// Property: input file
       std::string         m_input;
@@ -82,36 +107,21 @@ namespace DD4hep  {
       /// Event reader object
       Geant4EventReader*  m_reader;
 
+    public:
       /// Read an event and return a LCCollectionVec of MCParticles.
-      int readParticles(int event_number, std::vector<Particle*>& particles);
+      int readParticles(int event_number, Particles& particles);
       /// helper to report Geant4 exceptions
       std::string issue(int i) const;
 
-    public:
       /// Standard constructor
       Geant4InputAction(Geant4Context* context, const std::string& name);
       /// Default destructor
       virtual ~Geant4InputAction();
+      /// Create particle vector
+      Particles* new_particles() const { return new Particles; }
       /// Callback to generate primary particles
       virtual void operator()(G4Event* event);
     };
   }     /* End namespace Simulation   */
 }       /* End namespace DD4hep */
-
-#include "DD4hep/Plugins.h"
-namespace {
-  /// Factory template to create Geant4 event reader objects
-  template <typename P> class Factory<P, DD4hep::Simulation::Geant4EventReader*(std::string)> {  public:
-    static void Func(void *ret, void*, const std::vector<void*>& a, void*) 
-    { *(DD4hep::Simulation::Geant4EventReader**)ret = (DD4hep::Simulation::Geant4EventReader*)new P(*(std::string*)a[0]);}
-  };
-}
-/// Plugin defintion to create event reader objects
-#define DECLARE_GEANT4_EVENT_READER(name)					\
-  PLUGINSVC_FACTORY_WITH_ID(name,std::string(#name),DD4hep::Simulation::Geant4EventReader*(std::string))
-
-/// Plugin defintion to create event reader objects
-#define DECLARE_GEANT4_EVENT_READER_NS(ns,name) typedef ns::name __##name##__; \
-  PLUGINSVC_FACTORY_WITH_ID(__##name##__,std::string(#name),DD4hep::Simulation::Geant4EventReader*(std::string))
-
 #endif  /* DD4HEP_DDG4_GEANT4INPUTACTION_H  */
diff --git a/DDG4/include/DDG4/Geant4InteractionMerger.h b/DDG4/include/DDG4/Geant4InteractionMerger.h
index 32c97877a..6e2009c3c 100644
--- a/DDG4/include/DDG4/Geant4InteractionMerger.h
+++ b/DDG4/include/DDG4/Geant4InteractionMerger.h
@@ -22,7 +22,10 @@ namespace DD4hep {
     class Geant4PrimaryInteraction;
 
     /// Geant4Action to merge several independent interaction to one
-    /** Geant4Action to convert the particle information to Geant4
+    /** Merge all interactions created by each \tt{Geant4InputAction} into one single
+     *  record. The input records are taken from the item \tt{Geant4PrimaryEvent}
+     *  and are merged into the \tt{Geant4PrimaryInteraction} object attached to the
+     *  \tt{Geant4Event} event context.
      *
      *  \author  M.Frank
      *  \version 1.0
diff --git a/DDG4/include/DDG4/Geant4Mapping.h b/DDG4/include/DDG4/Geant4Mapping.h
index c5c54f2c5..060efd4a8 100644
--- a/DDG4/include/DDG4/Geant4Mapping.h
+++ b/DDG4/include/DDG4/Geant4Mapping.h
@@ -67,6 +67,11 @@ namespace DD4hep {
         return *m_dataPtr;
       }
 
+      /// Access to the data pointer
+      Geant4GeometryInfo* ptr() const {
+        return m_dataPtr;
+      }
+
       /// Create and attach new data block. Delete old data block if present.
       Geant4GeometryInfo& init();
 
diff --git a/DDG4/include/DDG4/Geant4ParticleGun.h b/DDG4/include/DDG4/Geant4ParticleGun.h
index efc9734f0..0e620e86c 100644
--- a/DDG4/include/DDG4/Geant4ParticleGun.h
+++ b/DDG4/include/DDG4/Geant4ParticleGun.h
@@ -23,6 +23,21 @@ namespace DD4hep {
 
     /// Implementation of a particle gun using Geant4Particles.
     /** 
+     *  The {\tt{Geant4ParticleGun}} is a tool to shoot a number of
+     *  particles with identical properties into a given region of the
+     *  detector to be simulated.
+     *
+     *  The particle gun is a input source like any other and participates 
+     *  in the general input stage merging process like any other input 
+     *  e.g. from file. Hence, there may be several particle guns present
+     *  each generating it's own primary vertex. Use the mask property to
+     *  ensure each gun generates it's own, well identified primary vertex.
+     *
+     *  There is one 'user lazyness' support though:
+     *  If there is only one particle gun in use, the property 'Standalone', 
+     *  which by default is set to true invokes the interaction merging and he 
+     *  Geant4 primary generation directly.
+     *
      *  \author  M.Frank
      *  \version 1.0
      *  \ingroup DD4HEP_SIMULATION
diff --git a/DDG4/include/DDG4/Geant4ParticleHandler.h b/DDG4/include/DDG4/Geant4ParticleHandler.h
index 4c64b7a20..9844eb836 100644
--- a/DDG4/include/DDG4/Geant4ParticleHandler.h
+++ b/DDG4/include/DDG4/Geant4ParticleHandler.h
@@ -33,6 +33,23 @@ namespace DD4hep {
     /**
      *  Extract the relevant particle information during the simulation step.
      *
+     *  This procedure works as follows:
+     *  -- At the beginning of the event generation the object registers itself as 
+     *    Monte-Carlo truth handler to the event context.
+     *  -- At the begin of each track action a particle candidate is created and filled
+     *     with all properties known at this time.
+     *  -- At each stepping action a flag is set if the step produced secondaries.
+     *  -- Sensitive detectors call the MC truth handler if a hit was created.
+     *    This fact is remembered.
+     *  -- At the end of the tracking action a first decision is taken if the candidate is to be 
+     *    kept for the final record.
+     *  -- At the end of the event action finally all particles are reduced to the 
+     *    final record. This logic can be overridden by a user handler to be attached.
+     *  .
+     *  Any of these actions may be intercepted by a {\tt{Geant4UserParticleHandler}}
+     *  attached to the particle handler.
+     *  See class {\tt{Geant4UserParticleHandler}} for details.
+     *
      *  \author  M.Frank
      *  \version 1.0
      *  \ingroup DD4HEP_SIMULATION
diff --git a/DDG4/include/DDG4/Geant4PrimaryHandler.h b/DDG4/include/DDG4/Geant4PrimaryHandler.h
index 0ea34e2d2..202e12327 100644
--- a/DDG4/include/DDG4/Geant4PrimaryHandler.h
+++ b/DDG4/include/DDG4/Geant4PrimaryHandler.h
@@ -19,7 +19,10 @@ namespace DD4hep {
   namespace Simulation {
 
     /// Geant4Action to convert the particle information to Geant4
-    /**
+    /** Convert the primary interaction (object \tt{Geant4PrimaryInteraction} object 
+     *  attached to the \tt{Geant4Event} event context) and pass the result
+     *  to Geant4 for simulation.
+     *
      *  \author  M.Frank
      *  \version 1.0
      *  \ingroup DD4HEP_SIMULATION
diff --git a/DDG4/include/DDG4/Geant4SensDetAction.h b/DDG4/include/DDG4/Geant4SensDetAction.h
index 70f8a96fd..c440b5dee 100644
--- a/DDG4/include/DDG4/Geant4SensDetAction.h
+++ b/DDG4/include/DDG4/Geant4SensDetAction.h
@@ -32,6 +32,7 @@ namespace DD4hep {
   namespace Geometry  {
     class LCDD;
     class DetElement;
+    class SensitiveDetector;
   }
 
   /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
@@ -57,6 +58,9 @@ namespace DD4hep {
       /// Default destructor
       virtual ~Geant4ActionSD();
     public:
+      /// Definition: Sensitive detector type
+      typedef Geometry::SensitiveDetector SensitiveDetector;
+
       /// Initialize the usage of a hit collection. Returns the collection identifier
       virtual size_t defineCollection(const std::string& name) = 0;
       /// Access to the readout geometry of the sensitive detector
@@ -65,10 +69,14 @@ namespace DD4hep {
       virtual G4int GetCollectionID(G4int i) = 0;
       /// Is the detector active?
       virtual bool isActive() const = 0;
+      /// Access to the LCDD sensitive detector handle
+      virtual SensitiveDetector sensitiveDetector() const = 0;
       /// G4VSensitiveDetector internals: Access to the detector path name
       virtual std::string path() const = 0;
       /// G4VSensitiveDetector internals: Access to the detector path name
       virtual std::string fullPath() const = 0;
+      /// Access to the sensitive type of the detector
+      virtual const std::string& sensitiveType() const = 0;
     };
 
     /// Base class to construct filters for Geant4 sensitive detectors
@@ -99,7 +107,9 @@ namespace DD4hep {
       typedef Geometry::Readout Readout;
       typedef Geometry::DetElement DetElement;
       typedef Geometry::Segmentation Segmentation;
+      /// Definition: Sensitive detector type
       typedef Geometry::SensitiveDetector SensitiveDetector;
+
       typedef Geant4StepHandler StepHandler;
       typedef Geant4HitCollection HitCollection;
 
@@ -284,7 +294,8 @@ namespace DD4hep {
       SensitiveDetector m_sensitive;
       /// Reference to G4 sensitive detector
       Geant4ActionSD* m_detector;
-
+      /// The true sensitive type of the detector
+      std::string m_sensitiveType;
       /// Create a new typed hit collection
       template <typename TYPE> static Geant4HitCollection* _create(const std::string& det, const std::string& coll, Geant4Sensitive* sd) {
         return new Geant4HitCollection(det, coll, sd, (TYPE*) 0);
@@ -297,6 +308,11 @@ namespace DD4hep {
       /// Default destructor
       virtual ~Geant4SensDetActionSequence();
 
+      /// Access to the sensitive type of the detector
+      virtual const std::string& sensitiveType() const   {
+	return m_sensitiveType;
+      }
+
       /// Called at construction time of the sensitive detector to declare all hit collections
       size_t defineCollections(Geant4ActionSD* sens_det);
 
diff --git a/DDG4/include/DDG4/Geant4StepHandler.h b/DDG4/include/DDG4/Geant4StepHandler.h
index 834914bba..b17d69c79 100644
--- a/DDG4/include/DDG4/Geant4StepHandler.h
+++ b/DDG4/include/DDG4/Geant4StepHandler.h
@@ -31,7 +31,7 @@ namespace DD4hep {
     /// Helper class to ease the extraction of information from a G4Step object.
     /**
      *
-     * Tiny helper/utility class to easily access Geant4 step information.
+     * Helper/utility class to easily access Geant4 step information.
      * Born by lazyness: Avoid typing millions of statements!
      *
      *  \author  M.Frank
diff --git a/DDG4/include/DDG4/Geant4UIManager.h b/DDG4/include/DDG4/Geant4UIManager.h
index 26bd64c48..e9e417a13 100644
--- a/DDG4/include/DDG4/Geant4UIManager.h
+++ b/DDG4/include/DDG4/Geant4UIManager.h
@@ -26,10 +26,15 @@ namespace DD4hep {
   namespace Simulation {
 
     /// Standard UI interface implementation with configuration using property options
-    /** @class Geant4UIManager Geant4UIManager.h DDG4/Geant4UIManager.h
+    /** The {\tt{Geant4UIManager}} is a component attached to the {\tt{Geant4Kernel}} object. 
      *
-     * @author  M.Frank
-     * @version 1.0
+     *  All properties of all {\tt{Geant4Action}} instances may be exported to 
+     *  Geant4 messengers and {\em{may}} hence be accessible directly from the Geant4 
+     *  prompt. To export properties from any action, call the {\tt{enableUI()}}
+     *  method of the action.
+     *
+     * \author  M.Frank
+     * \version 1.0
      */
     class Geant4UIManager : public Geant4Action, virtual public Geant4Call   {
     protected:
diff --git a/DDG4/lcio/Geant4Output2LCIO.cpp b/DDG4/lcio/Geant4Output2LCIO.cpp
index aff0ec9ad..4f3544639 100644
--- a/DDG4/lcio/Geant4Output2LCIO.cpp
+++ b/DDG4/lcio/Geant4Output2LCIO.cpp
@@ -183,7 +183,7 @@ lcio::LCCollectionVec* Geant4Output2LCIO::saveParticles(Geant4ParticleMap* parti
       MCParticleImpl* q = new lcio::MCParticleImpl();
       q->setPDG(p->pdgID);
 
-      float ps_fa[3] = { p->psx/GeV, p->psy/GeV, p->psz/GeV } ;  
+      float ps_fa[3] = {float(p->psx/GeV),float(p->psy/GeV),float(p->psz/GeV)};
       q->setMomentum( ps_fa );
 
       double vs_fa[3] = { p->vsx/mm, p->vsy/mm, p->vsz/mm } ;  
diff --git a/DDG4/lcio/HepEventReader.cpp b/DDG4/lcio/HepEventReader.cpp
deleted file mode 100644
index a1124beba..000000000
--- a/DDG4/lcio/HepEventReader.cpp
+++ /dev/null
@@ -1,232 +0,0 @@
-// $Id: Geant4Converter.cpp 603 2013-06-13 21:15:14Z markus.frank $
-//====================================================================
-//  AIDA Detector description implementation for LCD
-//--------------------------------------------------------------------
-//
-//====================================================================
-
-// Framework include files
-#include "LCIOEventReader.h"
-
-// C/C++ include files
-#include <fstream>
-
-/// Namespace for the AIDA detector description toolkit
-namespace DD4hep  {
-
-  /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
-  namespace Simulation  {
-
-    /// File reader to load StdHep format (ASCII)
-    /**
-     * 
-     * Class to populate Geant4 primary particles and vertices from a 
-     * file in HepEvent format (ASCII)
-     *
-     *  \author  P.Kostka (main author)
-     *  \author  M.Frank  (code reshuffeling into new DDG4 scheme)
-     *  \version 1.0
-     *  \ingroup DD4HEP_SIMULATION
-     */
-    class HepEventReader : public LCIOEventReader  {
-    protected:
-      std::ifstream m_input;
-      int m_format;
-    public:
-      /// Initializing constructor
-      HepEventReader(const std::string& nam, int fmt);
-      /// Default destructor
-      virtual ~HepEventReader();
-      /// Read an event and return a LCCollectionVec of MCParticles.
-      virtual EVENT::LCCollection *readParticles();
-    };
-  }     /* End namespace lcio   */
-}       /* End namespace DD4hep */
-
-
-#include "IMPL/LCCollectionVec.h"
-#include "IMPL/MCParticleImpl.h"
-#include "EVENT/LCIO.h"
-#include "lcio.h"
-using namespace IMPL;
-using namespace EVENT;
-using namespace DD4hep::Simulation;
-#define HEPEvt 1
-
-// Factory entry
-DECLARE_LCIO_EVENT_READER(HepEventReader)
-
-/// Initializing constructor
-HepEventReader::HepEventReader(const std::string& nam, int fmt) 
-: LCIOEventReader(nam), m_format(fmt)
-{
-}
-
-/// Default destructor
-HepEventReader::~HepEventReader()    {
-  m_input.close();
-}
-
-/// Helper function
-MCParticleImpl* cast_particle(LCObject* obj)  {
-  return dynamic_cast<MCParticleImpl*>(obj);
-}
-
-/// Read an event and return a LCCollectionVec of MCParticles.
-EVENT::LCCollection *HepEventReader::readParticles()   {
-  static const double c_light = 299.792;// mm/ns
-  //
-  //  Read the event, check for errors
-  //
-  int NHEP;  // number of entries
-  m_input >> NHEP;
-  if( m_input.eof() )   {
-    //
-    // End of File :: ??? Exception ???
-    //   -> FG:   EOF is not an exception as it happens for every file at the end !
-    return 0;
-  }
-    
-  //
-  //  Create a Collection Vector
-  IMPL::LCCollectionVec* mcVec = new IMPL::LCCollectionVec(LCIO::MCPARTICLE);
-  //
-  //  Loop over particles
-  int ISTHEP;   // status code
-  int IDHEP;    // PDG code
-  int JMOHEP1;  // first mother
-  int JMOHEP2;  // last mother
-  int JDAHEP1;  // first daughter
-  int JDAHEP2;  // last daughter
-  double PHEP1; // px in GeV/c
-  double PHEP2; // py in GeV/c
-  double PHEP3; // pz in GeV/c
-  double PHEP4; // energy in GeV
-  double PHEP5; // mass in GeV/c**2
-  double VHEP1; // x vertex position in mm
-  double VHEP2; // y vertex position in mm
-  double VHEP3; // z vertex position in mm
-  double VHEP4; // production time in mm/c
- 
-  //???? Memory leak ?
-  std::vector<int> *daughter1 = new std::vector<int> ();
-  std::vector<int> *daughter2 =  new std::vector<int> ();
- 
-  for( int IHEP=0; IHEP<NHEP; IHEP++ )    {
-    if ( m_format == HEPEvt)
-      m_input >> ISTHEP >> IDHEP >> JDAHEP1 >> JDAHEP2
-	      >> PHEP1 >> PHEP2 >> PHEP3 >> PHEP5;
-    else
-      m_input >> ISTHEP >> IDHEP 
-	      >> JMOHEP1 >> JMOHEP2
-	      >> JDAHEP1 >> JDAHEP2
-	      >> PHEP1 >> PHEP2 >> PHEP3 
-	      >> PHEP4 >> PHEP5
-	      >> VHEP1 >> VHEP2 >> VHEP3
-	      >> VHEP4;
- 
-    if(m_input.eof())
-      return 0;	
-    //
-    //  Create a MCParticle and fill it from stdhep info
-    MCParticleImpl* mcp = new MCParticleImpl();
-    //
-    //  PDGID
-    mcp->setPDG(IDHEP);
-    //
-    //  Momentum vector
-    float p0[3] = {PHEP1,PHEP2,PHEP3};
-    mcp->setMomentum(p0);
-    //
-    //  Mass
-    mcp->setMass(PHEP5);
-    //
-    //  Vertex 
-    // (missing information in HEPEvt files)
-    double v0[3] = {0.,0.,0.};
-    mcp->setVertex(v0);
-    //
-    //  Generator status
-    mcp->setGeneratorStatus(ISTHEP);
-    //
-    //  Simulator status 0 until simulator acts on it
-    mcp->setSimulatorStatus(0);
-    //
-    //  Creation time (note the units)
-    // (No information in HEPEvt files)
-    mcp->setTime(0./c_light);
-    //
-    //  Add the particle to the collection vector
-    mcVec->push_back(mcp);
-    //
-    // Keep daughters information for later
-    daughter1->push_back(JDAHEP1);
-    daughter2->push_back(JDAHEP2);
-  }// End loop over particles
-  //
-  //  Now make a second loop over the particles, checking the daughter
-  //  information. This is not always consistent with parent 
-  //  information, and this utility assumes all parents listed are
-  //  parents and all daughters listed are daughters
-  //
-  for( int IHEP=0; IHEP<NHEP; IHEP++ )    {
-    struct Particle  {
-      MCParticleImpl* m_part;
-      Particle(MCParticleImpl* p) : m_part(p) {}
-      void addParent(MCParticleImpl* p)  {   m_part->addParent(p);	  }
-      MCParticleImpl* findParent(MCParticleImpl* p)  {
-	int np = m_part->getParents().size();
-	for(int ip=0;ip < np;ip++)	      {
-	  MCParticleImpl* q = cast_particle(p->getParents()[ip]);  // cast necessary ? only if virt inheritance 
-	  if ( q == p ) return p;
-	}
-	return 0;
-      }
-    };
-
-    //
-    //  Get the MCParticle
-    //
-    MCParticleImpl* mcp = cast_particle(mcVec->getElementAt(IHEP));
-    //
-    //  Get the daughter information, discarding extra information
-    //  sometimes stored in daughter variables.
-    // 
-    int fd = daughter1->operator[](IHEP) - 1;
-    int ld = daughter2->operator[](IHEP) - 1;
- 
-    //
-    //  As with the parents, look for range, 2 discreet or 1 discreet 
-    //  daughter.
-    if( (fd > -1) && (ld > -1) )  {
-      if(ld >= fd)   {
-	for(int id=fd;id<ld+1;id++)   {
-	  //
-	  //  Get the daughter, and see if it already lists this particle as
-	  //  a parent. If not, add this particle as a parent
-	  //
-	  Particle part(cast_particle(mcVec->getElementAt(id)));
-	  if ( !part.findParent(mcp) ) part.addParent(mcp);
-	}
-      }
-      else  {   //  Same logic, discrete cases
-	Particle part_fd(cast_particle(mcVec->getElementAt(fd)));
-	if ( !part_fd.findParent(mcp) ) part_fd.addParent(mcp);
-
-	Particle part_ld(cast_particle(mcVec->getElementAt(ld)));
-	if ( !part_ld.findParent(mcp) ) part_ld.addParent(mcp);
-      }
-    }
-    else if(fd > -1)      {
-      Particle part(cast_particle(mcVec->getElementAt(fd)));
-      if ( !part.findParent(mcp) ) part.addParent(mcp);
-    }
-    else if(ld > -1)      {
-      Particle part(cast_particle(mcVec->getElementAt(ld)));
-      if ( !part.findParent(mcp) ) part.addParent(mcp);
-    }
-  }  // End second loop over particles
-
-  return mcVec;    
-}
-
diff --git a/DDG4/lcio/LCIOConversions.cpp b/DDG4/lcio/LCIOConversions.cpp
index 03d2611af..d873ae155 100644
--- a/DDG4/lcio/LCIOConversions.cpp
+++ b/DDG4/lcio/LCIOConversions.cpp
@@ -29,6 +29,7 @@
 //
 #include "UTIL/Operators.h"
 #include "UTIL/ILDConf.h"
+
 using namespace std;
 
 //==================================================================================
@@ -170,7 +171,7 @@ namespace DD4hep {
       }
       for(size_t i=0; i<nhits; ++i)   {
 	const Geant4Calorimeter::Hit* hit = coll->hit(i);
-	float pos[3] = {hit->position.x(), hit->position.y(), hit->position.z()};
+	float pos[3] = {float(hit->position.x()), float(hit->position.y()), float(hit->position.z())};
 	lcio::SimCalorimeterHitImpl*  lc_hit = new lcio::SimCalorimeterHitImpl;
 	lc_hit->setCellID0((hit->cellID >>    0       ) & 0xFFFFFFFF); 
 	lc_hit->setCellID1((hit->cellID >> sizeof(int)) & 0xFFFFFFFF); // ???? 
diff --git a/DDG4/lcio/LCIOEventReader.cpp b/DDG4/lcio/LCIOEventReader.cpp
index a4ffa7f2e..f51da1a04 100644
--- a/DDG4/lcio/LCIOEventReader.cpp
+++ b/DDG4/lcio/LCIOEventReader.cpp
@@ -10,11 +10,134 @@
 
 // Framework include files
 #include "LCIOEventReader.h"
+#include "DD4hep/Printout.h"
+#include "DDG4/Geant4Primary.h"
+#include "DDG4/Geant4Context.h"
+#include "DDG4/Factories.h"
+
+#include "G4ParticleTable.hh"
+#include "EVENT/MCParticle.h"
+#include "EVENT/LCCollection.h"
+
+#include "G4Event.hh"
+
+using namespace std;
+using namespace DD4hep;
+using namespace DD4hep::Simulation;
+typedef DD4hep::ReferenceBitMask<int> PropertyMask;
+
+// Neede for backwards compatibility:
+namespace DD4hep{namespace Simulation{typedef Geant4InputAction LCIOInputAction;}}
+DECLARE_GEANT4ACTION(LCIOInputAction)
+
+namespace {
+  inline int GET_ENTRY(const map<EVENT::MCParticle*,int>& mcparts, EVENT::MCParticle* part)  {
+    map<EVENT::MCParticle*,int>::const_iterator ip=mcparts.find(part);
+    if ( ip == mcparts.end() )  {
+      throw runtime_error("Unknown particle identifier look-up!");
+    }
+    return (*ip).second;
+  }
+}
+
 
 /// Initializing constructor
-DD4hep::Simulation::LCIOEventReader::LCIOEventReader(const std::string& nam) : m_name(nam)   {
+LCIOEventReader::LCIOEventReader(const string& nam)
+  : Geant4EventReader(nam), m_numEvent(0)
+{
 }
 
 /// Default destructor
-DD4hep::Simulation::LCIOEventReader::~LCIOEventReader()   {
+LCIOEventReader::~LCIOEventReader()   {
+}
+
+/// Read an event and fill a vector of MCParticles.
+LCIOEventReader::EventReaderStatus
+LCIOEventReader::readParticles(int event_number, vector<Particle*>& particles)   {
+  EVENT::LCCollection*        primaries = 0;
+  map<EVENT::MCParticle*,int> mcparts;
+  vector<EVENT::MCParticle*>  mcpcoll;
+  EventReaderStatus ret = EVENT_READER_OK;
+
+  if ( hasDirectAccess() )  
+    ret = readParticles(event_number,&primaries);
+  else if ( m_numEvent == event_number )
+    ret = readParticles(event_number,&primaries);
+  else
+    ret = EVENT_READER_NO_DIRECT;
+
+  ++m_numEvent;
+  if ( ret != EVENT_READER_OK ) return ret;
+
+  int NHEP = primaries->getNumberOfElements();
+  // check if there is at least one particle
+  if ( NHEP == 0 ) return EVENT_READER_NO_PRIMARIES;
+
+  mcpcoll.resize(NHEP,0);
+  for(int i=0; i<NHEP; ++i ) {
+    EVENT::MCParticle* p=dynamic_cast<EVENT::MCParticle*>(primaries->getElementAt(i));
+    mcparts[p] = i;
+    mcpcoll[i] = p;
+  }
+
+  // build collection of MCParticles
+  G4ParticleTable*      tab = G4ParticleTable::GetParticleTable();
+  for(int i=0; i<NHEP; ++i )   {
+    EVENT::MCParticle* mcp = mcpcoll[i];
+    Geant4ParticleHandle p(new Particle(i));
+    const double *mom   = mcp->getMomentum();
+    const double *vsx   = mcp->getVertex();
+    const double *vex   = mcp->getEndpoint();
+    const float  *spin  = mcp->getSpin();
+    const int    *color = mcp->getColorFlow();
+    G4ParticleDefinition* def = tab->FindParticle(mcp->getPDG());
+    PropertyMask status(p->status);
+    p->pdgID        = mcp->getPDG();
+    p->charge       = int(mcp->getCharge()*3.0);
+    p->psx          = mom[0]*GeV;
+    p->psy          = mom[1]*GeV;
+    p->psz          = mom[2]*GeV;
+    p->time         = mcp->getTime()*ns;
+    p->properTime   = mcp->getTime()*ns;
+    p->vsx          = vsx[0]*mm;
+    p->vsy          = vsx[1]*mm;
+    p->vsz          = vsx[2]*mm;
+    p->vex          = vex[0]*mm;
+    p->vey          = vex[1]*mm;
+    p->vez          = vex[2]*mm;
+    p->definition   = def;
+    p->process      = 0;
+    p->spin[0]      = spin[0];
+    p->spin[1]      = spin[1];
+    p->spin[2]      = spin[2];
+    p->colorFlow[0] = color[0];
+    p->colorFlow[0] = color[1];
+    p->mass         = mcp->getMass()*GeV;
+    const EVENT::MCParticleVec &par = mcp->getParents(), &dau=mcp->getDaughters();
+    for(int num=dau.size(),k=0; k<num; ++k)
+      p->daughters.insert(GET_ENTRY(mcparts,dau[k]));
+    for(int num=par.size(),k=0; k<num; ++k)
+      p->parents.insert(GET_ENTRY(mcparts,par[k]));
+
+    int genStatus = mcp->getGeneratorStatus();
+    if ( genStatus == 0 ) status.set(G4PARTICLE_GEN_EMPTY);
+    else if ( genStatus == 1 ) status.set(G4PARTICLE_GEN_STABLE); 
+    else if ( genStatus == 2 ) status.set(G4PARTICLE_GEN_DECAYED);
+    else if ( genStatus == 3 ) status.set(G4PARTICLE_GEN_DOCUMENTATION);
+    else { 
+      cout << " #### WARNING - LCIOInputAction : unknown generator status : " 
+	   << genStatus << " -> ignored ! " << endl;
+    }
+    if ( mcp->isCreatedInSimulation() )       status.set(G4PARTICLE_SIM_CREATED);
+    if ( mcp->isBackscatter() )               status.set(G4PARTICLE_SIM_BACKSCATTER);
+    if ( mcp->vertexIsNotEndpointOfParent() ) status.set(G4PARTICLE_SIM_PARENT_RADIATED);
+    if ( mcp->isDecayedInTracker() )          status.set(G4PARTICLE_SIM_DECAY_TRACKER);
+    if ( mcp->isDecayedInCalorimeter() )      status.set(G4PARTICLE_SIM_DECAY_CALO);
+    if ( mcp->hasLeftDetector() )             status.set(G4PARTICLE_SIM_LEFT_DETECTOR);
+    if ( mcp->isStopped() )                   status.set(G4PARTICLE_SIM_STOPPED);
+    if ( mcp->isOverlay() )                   status.set(G4PARTICLE_SIM_OVERLAY);
+    particles.push_back(p);
+  }
+  return EVENT_READER_OK;
 }
+
diff --git a/DDG4/lcio/LCIOEventReader.h b/DDG4/lcio/LCIOEventReader.h
index 8cb923d73..5d2e67626 100644
--- a/DDG4/lcio/LCIOEventReader.h
+++ b/DDG4/lcio/LCIOEventReader.h
@@ -7,8 +7,8 @@
 #ifndef DD4HEP_DDG4_LCIOEVENTREADER_H
 #define DD4HEP_DDG4_LCIOEVENTREADER_H
 
-// C/C++ include files
-#include <string>
+// Framework include files
+#include "DDG4/Geant4InputAction.h"
 
 // Forward declarations
 namespace EVENT { class LCCollection;    }
@@ -19,9 +19,6 @@ namespace DD4hep  {
   /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
   namespace Simulation  {
 
-    // Forward declarations
-    class Geant4Particle;
-
     /// Base class to read lcio files.
     /** 
      *  \author  P.Kostka (main author)
@@ -29,43 +26,21 @@ namespace DD4hep  {
      *  \version 1.0
      *  \ingroup DD4HEP_SIMULATION
      */
-    class LCIOEventReader  {
-
-    public:
-      typedef Geant4Particle Particle;
+    class LCIOEventReader : public Geant4EventReader  {
     protected:
-      /// File name
-      std::string m_name;
-
+      /// Event counter
+      int m_numEvent;
     public:
       /// Initializing constructor
       LCIOEventReader(const std::string& nam);
       /// Default destructor
       virtual ~LCIOEventReader();
-      /// File name
-      const std::string& name()  const   {  return m_name;   }
+      /// Read an event and fill a vector of MCParticles.
+      virtual EventReaderStatus readParticles(int event_number, std::vector<Particle*>& particles);
       /// Read an event and return a LCCollectionVec of MCParticles.
-      virtual EVENT::LCCollection *readParticles() = 0;
+      virtual EventReaderStatus readParticles(int event_number, EVENT::LCCollection** particles) = 0;
     };
 
   }     /* End namespace Simulation   */
 }       /* End namespace DD4hep */
-
-
-#include "DD4hep/Plugins.h"
-namespace {
-  /// Factory to create Geant4 physics constructions
-  template <typename P> class Factory<P, DD4hep::Simulation::LCIOEventReader*(std::string, int)> {  public:
-    static void Func(void *ret, void*, const std::vector<void*>& a, void*) 
-    { *(DD4hep::Simulation::LCIOEventReader**)ret = (DD4hep::Simulation::LCIOEventReader*)new P(*(std::string*)a[0],*(int*)a[1]);}
-  };
-}
-/// Plugin defintion to create event reader objects
-#define DECLARE_LCIO_EVENT_READER(name)					\
-  PLUGINSVC_FACTORY_WITH_ID(name,std::string(#name),DD4hep::Simulation::LCIOEventReader*(std::string,int))
-
-/// Plugin defintion to create event reader objects
-#define DECLARE_LCIO_EVENT_READER_NS(ns,name) typedef ns::name __##name##__; \
-  PLUGINSVC_FACTORY_WITH_ID(__##name##__,std::string(#name),DD4hep::Simulation::LCIOEventReader*(std::string,int))
-
 #endif  /* DD4HEP_DDG4_LCIOEVENTREADER_H  */
diff --git a/DDG4/lcio/LCIOFileReader.cpp b/DDG4/lcio/LCIOFileReader.cpp
index 0b3db53bd..307b877fe 100644
--- a/DDG4/lcio/LCIOFileReader.cpp
+++ b/DDG4/lcio/LCIOFileReader.cpp
@@ -32,30 +32,27 @@ namespace DD4hep  {
       IO::LCReader* m_reader;
     public:
       /// Initializing constructor
-      LCIOFileReader(const std::string& nam, int);
+      LCIOFileReader(const std::string& nam);
       /// Default destructor
       virtual ~LCIOFileReader();
-      /// Read an event and return a LCCollectionVec of MCParticles.
-      virtual EVENT::LCCollection *readParticles();
+      /// Read an event and fill a vector of MCParticles.
+      virtual EventReaderStatus readParticles(int event_number, EVENT::LCCollection** particles);
     };
   }
 }
 #endif // DD4HEP_DDG4_LCIOFILEREADER_H
 
 #include "DD4hep/Printout.h"
-#include "DD4hep/Primitives.h"
-#include "lcio.h"
-#include "EVENT/LCIO.h"
-#include "IO/LCReader.h"
+#include "DDG4/Factories.h"
+#include "UTIL/ILDConf.h"
 
-using namespace EVENT;
 using namespace DD4hep::Simulation;
 
 // Factory entry
-DECLARE_LCIO_EVENT_READER(LCIOFileReader)
+DECLARE_GEANT4_EVENT_READER_NS(DD4hep::Simulation,LCIOFileReader)
 
 /// Initializing constructor
-LCIOFileReader::LCIOFileReader(const std::string& nam, int /* arg */) 
+DD4hep::Simulation::LCIOFileReader::LCIOFileReader(const std::string& nam) 
 : LCIOEventReader(nam)
 {
   m_reader = ::lcio::LCFactory::getInstance()->createLCReader();
@@ -64,16 +61,18 @@ LCIOFileReader::LCIOFileReader(const std::string& nam, int /* arg */)
 }
 
 /// Default destructor
-LCIOFileReader::~LCIOFileReader()    {
+DD4hep::Simulation::LCIOFileReader::~LCIOFileReader()    {
   DD4hep::deletePtr(m_reader);
 }
 
-/// Read an event and return a LCCollectionVec of MCParticles.
-EVENT::LCCollection *LCIOFileReader::readParticles()   {
+/// Read an event and fill a vector of MCParticles.
+Geant4EventReader::EventReaderStatus
+DD4hep::Simulation::LCIOFileReader::readParticles(int /*event_number */, EVENT::LCCollection** particles)  {
   ::lcio::LCEvent* evt = m_reader->readNextEvent();
   if ( evt ) {
-    return evt->getCollection(LCIO::MCPARTICLE);
+    *particles = evt->getCollection(LCIO::MCPARTICLE);
+    if ( *particles ) return EVENT_READER_OK;
   }
-  return 0;
+  return EVENT_READER_ERROR;
 }
 
diff --git a/DDG4/lcio/LCIOInputAction.cpp b/DDG4/lcio/LCIOInputAction.cpp
deleted file mode 100644
index cd95c7e65..000000000
--- a/DDG4/lcio/LCIOInputAction.cpp
+++ /dev/null
@@ -1,191 +0,0 @@
-// $Id: Geant4Converter.cpp 603 2013-06-13 21:15:14Z markus.frank $
-//====================================================================
-//  AIDA Detector description implementation for LCD
-//--------------------------------------------------------------------
-//
-// @author  P.Kostka (main author)
-// @author  M.Frank  (code reshuffeling into new DDG4 scheme)
-//
-//====================================================================
-
-// Framework include files
-#include "LCIOInputAction.h"
-#include "LCIOEventReader.h"
-#include "DD4hep/Printout.h"
-#include "DDG4/Geant4Primary.h"
-#include "DDG4/Geant4Context.h"
-#include "G4ParticleTable.hh"
-#include "EVENT/MCParticle.h"
-#include "EVENT/LCCollection.h"
-
-#include "G4Event.hh"
-
-using namespace std;
-using namespace DD4hep::Simulation;
-typedef DD4hep::ReferenceBitMask<int> PropertyMask;
-
-namespace {
-  inline int GET_ENTRY(const map<EVENT::MCParticle*,int>& mcparts, EVENT::MCParticle* part)  {
-    map<EVENT::MCParticle*,int>::const_iterator ip=mcparts.find(part);
-    if ( ip == mcparts.end() )  {
-      throw runtime_error("Unknown particle identifier look-up!");
-    }
-    return (*ip).second;
-  }
-}
-
-/// Standard constructor
-LCIOInputAction::LCIOInputAction(Geant4Context* context, const string& name)
-  : Geant4GeneratorAction(context,name), m_reader(0)
-{
-  declareProperty("Input",          m_input);
-  declareProperty("Sync",           m_SYNCEVT=0);
-  declareProperty("Mask",           m_mask = 0);
-  declareProperty("MomentumScale",  m_momScale = 1.0);
-  m_needsControl = true;
-}
-
-/// Default destructor
-LCIOInputAction::~LCIOInputAction()   {
-}
-
-/// helper to report Geant4 exceptions
-string LCIOInputAction::issue(int i)  const  {
-  stringstream str;
-  str << "LCIOInputAction[" << name() << "]: Event " << i << " ";
-  return str.str();
-}
-
-/// Read an event and return a LCCollection of MCParticles.
-EVENT::LCCollection* LCIOInputAction::readParticles(int which)  {
-  int evid = which + m_SYNCEVT;
-  if ( 0 == m_reader )  {
-    if ( m_input.empty() )  {
-      throw runtime_error("InputAction: No inoput file declared!");
-    }
-    string err;
-    TypeName tn = TypeName::split(m_input,"|");
-    try  {
-      m_reader = PluginService::Create<LCIOEventReader*>(tn.first,tn.second,int(0));
-      if ( 0 == m_reader )   {
-	abortRun(issue(evid)+"Error creating reader plugin.",
-		 "Failed to create file reader of type %s. Cannot open dataset %s",
-		 tn.first.c_str(),tn.second.c_str());
-	return 0;
-      }
-    }
-    catch(const std::exception& e)  {
-      err = e.what();
-    }
-    if ( !err.empty() )  {
-      abortRun(issue(evid)+err,"Error when reading file %s",m_input.c_str());
-      return 0;
-    }
-  }
-  EVENT::LCCollection* parts = m_reader->readParticles();
-  if ( 0 == parts )  {
-    abortRun(issue(evid)+"Error when reading file - may be end of file.",
-	     "Error when reading file %s",m_input.c_str());
-  }
-  return parts;
-}
-
-/// Callback to generate primary particles
-void LCIOInputAction::operator()(G4Event* event)   {
-  Geant4Event& evt = context()->event();
-  Geant4PrimaryEvent*         prim = evt.extension<Geant4PrimaryEvent>();
-  Geant4PrimaryInteraction*   inter = new Geant4PrimaryInteraction();
-  EVENT::LCCollection*        primaries = readParticles(event->GetEventID());
-  map<EVENT::MCParticle*,int> mcparts;
-  vector<EVENT::MCParticle*>  mcpcoll;
-
-  prim->add(m_mask, inter);
-  // check if there is at least one particle
-  if ( 0 == primaries ) return;
-
-  int NHEP = primaries->getNumberOfElements();
-  // check if there is at least one particle
-  if ( NHEP == 0 ) return;
-
-  mcpcoll.resize(NHEP,0);
-  for(int i=0; i<NHEP; ++i ) {
-    EVENT::MCParticle* p=dynamic_cast<EVENT::MCParticle*>(primaries->getElementAt(i));
-    mcparts[p] = i;
-    mcpcoll[i] = p;
-  }
-
-  print("+++ Particle interaction with %d generator particles ++++++++++++++++++++++++",NHEP);
-  Geant4Vertex* vtx = new Geant4Vertex();
-  vtx->x = 0;
-  vtx->y = 0;
-  vtx->z = 0;
-  vtx->time = 0;
-  inter->vertices.insert(make_pair(m_mask,vtx));
-  // build collection of MCParticles
-  G4ParticleTable*      tab = G4ParticleTable::GetParticleTable();
-  for(int i=0; i<NHEP; ++i )   {
-    EVENT::MCParticle* mcp = mcpcoll[i];
-    Geant4ParticleHandle p(new Particle(i));
-    const double mom_scale = m_momScale;
-    const double *mom   = mcp->getMomentum();
-    const double *vsx   = mcp->getVertex();
-    const double *vex   = mcp->getEndpoint();
-    const float  *spin  = mcp->getSpin();
-    const int    *color = mcp->getColorFlow();
-    G4ParticleDefinition* def = tab->FindParticle(mcp->getPDG());
-    PropertyMask status(p->status);
-    p->pdgID        = mcp->getPDG();
-    p->charge       = int(mcp->getCharge()*3.0);
-    p->psx          = mom_scale*mom[0]*GeV;
-    p->psy          = mom_scale*mom[1]*GeV;
-    p->psz          = mom_scale*mom[2]*GeV;
-    p->time         = mcp->getTime()*ns;
-    p->properTime   = mcp->getTime()*ns;
-    p->vsx          = vsx[0]*mm;
-    p->vsy          = vsx[1]*mm;
-    p->vsz          = vsx[2]*mm;
-    p->vex          = vex[0]*mm;
-    p->vey          = vex[1]*mm;
-    p->vez          = vex[2]*mm;
-    p->definition   = def;
-    p->process      = 0;
-    p->spin[0]      = spin[0];
-    p->spin[1]      = spin[1];
-    p->spin[2]      = spin[2];
-    p->colorFlow[0] = color[0];
-    p->colorFlow[0] = color[1];
-    p->mass         = mcp->getMass()*GeV;
-    const EVENT::MCParticleVec &par = mcp->getParents(), &dau=mcp->getDaughters();
-    for(int num=dau.size(),k=0; k<num; ++k)
-      p->daughters.insert(GET_ENTRY(mcparts,dau[k]));
-    for(int num=par.size(),k=0; k<num; ++k)
-      p->parents.insert(GET_ENTRY(mcparts,par[k]));
-
-    int genStatus = mcp->getGeneratorStatus();
-    if ( genStatus == 0 ) status.set(G4PARTICLE_GEN_EMPTY);
-    else if ( genStatus == 1 ) status.set(G4PARTICLE_GEN_STABLE); 
-    else if ( genStatus == 2 ) status.set(G4PARTICLE_GEN_DECAYED);
-    else if ( genStatus == 3 ) status.set(G4PARTICLE_GEN_DOCUMENTATION);
-    else { std::cout << " #### WARNING - LCIOInputAction : unknown generator status : " << genStatus << " -> ignored ! " << std::endl ; } 
-
-    if ( mcp->isCreatedInSimulation() )       status.set(G4PARTICLE_SIM_CREATED);
-    if ( mcp->isBackscatter() )               status.set(G4PARTICLE_SIM_BACKSCATTER);
-    if ( mcp->vertexIsNotEndpointOfParent() ) status.set(G4PARTICLE_SIM_PARENT_RADIATED);
-    if ( mcp->isDecayedInTracker() )          status.set(G4PARTICLE_SIM_DECAY_TRACKER);
-    if ( mcp->isDecayedInCalorimeter() )      status.set(G4PARTICLE_SIM_DECAY_CALO);
-    if ( mcp->hasLeftDetector() )             status.set(G4PARTICLE_SIM_LEFT_DETECTOR);
-    if ( mcp->isStopped() )                   status.set(G4PARTICLE_SIM_STOPPED);
-    if ( mcp->isOverlay() )                   status.set(G4PARTICLE_SIM_OVERLAY);
-    if ( par.size() == 0 )  {
-      if ( status.isSet(G4PARTICLE_GEN_EMPTY) || status.isSet(G4PARTICLE_GEN_DOCUMENTATION) )
-	vtx->in.insert(p->id);  // Beam particles and primary quarks etc.
-      else
-	vtx->out.insert(p->id); // Stuff, to be given to Geant4 together with daughters
-    }
-    inter->particles.insert(make_pair(p->id,p));
-    p.dump3(outputLevel()-1,name(),"+->");
-  }
-}
-
-#include "DDG4/Factories.h"
-DECLARE_GEANT4ACTION(LCIOInputAction)
diff --git a/DDG4/lcio/LCIOStdHepReader.cpp b/DDG4/lcio/LCIOStdHepReader.cpp
index 2458ba353..626b8838b 100644
--- a/DDG4/lcio/LCIOStdHepReader.cpp
+++ b/DDG4/lcio/LCIOStdHepReader.cpp
@@ -6,11 +6,11 @@
 //====================================================================
 #ifndef DD4HEP_DDG4_LCIOSTDHEPREADER_H
 #define DD4HEP_DDG4_LCIOSTDHEPREADER_H
+
 // Framework include files
 #include "LCIOEventReader.h"
-
-// Forward declarations
-namespace UTIL { class LCStdHepRdr; }
+// LCIO include files
+#include "UTIL/LCStdHepRdr.h"
 
 /// Namespace for the AIDA detector description toolkit
 namespace DD4hep  {
@@ -31,31 +31,27 @@ namespace DD4hep  {
       UTIL::LCStdHepRdr* m_reader;
     public:
       /// Initializing constructor
-      LCIOStdHepReader(const std::string& nam, int);
+      LCIOStdHepReader(const std::string& nam);
       /// Default destructor
       virtual ~LCIOStdHepReader();
-      /// Read an event and return a LCCollectionVec of MCParticles.
-      virtual EVENT::LCCollection *readParticles();
+      /// Read an event and fill a vector of MCParticles.
+      virtual EventReaderStatus readParticles(int event_number, EVENT::LCCollection** particles);
     };
   }     /* End namespace lcio   */
 }       /* End namespace DD4hep */
 #endif  /* DD4HEP_DDG4_LCIOSTDHEPREADER_H */
 
-#include "lcio.h"
-#include "EVENT/LCIO.h"
-#include "UTIL/LCStdHepRdr.h"
-#include "DD4hep/Primitives.h"
+#include "DDG4/Factories.h"
+// Factory entry
+DECLARE_GEANT4_EVENT_READER_NS(DD4hep::Simulation,LCIOStdHepReader)
 
 using namespace DD4hep::Simulation;
 
-// Factory entry
-DECLARE_LCIO_EVENT_READER(LCIOStdHepReader)
-
 /// Initializing constructor
-LCIOStdHepReader::LCIOStdHepReader(const std::string& nam, int) 
+LCIOStdHepReader::LCIOStdHepReader(const std::string& nam) 
   : LCIOEventReader(nam)
 {
-  m_reader = new ::lcio::LCStdHepRdr(m_name.c_str());
+  m_reader = new UTIL::LCStdHepRdr(m_name.c_str());
 }
 
 /// Default destructor
@@ -63,7 +59,10 @@ LCIOStdHepReader::~LCIOStdHepReader()    {
   DD4hep::deletePtr(m_reader);
 }
 
-/// Read an event and return a LCCollectionVec of MCParticles.
-EVENT::LCCollection *LCIOStdHepReader::readParticles()   {
-  return m_reader->readEvent();
+/// Read an event and fill a vector of MCParticles.
+Geant4EventReader::EventReaderStatus
+LCIOStdHepReader::readParticles(int /*event_number */, EVENT::LCCollection** particles)  {
+  *particles = m_reader->readEvent();
+  if ( 0 == *particles ) return EVENT_READER_ERROR;
+  return EVENT_READER_OK;
 }
diff --git a/DDG4/plugins/Geant4EscapeCounter.cpp b/DDG4/plugins/Geant4EscapeCounter.cpp
index bbab87fbf..8bc974034 100644
--- a/DDG4/plugins/Geant4EscapeCounter.cpp
+++ b/DDG4/plugins/Geant4EscapeCounter.cpp
@@ -74,8 +74,7 @@ using namespace DD4hep::Simulation;
 
 /// Standard constructor
 Geant4EscapeCounter::Geant4EscapeCounter(Geant4Context* context, const string& nam, DetElement det, LCDD& lcdd)
-  //    : Geant4SteppingAction(context, nam) 
-  : Geant4Sensitive(context, nam, det, lcdd) 
+: Geant4Sensitive(context, nam, det, lcdd) 
 {
   string coll_name = name()+"Hits";
   m_needsControl = true;
@@ -91,8 +90,6 @@ Geant4EscapeCounter::~Geant4EscapeCounter() {
 
 /// G4VSensitiveDetector interface: Method for generating hit(s) using the information of G4Step object.
 bool Geant4EscapeCounter::process(G4Step* step, G4TouchableHistory* /* history */)   {
-  typedef SimpleHit::Contribution HitContribution;
-  typedef vector<string> _V;
   Geant4StepHandler h(step);
   Geant4TrackHandler th(h.track);
   Geant4TouchableHandler handler(step);
diff --git a/DDG4/plugins/Geant4HepEventReader.cpp b/DDG4/plugins/Geant4EventReaderHepEvt.cpp
similarity index 75%
rename from DDG4/plugins/Geant4HepEventReader.cpp
rename to DDG4/plugins/Geant4EventReaderHepEvt.cpp
index 666a91af5..ff4c3e053 100644
--- a/DDG4/plugins/Geant4HepEventReader.cpp
+++ b/DDG4/plugins/Geant4EventReaderHepEvt.cpp
@@ -20,25 +20,26 @@ namespace DD4hep {
     /// Class to populate Geant4 primaries from StdHep files.
     /** 
      * Class to populate Geant4 primary particles and vertices from a 
-     * file in StdHep format (ASCII)
+     * file in HEPEvt format (ASCII)
      *
      *  \author  P.Kostka (main author)
      *  \author  M.Frank  (code reshuffeling into new DDG4 scheme)
      *  \version 1.0
      *  \ingroup DD4HEP_SIMULATION
      */
-    class Geant4HepEventReader : public Geant4EventReader  {
+    class Geant4EventReaderHepEvt : public Geant4EventReader  {
+
     protected:
       std::ifstream m_input;
-      int m_format;
+      int           m_format;
 
     public:
       /// Initializing constructor
-      Geant4HepEventReader(const std::string& nam);
+      Geant4EventReaderHepEvt(const std::string& nam, int format);
       /// Default destructor
-      virtual ~Geant4HepEventReader();
+      virtual ~Geant4EventReaderHepEvt();
       /// Read an event and fill a vector of MCParticles.
-      virtual int readParticles(int event_number, std::vector<Particle*>& particles);
+      virtual EventReaderStatus readParticles(int event_number, std::vector<Particle*>& particles);
     };
   }     /* End namespace Simulation   */
 }       /* End namespace DD4hep       */
@@ -49,38 +50,72 @@ namespace DD4hep {
 //--------------------------------------------------------------------
 //
 //====================================================================
-// #include "DDG4/Geant4HepEventReader"
+// #include "DDG4/Geant4EventReaderHepEvt"
 
+#include "DDG4/Factories.h"
+#include "DD4hep/Printout.h"
 #include "CLHEP/Units/SystemOfUnits.h"
 #include "CLHEP/Units/PhysicalConstants.h"
 
 #include <cerrno>
 
+using namespace std;
 using namespace CLHEP;
 using namespace DD4hep::Simulation;
 typedef DD4hep::ReferenceBitMask<int> PropertyMask;
 
-#define HEPEvt 1
+#define HEPEvtShort 1
+#define HEPEvtLong 2
+namespace {
+  class Geant4EventReaderHepEvtShort : public Geant4EventReaderHepEvt  {
+  public:
+    /// Initializing constructor
+    Geant4EventReaderHepEvtShort(const string& nam) : Geant4EventReaderHepEvt(nam,HEPEvtShort) {}
+    /// Default destructor
+    virtual ~Geant4EventReaderHepEvtShort() {}
+  };
+  class Geant4EventReaderHepEvtLong : public Geant4EventReaderHepEvt  {
+  public:
+    /// Initializing constructor
+    Geant4EventReaderHepEvtLong(const string& nam) : Geant4EventReaderHepEvt(nam,HEPEvtLong) {}
+    /// Default destructor
+    virtual ~Geant4EventReaderHepEvtLong() {}
+  };
+}
 
 // Factory entry
-DECLARE_GEANT4_EVENT_READER(Geant4HepEventReader)
+DECLARE_GEANT4_EVENT_READER(Geant4EventReaderHepEvtShort)
+// Factory entry
+DECLARE_GEANT4_EVENT_READER(Geant4EventReaderHepEvtLong)
+
 
 /// Initializing constructor
-Geant4HepEventReader::Geant4HepEventReader(const std::string& nam)
-: Geant4EventReader(nam), m_input(), m_format(HEPEvt)
+Geant4EventReaderHepEvt::Geant4EventReaderHepEvt(const string& nam, int format)
+: Geant4EventReader(nam), m_input(), m_format(format)
 {
-  // Need to set format from input specification!!!
-
   // Now open the input file:
+  m_input.open(nam.c_str(),ifstream::in);
+  if ( !m_input.good() )   {
+    string err = "+++ Geant4EventReaderHepEvt: Failed to open input stream:"+nam+
+      " Error:"+string(strerror(errno));
+    throw runtime_error(err);
+  }
 }
 
 /// Default destructor
-Geant4HepEventReader::~Geant4HepEventReader()    {
+Geant4EventReaderHepEvt::~Geant4EventReaderHepEvt()    {
   m_input.close();
 }
 
 /// Read an event and fill a vector of MCParticles.
-int Geant4HepEventReader::readParticles(int /* event_number */, std::vector<Particle*>& particles)   {
+Geant4EventReader::EventReaderStatus 
+Geant4EventReaderHepEvt::readParticles(int /* event_number */, vector<Particle*>& particles)   {
+
+  // First check the input file status
+  if ( !m_input.good() || m_input.eof() )   {
+    return EVENT_READER_IO_ERROR;
+  }
+
   //static const double c_light = 299.792;// mm/ns
   //
   //  Read the event, check for errors
@@ -91,7 +126,7 @@ int Geant4HepEventReader::readParticles(int /* event_number */, std::vector<Part
     //
     // End of File :: ??? Exception ???
     //   -> FG:   EOF is not an exception as it happens for every file at the end !
-    return EIO;
+    return EVENT_READER_IO_ERROR;
   }
   //
   //  Loop over particles
@@ -111,11 +146,11 @@ int Geant4HepEventReader::readParticles(int /* event_number */, std::vector<Part
   double VHEP3; // z vertex position in mm
   double VHEP4; // production time in mm/c
  
-  std::vector<int> daughter1;
-  std::vector<int> daughter2;
+  vector<int> daughter1;
+  vector<int> daughter2;
  
   for( int IHEP=0; IHEP<NHEP; IHEP++ )    {
-    if ( m_format == HEPEvt)
+    if ( m_format == HEPEvtShort )
       m_input >> ISTHEP >> IDHEP >> JDAHEP1 >> JDAHEP2
 	      >> PHEP1 >> PHEP2 >> PHEP3 >> PHEP5;
     else
@@ -128,7 +163,7 @@ int Geant4HepEventReader::readParticles(int /* event_number */, std::vector<Part
 	      >> VHEP4;
  
     if(m_input.eof())
-      return EIO;
+      return EVENT_READER_IO_ERROR;
     //
     //  Create a MCParticle and fill it from stdhep info
     Particle* p = new Particle(IHEP);
@@ -236,6 +271,6 @@ int Geant4HepEventReader::readParticles(int /* event_number */, std::vector<Part
       if ( !part.findParent(mcp) ) part.addParent(mcp);
     }
   }  // End second loop over particles
-  return 0;
+  return EVENT_READER_OK;
 }
 
diff --git a/DDG4/plugins/Geant4EventReaderHepMC.cpp b/DDG4/plugins/Geant4EventReaderHepMC.cpp
new file mode 100644
index 000000000..07b35190c
--- /dev/null
+++ b/DDG4/plugins/Geant4EventReaderHepMC.cpp
@@ -0,0 +1,632 @@
+// $Id: Geant4Converter.cpp 603 2013-06-13 21:15:14Z markus.frank $
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//====================================================================
+
+// Framework include files
+#include "DD4hep/IoStreams.h"
+#include "DDG4/Geant4InputAction.h"
+
+// C/C++ include files
+#include <fstream>
+#include <boost/iostreams/stream.hpp>
+
+/// Namespace for the AIDA detector description toolkit
+namespace DD4hep {
+
+  /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
+  namespace Simulation {
+
+    namespace HepMC {  class EventStream;  }
+    /// Class to populate Geant4 primaries from StdHep files.
+    /** 
+     * Class to populate Geant4 primary particles and vertices from a 
+     * file in HEPEvt format (ASCII)
+     *
+     *  \author  P.Kostka (main author)
+     *  \author  M.Frank  (code reshuffeling into new DDG4 scheme)
+     *  \version 1.0
+     *  \ingroup DD4HEP_SIMULATION
+     */
+    class Geant4EventReaderHepMC : public Geant4EventReader  {
+      typedef boost::iostreams::stream<dd4hep_file_source<int> > in_stream;
+      //typedef boost::iostreams::stream<dd4hep_file_source<TFile*> > in_stream;
+      typedef HepMC::EventStream EventStream;
+    protected:
+      in_stream m_input;
+      EventStream* m_events;
+    public:
+      /// Initializing constructor
+      Geant4EventReaderHepMC(const std::string& nam);
+      /// Default destructor
+      virtual ~Geant4EventReaderHepMC();
+      /// Read an event and fill a vector of MCParticles.
+      virtual EventReaderStatus readParticles(int event_number, std::vector<Particle*>& particles);
+    };
+  }     /* End namespace Simulation   */
+}       /* End namespace DD4hep       */
+
+// $Id: Geant4Converter.cpp 603 2013-06-13 21:15:14Z markus.frank $
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//====================================================================
+// #include "DDG4/Geant4EventReaderHepMC"
+
+#include "DDG4/Factories.h"
+#include "DD4hep/Printout.h"
+#include "DDG4/Geant4Primary.h"
+#include "CLHEP/Units/SystemOfUnits.h"
+#include "CLHEP/Units/PhysicalConstants.h"
+
+#include <cerrno>
+#include <algorithm>
+
+using namespace std;
+using namespace CLHEP;
+using namespace DD4hep::Simulation;
+typedef DD4hep::ReferenceBitMask<int> PropertyMask;
+
+// Factory entry
+DECLARE_GEANT4_EVENT_READER(Geant4EventReaderHepMC)
+
+/// Namespace for the AIDA detector description toolkit
+namespace DD4hep {
+
+  /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
+  namespace Simulation {
+
+    namespace HepMC {
+
+      class EventHeader  {
+      public:
+	int   id;
+	int   num_vertices;
+	int   bp1, bp2;
+	int   signal_process_id;
+	int   signal_process_vertex;
+	float scale;
+	float alpha_qcd;
+	float alpha_qed;
+	vector<float>      weights;
+	vector<long>       random;
+	EventHeader() {}
+      };
+
+      /// The known_io enum is used to track which type of input is being read
+      enum known_io { gen=1, ascii, extascii, ascii_pdt, extascii_pdt };
+
+      class EventStream {
+      public:
+	istream& instream;
+	// io information
+	string key;
+	double mom_unit, pos_unit;
+	int    io_type;
+	float xsection, xsection_err;
+	//WeightContainer weights;
+	typedef std::map<int,Geant4Vertex*> Vertices;
+	Vertices m_vertices;
+	typedef std::map<int,Geant4Particle*> Particles;
+	Particles m_particles;
+
+	EventHeader header;
+
+	EventStream(istream& in) : instream(in), io_type(0)
+	{ use_default_units();                       }
+	Particles& particles() { return m_particles; }
+	Vertices&  vertices()  { return m_vertices;  }
+	void add_vertex(int id, Geant4Vertex* v)
+	{ m_vertices.insert(make_pair(id,v));        }
+	void add_particle(Geant4Particle* p);
+	void set_io(int typ, const string& k) 
+	{ io_type = typ;    key = k;                 }
+	void use_default_units()  
+	{ mom_unit = MeV; pos_unit = mm;             }
+	Geant4Vertex* vertex(int i);
+	void fix_particles();
+	bool read();
+	void clear();
+      };
+
+      char get_input(istream& is, istringstream& iline);
+      int find_event_end(istream & is);
+      int read_weight_names(EventStream &, istringstream& iline);
+      int read_particle(EventStream &info, istringstream& iline, Geant4Particle * p);
+      int read_vertex(EventStream &info, istream& is, istringstream & iline);
+      int read_event_header(EventStream &info, istringstream & input, EventHeader& header);
+      int read_cross_section(EventStream &info, istringstream & input);
+      int read_units(EventStream &info, istringstream & input);
+      int read_heavy_ion(EventStream &, istringstream & input);
+      int read_pdf(EventStream &, istringstream & input);
+    }
+  }
+}
+
+/// Initializing constructor
+Geant4EventReaderHepMC::Geant4EventReaderHepMC(const string& nam)
+: Geant4EventReader(nam), m_input(), m_events(0)
+{
+  // Now open the input file:
+  m_input.open(nam.c_str(),BOOST_IOS::in|BOOST_IOS::binary);
+  if ( m_input < 0 )   {
+    string err = "+++ Geant4EventReaderHepMC: Failed to open input stream:"+nam+
+      " Error:"+string(strerror(errno));
+    throw runtime_error(err);
+  }
+  m_events = new HepMC::EventStream(m_input);
+}
+
+/// Default destructor
+Geant4EventReaderHepMC::~Geant4EventReaderHepMC()    {
+  delete m_events;
+  m_events = 0;
+  m_input.close();
+}
+namespace DD4hep{
+  template <typename M> ReferenceObjects<typename M::value_type> __reference2nd(M&) {
+    return ReferenceObjects<typename M::value_type>();
+  }
+}
+/// Read an event and fill a vector of MCParticles.
+Geant4EventReaderHepMC::EventReaderStatus
+Geant4EventReaderHepMC::readParticles(int /* ev_id */, Particles& output) {
+  // make sure the stream is good
+  if ( m_input.eof() || m_input.fail() )  {
+    cerr << "streaming input: end of stream found setting badbit." << endl;
+    m_input.clear(ios::badbit); 
+    return EVENT_READER_IO_ERROR;
+  }
+
+  if ( m_events->read() )  {
+    EventStream::Particles& p = m_events->particles();
+    output.reserve(p.size());
+    transform(p.begin(),p.end(),back_inserter(output),reference2nd(p));
+    m_events->clear();
+    for(Particles::const_iterator k=output.begin(); k != output.end(); ++k) {
+      Geant4ParticleHandle p(*k);
+      printout(INFO,m_name,
+	       "+++ %s ID:%3d status:%08X typ:%9d Mom:(%+.2e,%+.2e,%+.2e)[MeV] "
+	       "time: %+.2e [ns] #Dau:%3d #Par:%1d",
+	       "",p->id,p->status,p->pdgID,
+	       p->psx/MeV,p->psy/MeV,p->psz/MeV,p->time/ns,
+	       p->daughters.size(),
+	       p->parents.size());
+      //output.push_back(p);
+    }
+    return EVENT_READER_OK;
+  }
+  return EVENT_READER_IO_ERROR;
+}
+
+
+void HepMC::EventStream::fix_particles()  {
+  EventStream::Particles::iterator i;
+  std::set<int>::const_iterator id, ip;
+  for(i=m_particles.begin(); i != m_particles.end(); ++i)  {
+    Geant4ParticleHandle p((*i).second);
+    int end_vtx_id = p->secondaries;
+    p->secondaries = 0;
+    Geant4Vertex* v = vertex(end_vtx_id);
+    if ( v )   {
+      p->vex = v->x;
+      p->vey = v->y;
+      p->vez = v->z;
+      v->in.insert(p->id);
+      for(id=v->out.begin(); id!=v->out.end();++id)
+	p->daughters.insert(*id);
+    }
+  }
+  EventStream::Vertices::iterator j;
+  for(j=m_vertices.begin(); j != m_vertices.end(); ++j)  {
+    Geant4Vertex* v = (*j).second;
+    for (id=v->in.begin(); id!=v->in.end();++id)  {
+      for (ip=v->out.begin(); ip!=v->out.end();++ip)   {
+	EventStream::Particles::iterator ipp = m_particles.find(*ip);
+	(*ipp).second->parents.insert(*id);
+      }
+    }
+  }
+}
+
+char HepMC::get_input(istream& is, istringstream& iline)  {
+  char value = is.peek();
+  if ( !is ) {        // make sure the stream is valid
+    cerr << "StreamHelpers: setting badbit." << endl;
+    is.clear(ios::badbit); 
+    return -1;
+  }
+  string line, firstc;
+  getline(is,line);
+  if ( !is ) {        // make sure the stream is valid
+    cerr << "StreamHelpers: setting badbit." << endl;
+    is.clear(ios::badbit); 
+    return -1;
+  }
+  iline.str(line);
+  if ( line.length()>0 && line[1] == ' ' ) iline >> firstc;
+  return iline ? value : -1;
+}
+
+int HepMC::find_event_end(istream & is) {
+  string line;
+  while ( is ) { 
+    char val = is.peek();
+    if( val == 'E' ) {	// next event
+      return 1;
+    }
+    getline(is,line);
+    if ( !is.good() ) return 0;
+  }
+  return 0;
+}
+
+int HepMC::read_weight_names(EventStream&, istringstream&)   {
+#if 0
+  int HepMC::read_weight_names(EventStream& info, istringstream& iline)
+    size_t name_size = 0;
+  iline >> name_size;
+  info.weights.names.clear();
+  info.weights.weights.clear();
+
+  string name;
+  WeightContainer namedWeight;
+  string::size_type i1 = line.find("\""), i2, len = line.size();
+  for(size_t ii = 0; ii < name_size; ++ii) {
+    // weight names may contain blanks
+    if(i1 >= len) {
+      cout << "debug: attempting to read past the end of the named weight line " << endl;
+      cout << "debug: We should never get here" << endl;
+      cout << "debug: Looking for the end of this event" << endl;
+      find_event_end(is);
+    }
+    i2 = line.find("\"",i1+1);
+    name = line.substr(i1+1,i2-i1-1);
+    if ( namedWeight.names.find(name) == namedWeight.names.end() )
+      namedWeight.names[name] = namedWeight.names.size();
+    namedWeight.weights[ii] = info.weights.weights[ii];
+    i1 = line.find("\"",i2+1);
+  }
+
+  info.weights.weights = namedWeight.weights;
+  info.weights.names   = namedWeight.names;
+#endif
+  return 1;
+}
+
+int HepMC::read_particle(EventStream &info, istringstream& iline, Geant4Particle * p)   {
+  float ene = 0., theta = 0., phi = 0;
+  int   size = 0;
+
+  // check that the input stream is still OK after reading item
+  iline >> p->id >> p->pdgID >> p->psx >> p->psy >> p->psz >> ene;
+  if ( !iline ) 
+    return 0;
+  else if( info.io_type != ascii )
+    iline >> p->mass;
+  else 
+    p->mass = sqrt(fabs(ene*ene - p->psx*p->psx + p->psy*p->psy + p->psz*p->psz));
+
+  // Reuse here the secondaries to store the end-vertex ID
+  iline >> p->status >> theta >> phi >> p->secondaries >> size;
+  if(!iline) 
+    return 0;
+
+  // read flow patterns if any exist
+  for (int i = 0; i < size; ++i ) {
+    iline >> p->colorFlow[0] >> p->colorFlow[1];
+    if(!iline) return 0;
+  }
+  return 1;
+}
+
+int HepMC::read_vertex(EventStream &info, istream& is, istringstream & iline)    {
+  int id=0, dummy=0, num_orphans_in=0, num_particles_out=0, weights_size=0;
+  vector<float> weights;
+  Geant4Vertex* v = new Geant4Vertex();
+  Geant4Particle* p;
+
+  iline >> id >> dummy >> v->x >> v->y >> v->z >> v->time 
+	>> num_orphans_in >> num_particles_out >> weights_size;
+  if(!iline) 
+    return 0;
+  weights.resize(weights_size);
+  for (int i1 = 0; i1 < weights_size; ++i1) {
+    iline >> weights[i1];
+    if(!iline)
+      return 0;
+  }
+  info.add_vertex(id,v);
+  //cout << "Add Vertex:" << id << endl;
+
+  for(char value = is.peek(); value=='P'; value=is.peek())  {
+    value = get_input(is,iline);
+    if( !iline || value < 0 )
+      return 0;
+
+    read_particle(info, iline,p = new Geant4Particle());
+    if(!iline)   {
+      cerr << "Failed to read particle!" << endl;
+      delete p;
+      return 0;
+    }
+    info.add_particle(p);
+    p->pex = p->psx;
+    p->pey = p->psy;
+    p->pez = p->psz;
+    if ( --num_orphans_in >= 0 )   {
+      p->vex = v->x;
+      p->vey = v->y;
+      p->vez = v->z;
+      v->in.insert(p->id);
+      //cout << "Add INGOING  Particle:" << p->id << endl;
+    }
+    else if ( num_particles_out >= 0 )   {
+      v->out.insert(p->id);
+      p->vsx = v->x;
+      p->vsy = v->y;
+      p->vsz = v->z;
+      //cout << "Add OUTGOING Particle:" << p->id << endl;
+    }
+    else  {
+      delete p;
+      throw runtime_error("Invalid number of particles....");
+    }
+  }
+  return 1;
+}
+	
+int HepMC::read_event_header(EventStream &info, istringstream & input, EventHeader& header)   {
+  // read values into temp variables, then fill GenEvent
+  int random_states_size = 0, nmpi = -1;
+  input >> header.id;
+  if( info.io_type == gen || info.io_type == extascii ) {
+    input >> nmpi;
+    if( input.fail() ) return 0;
+    //MSF set_mpi( nmpi );
+  }
+  input >> header.scale;
+  input >> header.alpha_qcd;
+  input >> header.alpha_qed;
+  input >> header.signal_process_id;
+  input >> header.signal_process_vertex;
+  input >> header.num_vertices;
+  if( info.io_type == gen || info.io_type == extascii )
+    input >> header.bp1 >> header.bp2;
+
+  input >> random_states_size;
+  cout << input.str() << endl;
+  input.clear();
+  if( input.fail() ) return 0;
+
+  header.random.resize(random_states_size);
+  for(int i = 0; i < random_states_size; ++i )
+    input >> header.random[i];
+
+  size_t weights_size = 0;
+  input >> weights_size;
+  if( input.fail() ) return 0;
+
+  vector<float> wgt(weights_size);
+  for(size_t ii = 0; ii < weights_size; ++ii )
+    input >> wgt[ii];
+  if( input.fail() ) return 0;
+
+  // weight names will be added later if they exist
+  if( weights_size > 0 ) header.weights = wgt;
+  return 1;
+}
+
+int HepMC::read_cross_section(EventStream &info, istringstream & input)   {
+  input >> info.xsection >> info.xsection_err;
+  return input.fail() ? 0 : 1;
+}
+
+int HepMC::read_units(EventStream &info, istringstream & input)   {
+  if( info.io_type == gen )  {
+    string mom, pos;
+    input >> mom >> pos;
+    if ( !input.fail() )  {
+      if ( mom == "KEV" ) info.mom_unit = keV;
+      else if ( mom == "MEV" ) info.mom_unit = MeV;
+      else if ( mom == "GEV" ) info.mom_unit = GeV;
+      else if ( mom == "TEV" ) info.mom_unit = TeV;
+      
+      if ( pos == "MM" ) info.pos_unit = mm;
+      else if ( pos == "CM" ) info.pos_unit = cm;
+      else if ( pos == "M"  ) info.pos_unit = m;
+    }
+  }
+  return input.fail() ? 0 : 1;
+}
+
+int HepMC::read_heavy_ion(EventStream &, istringstream & input)  {
+  // read values into temp variables, then create a new HeavyIon object
+  int nh =0, np =0, nt =0, nc =0, 
+    neut = 0, prot = 0, nw =0, nwn =0, nwnw =0;
+  float impact = 0., plane = 0., xcen = 0., inel = 0.; 
+  input >> nh >> np >> nt >> nc >> neut >> prot >> nw >> nwn >> nwnw;
+  input >> impact >> plane >> xcen >> inel;
+  cerr << "Reading heavy ion, but igoring data!" << endl;
+  /*
+    ion->set_Ncoll_hard(nh);
+    ion->set_Npart_proj(np);
+    ion->set_Npart_targ(nt);
+    ion->set_Ncoll(nc);
+    ion->set_spectator_neutrons(neut);
+    ion->set_spectator_protons(prot);
+    ion->set_N_Nwounded_collisions(nw);
+    ion->set_Nwounded_N_collisions(nwn);
+    ion->set_Nwounded_Nwounded_collisions(nwnw);
+    ion->set_impact_parameter(impact);
+    ion->set_event_plane_angle(plane);
+    ion->set_eccentricity(xcen);
+    ion->set_sigma_inel_NN(inel);
+  */
+  return input.fail() ? 0 : 1;
+}
+
+int HepMC::read_pdf(EventStream &, istringstream & input)  {
+  // read values into temp variables, then create a new PdfInfo object
+  int id1 =0, id2 =0, pdf_id1=0, pdf_id2=0;
+  double  x1 = 0., x2 = 0., scale = 0., pdf1 = 0., pdf2 = 0.; 
+  input >> id1 ;
+  if ( input.fail()  )
+    return 0;
+  // check now for empty PdfInfo line
+  if( id1 == 0 )
+    return 0;
+  // continue reading
+  input >> id2 >> x1 >> x2 >> scale >> pdf1 >> pdf2;
+  if ( input.fail()  )
+    return 0;
+  // check to see if we are at the end of the line
+  if( !input.eof() )  {
+    input >> pdf_id1 >> pdf_id2;
+  }
+  cerr << "Reading pdf, but igoring data!" << endl;
+  /*
+    pdf->set_id1( id1 );
+    pdf->set_id2( id2 );
+    pdf->set_pdf_id1( pdf_id1 );
+    pdf->set_pdf_id2( pdf_id2 );
+    pdf->set_x1( x1 );
+    pdf->set_x2( x2 );
+    pdf->set_scalePDF( scale );
+    pdf->set_pdf1( pdf1 );
+    pdf->set_pdf2( pdf2 );
+  */
+  return input.fail() ? 0 : 1;
+}
+
+void HepMC::EventStream::add_particle(Geant4Particle* p)   {
+  p->id = m_particles.size();
+  m_particles.insert(make_pair(p->id,p));
+}
+
+Geant4Vertex* HepMC::EventStream::vertex(int i)   {
+  Vertices::iterator it=m_vertices.find(i);
+  return (it==m_vertices.end()) ? 0 : (*it).second;
+}
+
+void HepMC::EventStream::clear()   {
+  releaseObjects(m_vertices)();
+  releaseObjects(m_particles)();
+}
+
+bool HepMC::EventStream::read()   {
+  EventStream& info = *this;
+
+  // OK - now ready to start reading the event, so set the header flag
+  // The flag will be set to false when we reach the end of the header
+  m_particles.clear();
+  m_vertices.clear();
+
+  bool event_read = false;
+  while( instream.good() ) {
+    char value = instream.peek();
+    if ( value == 'E' && event_read ) break;
+    else if ( event_read ) break;
+    else if ( instream.eof() ) return false;
+
+    istringstream input_line;
+    value = get_input(instream,input_line);
+
+    // On failure switch to end
+    if( !input_line || value < 0 )
+      goto Skip;
+
+    switch( value )   {
+    case 'H':  {
+      int iotype = 0;
+      string key;
+      input_line >> key;
+      // search for event listing key before first event only.
+      key = key.substr(0,key.find('\r'));
+      if ( key == "H" && (this->io_type == gen || this->io_type == extascii) ) {
+	read_heavy_ion(info, input_line);
+	break;
+      }
+      else if( key == "HepMC::IO_GenEvent-START_EVENT_LISTING" )
+	this->set_io(gen,key);
+      else if( key == "HepMC::IO_Ascii-START_EVENT_LISTING" )
+	this->set_io(ascii,key);
+      else if( key == "HepMC::IO_ExtendedAscii-START_EVENT_LISTING" )
+	this->set_io(extascii,key);
+      else if( key == "HepMC::IO_Ascii-START_PARTICLE_DATA" )
+	this->set_io(ascii_pdt,key);
+      else if( key == "HepMC::IO_ExtendedAscii-START_PARTICLE_DATA" )
+	this->set_io(extascii_pdt,key);
+      else if( key == "HepMC::IO_GenEvent-END_EVENT_LISTING" )
+	iotype = gen;
+      else if( key == "HepMC::IO_Ascii-END_EVENT_LISTING" ) 
+	iotype = ascii;
+      else if( key == "HepMC::IO_ExtendedAscii-END_EVENT_LISTING" ) 
+	iotype = extascii;
+      else if( key == "HepMC::IO_Ascii-END_PARTICLE_DATA" ) 
+	iotype = ascii_pdt;
+      else if( key == "HepMC::IO_ExtendedAscii-END_PARTICLE_DATA" ) 
+	iotype = extascii_pdt;
+
+      if( iotype != 0 && this->io_type != iotype )  {
+	cerr << "GenEvent::find_end_key: iotype keys have changed. "
+	     << "MALFORMED INPUT" << endl;
+	instream.clear(ios::badbit); 
+	return false;
+      }
+      continue;
+    }      
+    case 'E':      	// deal with the event line
+      if ( !read_event_header(info, input_line, this->header) )
+	goto Skip;
+      event_read = true;
+      continue;
+
+    case 'N':      	// get weight names 
+      if ( !read_weight_names(info, input_line) )
+	goto Skip;
+      continue;
+
+    case 'U':      	// get unit information if it exists
+      if ( !read_units(info, input_line) )
+	goto Skip;
+      continue;
+
+    case 'C':      	// we have a GenCrossSection line
+      if ( !read_cross_section(info, input_line) )
+	goto Skip;
+      continue;
+
+    case 'V':           // Read vertex with particles
+      if ( !read_vertex(info, instream, input_line) )
+	goto Skip;
+      continue;
+
+    case 'F':           // Read PDF
+      if ( !read_pdf(info, input_line) )
+	goto Skip;
+      continue;
+
+    case 'P':      	// we should not find this line
+      cerr << "streaming input: found unexpected Particle line." << endl;
+      continue;
+
+    default:            // ignore everything else
+      continue;
+    }
+    continue;
+  Skip:
+    printout(WARNING,"HepMC::EventStream","+++ Skip event with ID: %d",this->header.id);
+    releaseObjects(vertices())();
+    releaseObjects(particles())();
+    find_event_end(instream);
+    event_read = false;
+    if ( instream.eof() ) return false;
+  }
+  this->fix_particles();
+  releaseObjects(vertices())();
+  return true;
+}
diff --git a/DDG4/plugins/Geant4SensDet.cpp b/DDG4/plugins/Geant4SensDet.cpp
index 6e1456cd3..b91f0de30 100644
--- a/DDG4/plugins/Geant4SensDet.cpp
+++ b/DDG4/plugins/Geant4SensDet.cpp
@@ -64,6 +64,9 @@ namespace DD4hep {
 			  virtual public Geant4ActionSD,
 			  virtual public RefCountedSequence<Geant4SensDetActionSequence>
     {
+    protected:
+      /// Access to the geant4 sensitive detector handle
+      SensitiveDetector m_sensitive;
     public:
       /// Constructor. The detector element is identified by the name
       Geant4SensDet(const std::string& nam, Geometry::LCDD& lcdd)
@@ -71,6 +74,7 @@ namespace DD4hep {
 	  Geant4Action(0,nam), Geant4ActionSD(nam), Base()
       {
 	Geant4Kernel& kernel = Geant4Kernel::access(lcdd);
+	m_sensitive = lcdd.sensitiveDetector(nam);
 	m_context = Geant4Context(&kernel);
 	m_outputLevel = kernel.getOutputLevel(nam);
 	_aquire(kernel.sensitiveAction(nam));
@@ -98,6 +102,12 @@ namespace DD4hep {
       /// Access to the readout geometry of the sensitive detector
       virtual G4VReadOutGeometry* readoutGeometry() const
       {  return this->G4VSensitiveDetector::GetROgeometry();            }
+      /// Access to the LCDD sensitive detector handle
+      virtual SensitiveDetector sensitiveDetector() const
+      {  return m_sensitive;                                            }
+      /// Access to the sensitive type of the detector
+      virtual const std::string& sensitiveType() const
+      {  return m_sequence->sensitiveType();                            }
       /// Callback if the sequence should be accepted or filtered off
       virtual G4bool Accept(const G4Step* step) const
       {  return m_sequence->accept(step);                               }
diff --git a/DDG4/python/DDG4Dict.C b/DDG4/python/DDG4Dict.C
index 0221e930f..22c665d51 100644
--- a/DDG4/python/DDG4Dict.C
+++ b/DDG4/python/DDG4Dict.C
@@ -39,6 +39,7 @@ using namespace DD4hep::Simulation;
 
 #include "DDG4/Geant4Config.h"
 #include "DDG4/Geant4DataDump.h"
+#include "DDG4/Geant4InputAction.h"
 #include <iostream>
 
 namespace DD4hep {
@@ -188,6 +189,8 @@ typedef DD4hep::Simulation::Geant4ActionCreation Geant4ActionCreation;
 // CINT configuration for DDG4
 #if defined(__MAKECINT__)
 #pragma link C++ class PropertyResult;
+#pragma link C++ class Geant4InputAction::Particles;
+#pragma link C++ class auto_ptr<Geant4InputAction::Particles>;
 
 #pragma link C++ class ActionHandle;
 #pragma link C++ class FilterHandle;
@@ -234,6 +237,8 @@ typedef DD4hep::Simulation::Geant4ActionCreation Geant4ActionCreation;
 
 #pragma link C++ class Geant4GeneratorActionSequence;
 #pragma link C++ class Geant4GeneratorAction;
+#pragma link C++ class Geant4InputAction;
+#pragma link C++ class Geant4EventReader;
 
 #pragma link C++ class Geant4PhysicsListActionSequence;
 #pragma link C++ class Geant4PhysicsList;
diff --git a/DDG4/src/Geant4Data.cpp b/DDG4/src/Geant4Data.cpp
index c255e06dc..240f39951 100644
--- a/DDG4/src/Geant4Data.cpp
+++ b/DDG4/src/Geant4Data.cpp
@@ -66,7 +66,7 @@ Geant4HitData::Contribution Geant4HitData::extractContribution(G4Step* step) {
     (h.trackDef() == G4OpticalPhoton::OpticalPhotonDefinition()) ? h.trkEnergy() : h.totalEnergy();
   const G4ThreeVector& pre  = h.prePosG4();
   const G4ThreeVector& post = h.postPosG4();
-  float pos[] = { (pre.x()+post.x())/2.0, (pre.y()+post.y())/2.0, (pre.z()+post.z())/2.0 };
+  float pos[] = {float((pre.x()+post.x())/2.0),float((pre.y()+post.y())/2.0),float((pre.z()+post.z())/2.0) };
   Contribution contrib(h.trkID(),h.trkPdgID(),deposit,h.trkTime(),pos);
   return contrib;
 }
diff --git a/DDG4/src/Geant4DetectorConstruction.cpp b/DDG4/src/Geant4DetectorConstruction.cpp
index 80d847ea6..15ee8bfdb 100644
--- a/DDG4/src/Geant4DetectorConstruction.cpp
+++ b/DDG4/src/Geant4DetectorConstruction.cpp
@@ -21,25 +21,42 @@
 
 using namespace std;
 using namespace DD4hep;
-using namespace DD4hep::Geometry;
+using namespace DD4hep::Simulation;
 
-DD4hep::Simulation::Geant4DetectorConstruction::Geant4DetectorConstruction(Geometry::LCDD& lcdd)
-  : m_outputLevel(PrintLevel(printLevel()-1)), m_lcdd(lcdd), m_world(0) {
+namespace {
+  static Geant4DetectorConstruction* s_instance = 0;
 }
 
-DD4hep::Simulation::Geant4DetectorConstruction::Geant4DetectorConstruction(DD4hep::Simulation::Geant4Kernel& kernel)
-  : m_lcdd(kernel.lcdd()), m_world(0) {
+/// Instance accessor
+Geant4DetectorConstruction* Geant4DetectorConstruction::instance(Geant4Kernel& kernel)   {
+  if ( 0 == s_instance ) s_instance = new Geant4DetectorConstruction(kernel);
+  return s_instance;
+}
+
+/// Initializing constructor for other clients
+Geant4DetectorConstruction::Geant4DetectorConstruction(Geometry::LCDD& lcdd)
+  : Geant4Action(0,"DetectorConstruction"), m_lcdd(lcdd), m_world(0) 
+{
+  m_outputLevel = PrintLevel(printLevel()-1);
+  s_instance = this;
+}
+
+/// Initializing constructor for DDG4
+Geant4DetectorConstruction::Geant4DetectorConstruction(Geant4Kernel& kernel)
+  : Geant4Action(0,"DetectorConstruction"), m_lcdd(kernel.lcdd()), m_world(0)
+{
   m_outputLevel = kernel.getOutputLevel("Geant4Converter");
+  s_instance = this;
 }
 
 /// Default destructor
-DD4hep::Simulation::Geant4DetectorConstruction::~Geant4DetectorConstruction() {
+Geant4DetectorConstruction::~Geant4DetectorConstruction() {
+  s_instance = 0;
 }
 
-G4VPhysicalVolume* DD4hep::Simulation::Geant4DetectorConstruction::Construct() {
-  typedef Simulation::Geant4Converter Geant4Converter;
+G4VPhysicalVolume* Geant4DetectorConstruction::Construct() {
   Geant4Mapping& g4map = Geant4Mapping::instance();
-  DetElement world = m_lcdd.world();
+  Geometry::DetElement world = m_lcdd.world();
   Geant4Converter conv(m_lcdd, m_outputLevel);
   Geant4GeometryInfo* info = conv.create(world).detach();
   g4map.attach(info);
@@ -57,3 +74,66 @@ G4VPhysicalVolume* DD4hep::Simulation::Geant4DetectorConstruction::Construct() {
 #endif
   return m_world;
 }
+
+/// Access to the converted regions
+const Geant4GeometryMaps::RegionMap& Geant4DetectorConstruction::regions() const   {
+  Geant4GeometryInfo* p = Geant4Mapping::instance().ptr();
+  if ( p ) return p->g4Regions;
+  throw runtime_error("+++ Geant4DetectorConstruction::regions: Access not possible. Geometry is not yet converted!");
+}
+
+/// Access to the converted sensitive detectors
+const Geant4GeometryMaps::SensDetMap& Geant4DetectorConstruction::sensitives() const   {
+  Geant4GeometryInfo* p = Geant4Mapping::instance().ptr();
+  if ( p ) return p->g4SensDets;
+  throw runtime_error("+++ Geant4DetectorConstruction::sensitives: Access not possible. Geometry is not yet converted!");
+}
+
+/// Access to the converted volumes
+const Geant4GeometryMaps::VolumeMap& Geant4DetectorConstruction::volumes() const   {
+  Geant4GeometryInfo* p = Geant4Mapping::instance().ptr();
+  if ( p ) return p->g4Volumes;
+  throw runtime_error("+++ Geant4DetectorConstruction::volumes: Access not possible. Geometry is not yet converted!");
+}
+
+/// Access to the converted shapes
+const Geant4GeometryMaps::SolidMap& Geant4DetectorConstruction::shapes() const   {
+  Geant4GeometryInfo* p = Geant4Mapping::instance().ptr();
+  if ( p ) return p->g4Solids;
+  throw runtime_error("+++ Geant4DetectorConstruction::shapes: Access not possible. Geometry is not yet converted!");
+}
+
+/// Access to the converted limit sets
+const Geant4GeometryMaps::LimitMap& Geant4DetectorConstruction::limits() const   {
+  Geant4GeometryInfo* p = Geant4Mapping::instance().ptr();
+  if ( p ) return p->g4Limits;
+  throw runtime_error("+++ Geant4DetectorConstruction::limits: Access not possible. Geometry is not yet converted!");
+}
+
+/// Access to the converted assemblies
+const Geant4GeometryMaps::AssemblyMap& Geant4DetectorConstruction::assemblies() const   {
+  Geant4GeometryInfo* p = Geant4Mapping::instance().ptr();
+  if ( p ) return p->g4AssemblyVolumes;
+  throw runtime_error("+++ Geant4DetectorConstruction::assemblies: Access not possible. Geometry is not yet converted!");
+}
+
+/// Access to the converted placements
+const Geant4GeometryMaps::PlacementMap& Geant4DetectorConstruction::placements() const   {
+  Geant4GeometryInfo* p = Geant4Mapping::instance().ptr();
+  if ( p ) return p->g4Placements;
+  throw runtime_error("+++ Geant4DetectorConstruction::placements: Access not possible. Geometry is not yet converted!");
+}
+
+/// Access to the converted materials
+const Geant4GeometryMaps::MaterialMap& Geant4DetectorConstruction::materials() const   {
+  Geant4GeometryInfo* p = Geant4Mapping::instance().ptr();
+  if ( p ) return p->g4Materials;
+  throw runtime_error("+++ Geant4DetectorConstruction::materials: Access not possible. Geometry is not yet converted!");
+}
+
+/// Access to the converted elements
+const Geant4GeometryMaps::ElementMap& Geant4DetectorConstruction::elements() const   {
+  Geant4GeometryInfo* p = Geant4Mapping::instance().ptr();
+  if ( p ) return p->g4Elements;
+  throw runtime_error("+++ Geant4DetectorConstruction::elements: Access not possible. Geometry is not yet converted!");
+}
diff --git a/DDG4/src/Geant4Exec.cpp b/DDG4/src/Geant4Exec.cpp
index 78a9198a3..60bc26658 100644
--- a/DDG4/src/Geant4Exec.cpp
+++ b/DDG4/src/Geant4Exec.cpp
@@ -280,8 +280,6 @@ namespace DD4hep {
       runAction->releaseContextFromClients();
       destroyClientContext(evt);
     }
-
-
   }
 }
 
@@ -315,7 +313,7 @@ int Geant4Exec::configure(Geant4Kernel& kernel) {
 	     "You sure you loaded the geometry properly?",int(lcdd.detectors().size()));
   }
   // Get the detector constructed
-  Geant4DetectorConstruction* detector = new Geant4DetectorConstruction(kernel);
+  Geant4DetectorConstruction* detector = Geant4DetectorConstruction::instance(kernel);
 
   runManager.SetUserInitialization(detector);
   G4VUserPhysicsList* physics = 0;
diff --git a/DDG4/src/Geant4InputAction.cpp b/DDG4/src/Geant4InputAction.cpp
index f833caa6c..161a4e9de 100644
--- a/DDG4/src/Geant4InputAction.cpp
+++ b/DDG4/src/Geant4InputAction.cpp
@@ -9,11 +9,10 @@
 //====================================================================
 
 // Framework include files
-#include "DD4hep/Printout.h"
-#include "DD4hep/Primitives.h"
-#include "DDG4/Geant4InputAction.h"
+#include "DD4hep/Plugins.h"
 #include "DDG4/Geant4Primary.h"
 #include "DDG4/Geant4Context.h"
+#include "DDG4/Geant4InputAction.h"
 
 #include "G4Event.hh"
 
@@ -23,7 +22,7 @@ typedef DD4hep::ReferenceBitMask<int> PropertyMask;
 
 /// Initializing constructor
 Geant4EventReader::Geant4EventReader(const std::string& nam) 
-  : m_name(nam), m_directAccess(false)
+: m_name(nam), m_directAccess(false), m_currEvent(0)
 {
 }
 
@@ -31,6 +30,41 @@ Geant4EventReader::Geant4EventReader(const std::string& nam)
 Geant4EventReader::~Geant4EventReader()   {
 }
 
+/// Skip event. To be implemented for sequential sources
+Geant4EventReader::EventReaderStatus Geant4EventReader::skipEvent()  { 
+  if ( hasDirectAccess() )   {
+    ++m_currEvent;
+    return EVENT_READER_OK;
+  }
+  std::vector<Particle*> particles;
+  ++m_currEvent;
+  EventReaderStatus sc = readParticles(m_currEvent,particles);
+  for_each(particles.begin(),particles.end(),deleteObject<Particle>);
+  return sc;
+}
+
+/// Move to the indicated event number.
+Geant4EventReader::EventReaderStatus 
+Geant4EventReader::moveToEvent(int event_number)   {
+  if ( m_currEvent == event_number-1 )  {
+    return EVENT_READER_OK;
+  }
+  else if ( hasDirectAccess() )   {
+    m_currEvent = event_number-1;
+    return EVENT_READER_OK;
+  }
+  else if ( event_number<m_currEvent )   {
+    return EVENT_READER_ERROR;
+  }
+  else  {
+    for(int i=m_currEvent; i<event_number;++i)
+      skipEvent();
+    m_currEvent = event_number-1;
+    return EVENT_READER_OK;
+  }
+  return EVENT_READER_ERROR;
+}
+
 /// Standard constructor
 Geant4InputAction::Geant4InputAction(Geant4Context* context, const string& name)
   : Geant4GeneratorAction(context,name), m_reader(0)
@@ -65,22 +99,29 @@ int Geant4InputAction::readParticles(int evt_number, std::vector<Particle*>& par
     try  {
       m_reader = PluginService::Create<Geant4EventReader*>(tn.first,tn.second);
       if ( 0 == m_reader )   {
+	PluginDebug dbg();
+	m_reader = PluginService::Create<Geant4EventReader*>(tn.first,tn.second);
 	abortRun(issue(evid)+"Error creating reader plugin.",
 		 "Failed to create file reader of type %s. Cannot open dataset %s",
 		 tn.first.c_str(),tn.second.c_str());
-	return 0;
+	return Geant4EventReader::EVENT_READER_NO_FACTORY;
       }
     }
     catch(const exception& e)  {
       err = e.what();
     }
     if ( !err.empty() )  {
-      abortRun(issue(evid)+err,"Error when reading file %s",m_input.c_str());
-      return 0;
+      abortRun(issue(evid)+err,"Error when creating reader for file %s",m_input.c_str());
+      return Geant4EventReader::EVENT_READER_NO_FACTORY;
     }
   }
-  int status = m_reader->readParticles(evid,particles);
-  if ( 0 != status )  {
+  int status = m_reader->moveToEvent(evid);
+  if ( Geant4EventReader::EVENT_READER_OK != status )  {
+    abortRun(issue(evid)+"Error when moving to event - may be end of file.",
+	     "Error when reading file %s",m_input.c_str());
+   }
+  status = m_reader->readParticles(evid,particles);
+  if ( Geant4EventReader::EVENT_READER_OK != status )  {
     abortRun(issue(evid)+"Error when reading file - may be end of file.",
 	     "Error when reading file %s",m_input.c_str());
   }
@@ -95,7 +136,7 @@ void Geant4InputAction::operator()(G4Event* event)   {
   Geant4PrimaryInteraction* inter = new Geant4PrimaryInteraction();
 
   int result = readParticles(event->GetEventID(),primaries);
-  if ( result != 0 )   {    // handle I/O error, but how?
+  if ( result != Geant4EventReader::EVENT_READER_OK )   {    // handle I/O error, but how?
     return;
   }
   prim->add(m_mask, inter);
diff --git a/DDG4/src/Geant4InteractionVertexSmear.cpp b/DDG4/src/Geant4InteractionVertexSmear.cpp
index a531b6490..5e33448d1 100644
--- a/DDG4/src/Geant4InteractionVertexSmear.cpp
+++ b/DDG4/src/Geant4InteractionVertexSmear.cpp
@@ -39,8 +39,6 @@ Geant4InteractionVertexSmear::~Geant4InteractionVertexSmear() {
 /// Callback to generate primary particles
 void Geant4InteractionVertexSmear::operator()(G4Event*) {
   typedef Geant4PrimaryEvent::Interaction Interaction;
-  typedef Geant4Particle Particle;
-  typedef Geant4Particle Vertex;
   Geant4Random& rndm = context()->event().random();
   Geant4PrimaryEvent* evt = context()->event().extension<Geant4PrimaryEvent>();
   Interaction* inter = evt->get(m_mask);
diff --git a/DDG4/src/Geant4ParticleHandler.cpp b/DDG4/src/Geant4ParticleHandler.cpp
index 90a700d9c..c2b3155d7 100644
--- a/DDG4/src/Geant4ParticleHandler.cpp
+++ b/DDG4/src/Geant4ParticleHandler.cpp
@@ -13,6 +13,7 @@
 #include "DDG4/Geant4StepHandler.h"
 #include "DDG4/Geant4TrackHandler.h"
 #include "DDG4/Geant4EventAction.h"
+#include "DDG4/Geant4SensDetAction.h"
 #include "DDG4/Geant4TrackingAction.h"
 #include "DDG4/Geant4SteppingAction.h"
 #include "DDG4/Geant4ParticleHandler.h"
@@ -148,14 +149,18 @@ void Geant4ParticleHandler::mark(const G4Track* track)   {
   PropertyMask mask(m_currTrack.reason);
   mask.set(G4PARTICLE_CREATED_HIT);
   /// Check if the track origines from the calorimeter. 
-  // If yes, flag it, because it is a candidate fro removal.
-  G4VPhysicalVolume* vol = track->GetVolume();
-  if ( strstr(vol->GetName().c_str(),"cal") )  { // just for test!
+  // If yes, flag it, because it is a candidate for removal.
+  G4LogicalVolume*       vol = track->GetVolume()->GetLogicalVolume();
+  G4VSensitiveDetector*   g4 = vol->GetSensitiveDetector();
+  Geant4ActionSD* sd = dynamic_cast<Geant4ActionSD*>(g4);
+  string typ = sd ? sd->sensitiveType() : string();
+  if ( typ == "calorimeter" )
     mask.set(G4PARTICLE_CREATED_CALORIMETER_HIT);
-  }
-  else if ( !mask.isSet(G4PARTICLE_CREATED_TRACKER_HIT) )  {
+  else if ( typ == "tracker" )
     mask.set(G4PARTICLE_CREATED_TRACKER_HIT);
-  }
+  else // Assume by default "tracker"
+    mask.set(G4PARTICLE_CREATED_TRACKER_HIT);
+
   //Geant4ParticleHandle(&m_currTrack).dump4(outputLevel(),vol->GetName(),"hit created by particle");
 }
 
diff --git a/DDG4/src/Geant4SensDetAction.cpp b/DDG4/src/Geant4SensDetAction.cpp
index 46a3918ae..9ebcd47ff 100644
--- a/DDG4/src/Geant4SensDetAction.cpp
+++ b/DDG4/src/Geant4SensDetAction.cpp
@@ -197,7 +197,6 @@ long long int Geant4Sensitive::volumeID(G4Step* s) {
 /// Returns the cellID(volumeID+local coordinate encoding) of the sensitive volume corresponding to the step
 long long int Geant4Sensitive::cellID(G4Step* s) {
   StepHandler h(s);
-  typedef DDSegmentation::Vector3D _V;
   Geant4VolumeManager volMgr = Geant4Mapping::instance().volumeManager();
   VolumeID volID = volMgr.volumeID(h.preTouchable());
   if ( m_segmentation.isValid() )  {
@@ -219,6 +218,7 @@ Geant4SensDetActionSequence::Geant4SensDetActionSequence(Geant4Context* context,
   context->sensitiveActions().insert(name(), this);
   /// Update the sensitive detector type, so that the proper instance is created
   m_sensitive = context->lcdd().sensitiveDetector(nam);
+  m_sensitiveType = m_sensitive.type();
   m_sensitive.setType("Geant4SensDet");
   InstanceCount::increment(this);
 }
diff --git a/UtilityApps/src/teve_display.cpp b/UtilityApps/src/teve_display.cpp
index 4433192ca..0460b6e09 100644
--- a/UtilityApps/src/teve_display.cpp
+++ b/UtilityApps/src/teve_display.cpp
@@ -75,7 +75,7 @@ static long teve_display(LCDD& lcdd, int /* argc */, char** /* argv */) {
   TEveGeoTopNode* tn = new TEveGeoTopNode(mgr, mgr->GetTopNode());
   tn->SetVisLevel(4);
 
-  EvNavHandler *fh = new EvNavHandler;
+  /* EvNavHandler *fh = */ new EvNavHandler;
 
   // // ---- try to set transparency - does not seem to work ...
   // TGeoNode* node1 = gGeoManager->GetTopNode();
diff --git a/cmake/DD4hepConfig.cmake.in b/cmake/DD4hepConfig.cmake.in
index 99ae5065c..3ea3dde09 100644
--- a/cmake/DD4hepConfig.cmake.in
+++ b/cmake/DD4hepConfig.cmake.in
@@ -50,7 +50,7 @@ INCLUDE( ${DD4hep_ROOT}/cmake/DD4hepMacros.cmake )
 # additional components are set by cmake in variable PKG_FIND_COMPONENTS
 # first argument should be the package name
 if(@DD4HEP_USE_GEANT4@)
-  CHECK_PACKAGE_LIBS( DD4hep DD4hepCore DDSegmentation DD4hepRec DD4hepPlugins DD4hepG4 ) 
+  CHECK_PACKAGE_LIBS( DD4hep DD4hepCore DDSegmentation DD4hepRec DD4hepG4 ) 
 
   #--- if geant 4 was built with CLHEP we need to export this to client packages
   if( @GEANT4_USE_CLHEP@)
@@ -60,7 +60,7 @@ if(@DD4HEP_USE_GEANT4@)
   set( Geant4_DIR @Geant4_DIR@)
 
 else()
-  CHECK_PACKAGE_LIBS( DD4hep DD4hepCore DDSegmentation DD4hepRec DD4hepPlugins ) 
+  CHECK_PACKAGE_LIBS( DD4hep DD4hepCore DDSegmentation DD4hepRec ) 
 endif()
 
 
-- 
GitLab