diff --git a/DDG4/include/DDG4/Geant4GeometryInfo.h b/DDG4/include/DDG4/Geant4GeometryInfo.h
index 31b6aa6e3f2588471306527a0516038b99be4be8..a2392170e762f5b86e3f7a0f5edcc6e6eb2a1ceb 100644
--- a/DDG4/include/DDG4/Geant4GeometryInfo.h
+++ b/DDG4/include/DDG4/Geant4GeometryInfo.h
@@ -19,10 +19,13 @@
 #include <DD4hep/GeoHandler.h>
 #include <DD4hep/PropertyTable.h>
 #include <DDG4/Geant4Primitives.h>
+#include <DDG4/Geant4TouchableHandler.h>
+
 
 // C/C++ include files
 #include <map>
 #include <vector>
+#include <cstdint>
 
 // Forward declarations (TGeo)
 class TGeoElement;
@@ -64,24 +67,19 @@ namespace dd4hep {
      *  \ingroup DD4HEP_SIMULATION
      */
     namespace Geant4GeometryMaps  {
-      //typedef std::vector<const G4VPhysicalVolume*>           Geant4PlacementPath;
-      typedef std::map<Atom, G4Element*>                      ElementMap;
-      typedef std::map<const TGeoIsotope*, G4Isotope*>        IsotopeMap;
-      typedef std::map<Material, G4Material*>                 MaterialMap;
-      //typedef std::map<LimitSet, G4UserLimits*>               LimitMap;
-      typedef std::map<PlacedVolume, G4VPhysicalVolume*>      PlacementMap;
-      //typedef std::map<Region, G4Region*>                     RegionMap;
-      typedef std::map<Volume, G4LogicalVolume*>              VolumeMap;
-      typedef std::map<PlacedVolume, Geant4AssemblyVolume*>   AssemblyMap;
+      typedef std::map<Atom, G4Element*>                            ElementMap;
+      typedef std::map<const TGeoIsotope*, G4Isotope*>              IsotopeMap;
+      typedef std::map<Material, G4Material*>                       MaterialMap;
+      typedef std::map<PlacedVolume, G4VPhysicalVolume*>            PlacementMap;
+      typedef std::map<Volume, G4LogicalVolume*>                    VolumeMap;
+      typedef std::map<PlacedVolume, Geant4AssemblyVolume*>         AssemblyMap;
 
-      typedef std::vector<const TGeoNode*>                    VolumeChain;
-      typedef std::pair<VolumeChain,const G4VPhysicalVolume*> ImprintEntry;
-      typedef std::vector<ImprintEntry>                       Imprints;
-      typedef std::map<Volume,Imprints>                       VolumeImprintMap;
-      typedef std::map<const TGeoShape*, G4VSolid*>           SolidMap;
-      //typedef std::map<VisAttr, G4VisAttributes*>             VisMap;
-      //typedef std::map<Geant4PlacementPath, VolumeID>         Geant4PathMap;
-      typedef std::map<const G4VPhysicalVolume*, PlacedVolume> G4PlacementMap;
+      typedef std::vector<const TGeoNode*>                          PlacedVolumeChain;
+      typedef std::pair<PlacedVolumeChain,const G4VPhysicalVolume*> ImprintEntry;
+      typedef std::vector<ImprintEntry>                             Imprints;
+      typedef std::map<Volume,Imprints>                             VolumeImprintMap;
+      typedef std::map<const TGeoShape*, G4VSolid*>                 SolidMap;
+      typedef std::map<const G4VPhysicalVolume*, PlacedVolume>      G4PlacementMap;
     }
 
     /// Concreate class holding the relation information between geant4 objects and dd4hep objects.
@@ -92,22 +90,20 @@ namespace dd4hep {
      */
     class Geant4GeometryInfo : public TNamed, public detail::GeoHandlerTypes::GeometryInfo {
     public:
-      struct Placement  {
-	VolumeID     volumeID;
-	int          flags;
-      };
       union PlacementFlags {
-	int value;
-	struct _flags  {
-	  unsigned     parametrised:1;
-	  unsigned     replicated:1;
-	  unsigned     path_has_parametrised:1;
-	  unsigned     path_has_replicated:1;
-	} flags;
-	PlacementFlags()      { this->value = 0; }
-	PlacementFlags(int v) { this->value = v; }
+        int value;
+        struct _flags  {
+          unsigned parametrised:1;
+          unsigned replicated:1;
+        } flags;
+        PlacementFlags()      { this->value = 0; }
+        PlacementFlags(int v) { this->value = v; }
       };
-      typedef std::vector<const G4VPhysicalVolume*>  Geant4PlacementPath;
+      struct Placement  {
+        VolumeID volumeID;
+        int      flags;
+      };
+
       TGeoManager*                         manager = 0;
       Geant4GeometryMaps::IsotopeMap       g4Isotopes;
       Geant4GeometryMaps::ElementMap       g4Elements;
@@ -126,35 +122,45 @@ namespace dd4hep {
         PropertyVector() = default;
         ~PropertyVector() = default;
       };
-      std::map<PropertyTable,  PropertyVector*>                g4OpticalProperties;
-      std::map<OpticalSurface, G4OpticalSurface*>              g4OpticalSurfaces;
-      std::map<SkinSurface,    G4LogicalSkinSurface*>          g4SkinSurfaces;
-      std::map<BorderSurface,  G4LogicalBorderSurface*>        g4BorderSurfaces;
-      std::map<Region, G4Region*>                              g4Regions;
-      std::map<VisAttr, G4VisAttributes*>                      g4Vis;
-      std::map<LimitSet, G4UserLimits*>                        g4Limits;
-      std::map<Geant4PlacementPath, Placement>                 g4Paths;
+      std::map<PropertyTable,    PropertyVector*>              g4OpticalProperties;
+      std::map<OpticalSurface,   G4OpticalSurface*>            g4OpticalSurfaces;
+      std::map<SkinSurface,      G4LogicalSkinSurface*>        g4SkinSurfaces;
+      std::map<BorderSurface,    G4LogicalBorderSurface*>      g4BorderSurfaces;
+      std::map<Region,           G4Region*>                    g4Regions;
+      std::map<VisAttr,          G4VisAttributes*>             g4Vis;
+      std::map<LimitSet,         G4UserLimits*>                g4Limits;
+#ifdef OLD_VOLMGR_TYPE
+      typedef std::vector<const G4VPhysicalVolume*>  Geant4PlacementPath;
+      std::map<Geant4PlacementPath,         Placement>         g4Paths;
+#else
+      std::map<uint64_t,         Placement>                    g4Paths;
+#endif      
       std::map<SensitiveDetector,std::set<const TGeoVolume*> > sensitives;
       std::map<Region,           std::set<const TGeoVolume*> > regions;
       std::map<LimitSet,         std::set<const TGeoVolume*> > limits;
       G4VPhysicalVolume*                                       m_world;
       PrintLevel                                               printLevel;
+      bool                                                     has_volmgr;
       bool                                                     valid;
+
+      /// Assemble Geant4 volume path
+      static std::string placementPath(const Geant4TouchableHandler::Geant4PlacementPath& path, bool reverse=true)  {
+        return Geant4TouchableHandler::placementPath(path, reverse);
+      }
+
     private:
       friend class Geant4Mapping;
       /// Default constructor
       Geant4GeometryInfo();
       /// Default destructor
       virtual ~Geant4GeometryInfo();
+
     public:
       /// The world placement
       G4VPhysicalVolume* world() const;
       /// Set the world volume
       void setWorld(const TGeoNode* node);
-      /// Assemble Geant4 volume path
-      static std::string placementPath(const Geant4PlacementPath& path, bool reverse=true);
     };
-
   }    // End namespace sim
 }      // End namespace dd4hep
 #endif // DDG4_GEANT4GEOMETRYINFO_H
diff --git a/DDG4/include/DDG4/Geant4TouchableHandler.h b/DDG4/include/DDG4/Geant4TouchableHandler.h
index 0be5a58c1d5c156d40c2d5552e4169491ca3db24..37b6e38e24b09a99b78801a076dd0e17774909d1 100644
--- a/DDG4/include/DDG4/Geant4TouchableHandler.h
+++ b/DDG4/include/DDG4/Geant4TouchableHandler.h
@@ -55,6 +55,9 @@ namespace dd4hep {
       /// Default constructor. Takes the step's pre-touchable
       Geant4TouchableHandler(const G4Step* step, bool use_post_step_point);
 
+      /// Assemble Geant4 volume path
+      static std::string placementPath(const Geant4PlacementPath& path, bool reverse=true);
+
       /// Helper: Generate placement path from touchable object
       Geant4PlacementPath placementPath(bool exception=false) const;
 
diff --git a/DDG4/include/DDG4/Geant4VolumeManager.h b/DDG4/include/DDG4/Geant4VolumeManager.h
index 02027ad3e160c7245f0dce5ff3d21ae9bd17dfed..e162be4a0ce157ecbf0da3e198d4a62443f3292e 100644
--- a/DDG4/include/DDG4/Geant4VolumeManager.h
+++ b/DDG4/include/DDG4/Geant4VolumeManager.h
@@ -18,7 +18,9 @@
 #include <DD4hep/IDDescriptor.h>
 #include <DDG4/Geant4Primitives.h>
 
+// Geant4 include files
 #include <G4VTouchable.hh>
+
 // Geant4 forward declarations
 class G4VPhysicalVolume;
 
@@ -68,8 +70,6 @@ namespace dd4hep {
       /// Helper: Generate placement path from touchable object
       std::vector<const G4VPhysicalVolume*>
       placementPath(const G4VTouchable* touchable, bool exception = true) const;
-      /// Access CELLID by placement path
-      //VolumeID volumeID(const std::vector<const G4VPhysicalVolume*>& path) const;
       /// Access CELLID by Geant4 touchable object
       VolumeID volumeID(const G4VTouchable* touchable) const;
       /// Accessfully decoded volume fields  by placement path
@@ -79,7 +79,6 @@ namespace dd4hep {
       void volumeDescriptor(const G4VTouchable* touchable,
                             std::pair<VolumeID,std::vector<std::pair<const BitFieldElement*, VolumeID> > >& volume_desc) const;
     };
-
   }    // End namespace sim
 }      // End namespace dd4hep
 #endif // DDG4_GEANT4VOLUMEMANAGER_H
diff --git a/DDG4/src/Geant4AssemblyVolume.cpp b/DDG4/src/Geant4AssemblyVolume.cpp
index 4055636e78247d9666806507f8e1f72fb76cffbb..95b1d784bd2a4d31d5831e85542865818095ba11 100644
--- a/DDG4/src/Geant4AssemblyVolume.cpp
+++ b/DDG4/src/Geant4AssemblyVolume.cpp
@@ -86,7 +86,7 @@ void Geant4AssemblyVolume::imprint(const Geant4Converter& cnv,
 
   path = detail::tools::placementPath(chain);
   printout(cnv.debugPlacements ? ALWAYS : DEBUG, "Geant4Converter",
-	   "++ Assembly: %s", path.c_str());
+           "++ Assembly: %s", path.c_str());
   std::vector<G4AssemblyTriplet>::iterator iter = par_ass->GetTripletsIterator();
   for( unsigned int i = 0, n = par_ass->TotalTriplets(); i < n; i++, iter++ )  {
     Chain            new_chain = chain;
@@ -97,14 +97,14 @@ void Geant4AssemblyVolume::imprint(const Geant4Converter& cnv,
     new_chain.emplace_back(node);
     path = detail::tools::placementPath(new_chain);
     printout(cnv.debugPlacements ? ALWAYS : DEBUG, "Geant4Converter",
-	     " Assembly: Entry: %s", path.c_str());
+             " Assembly: Entry: %s", path.c_str());
 
     G4Transform3D Ta( *(triplet.GetRotation()), triplet.GetTranslation() );
-    if ( triplet.IsReflection() )  {
+    if( triplet.IsReflection() )  {
       Ta = Ta * G4ReflectZ3D();
     }
     G4Transform3D Tfinal = transformation * Ta;
-    if ( triplet.GetVolume() )    {
+    if( triplet.GetVolume() )  {
       // Generate the unique name for the next PV instance
       // The name has format:
       //
@@ -119,9 +119,9 @@ void Geant4AssemblyVolume::imprint(const Geant4Converter& cnv,
       pvName << "AV_"
              << m_assembly->GetAssemblyID()
              << '!'
-	     << parent->GetName()
-	     << '#'
-	     << parent->GetNumber()
+             << parent->GetName()
+             << '#'
+             << parent->GetNumber()
              << '!'
              << node->GetName()
              << '#'
@@ -140,24 +140,24 @@ void Geant4AssemblyVolume::imprint(const Geant4Converter& cnv,
                                                   node->GetNumber(),
                                                   surfCheck );
 
-      info.g4VolumeImprints[vol].emplace_back(new_chain,pvPlaced.first);
+      info.g4VolumeImprints[vol].emplace_back(new_chain, pvPlaced.first);
       printout(cnv.debugPlacements ? ALWAYS : DEBUG,
-	       "Geant4Converter", "++ Place %svolume %s in assembly.",
-	       triplet.IsReflection() ? "REFLECTED " : "", path.c_str());
+               "Geant4Converter", "++ Place %svolume %s in assembly.",
+               triplet.IsReflection() ? "REFLECTED " : "", path.c_str());
       printout(cnv.debugPlacements ? ALWAYS : DEBUG,
-	       "Geant4Converter", " Assembly:Parent: %s %s %p G4:%s",
-	       parent->GetName(), node->GetName(),
-	       (void*)node, pvName.str().c_str());
-      if ( pvPlaced.second )  {
+               "Geant4Converter", " Assembly:Parent: %s %s %p G4:%s",
+               parent->GetName(), node->GetName(),
+               (void*)node, pvName.str().c_str());
+      if( pvPlaced.second )  {
         G4Exception("Geant4AssemblyVolume::imprint(..)", "GeomVol0003", FatalException,
                     "Fancy construct popping new mother from the stack!");
       }
     }
-    else if ( triplet.GetAssembly() )  {
+    else if( triplet.GetAssembly() )  {
       // Place volumes in this assembly with composed transformation
       imprint(cnv, parent, std::move(new_chain), avol, pMotherLV, Tfinal, surfCheck );
     }
-    else   {
+    else  {
       G4Exception("Geant4AssemblyVolume::imprint(..)", "GeomVol0003", FatalException,
                   "Triplet has no volume and no assembly");
     }
diff --git a/DDG4/src/Geant4Converter.cpp b/DDG4/src/Geant4Converter.cpp
index 56ea36de80e8778086d6fecbf5ab707ab3507dba..ce4de2fd48605f0fa46de02c98e71eeb626031d4 100644
--- a/DDG4/src/Geant4Converter.cpp
+++ b/DDG4/src/Geant4Converter.cpp
@@ -745,7 +745,9 @@ void* Geant4Converter::handleVolume(const std::string& name, const TGeoVolume* v
   PrintLevel lvl = debugVolumes ? ALWAYS : outputLevel;
   Geant4GeometryMaps::VolumeMap::const_iterator volIt = info.g4Volumes.find(volume);
   if ( _v.testFlagBit(Volume::VETO_SIMU) )  {
-    printout(lvl, "Geant4Converter", "++ Volume %s not converted [Veto'ed for simulation]",volume->GetName());
+    printout(lvl, "Geant4Converter",
+	     "++ Volume %s not converted [Veto'ed for simulation]",
+	     volume->GetName());
     return nullptr;
   }
   else if (volIt == info.g4Volumes.end() ) {
@@ -786,7 +788,7 @@ void* Geant4Converter::handleVolume(const std::string& name, const TGeoVolume* v
 
     G4LogicalVolume* g4vol = nullptr;
     if( _v.hasProperties() && !_v.getProperty(GEANT4_TAG_PLUGIN,"").empty() )   {
-      Detector* det = const_cast<Detector*>(&m_detDesc); 
+      Detector*   det = const_cast<Detector*>(&m_detDesc); 
       std::string plugin = _v.getProperty(GEANT4_TAG_PLUGIN,"");
       g4vol = PluginService::Create<G4LogicalVolume*>(plugin, det, _v, g4solid, g4medium);
       if ( !g4vol )    {
@@ -800,8 +802,9 @@ void* Geant4Converter::handleVolume(const std::string& name, const TGeoVolume* v
     /// Set smartless optimization
     unsigned char smart_less_value = _v.smartlessValue();
     if( smart_less_value != Volume::NO_SMARTLESS_OPTIMIZATION )  {
-      printout(ALWAYS, "Geant4Converter", "++ Volume %s Set Smartless value to %d",
-               vnam, int(smart_less_value));
+      printout(ALWAYS, "Geant4Converter",
+	       "++ Volume %s Set Smartless value to %d",
+	       vnam, int(smart_less_value));
       g4vol->SetSmartless( smart_less_value );
     }
     /// Assign limits if necessary
@@ -809,8 +812,9 @@ void* Geant4Converter::handleVolume(const std::string& name, const TGeoVolume* v
       g4vol->SetUserLimits(g4limits);
     }
     if( g4region )   {
-      printout(plevel, "Geant4Converter", "++ Volume     + Apply REGION settings: %-24s to volume %s.",
-               reg.name(), vnam);
+      printout(plevel, "Geant4Converter",
+	       "++ Volume     + Apply REGION settings: %-24s to volume %s.",
+	       reg.name(), vnam);
       // Handle the region settings for the world volume seperately.
       // Geant4 does NOT WANT any regions assigned to the workd volume.
       // The world's region is created in the G4RunManagerKernel!
diff --git a/DDG4/src/Geant4GeometryInfo.cpp b/DDG4/src/Geant4GeometryInfo.cpp
index 666df2fa8e93d59c95e2ae3cc9d1dfa035c0d749..20fe5bb1c4bbd3393c97fc83d3922f9bdef4eefd 100644
--- a/DDG4/src/Geant4GeometryInfo.cpp
+++ b/DDG4/src/Geant4GeometryInfo.cpp
@@ -21,21 +21,6 @@
 
 using namespace dd4hep::sim;
 
-std::string Geant4GeometryInfo::placementPath(const Geant4PlacementPath& path, bool reverse)   {
-  std::string path_name;
-  if ( reverse )  {
-    for (Geant4PlacementPath::const_reverse_iterator pIt = path.rbegin(); pIt != path.rend(); ++pIt) {
-      path_name += "/"; path_name += (*pIt)->GetName();
-    }
-  }
-  else  {
-    for (Geant4PlacementPath::const_iterator pIt = path.begin(); pIt != path.end(); ++pIt) {
-      path_name += "/"; path_name += (*pIt)->GetName();
-    }
-  }
-  return path_name;
-}
-
 /// Default constructor
 Geant4GeometryInfo::Geant4GeometryInfo()
   : TNamed("Geant4GeometryInfo", "Geant4GeometryInfo"), m_world(0), printLevel(DEBUG), valid(false) {
diff --git a/DDG4/src/Geant4Mapping.cpp b/DDG4/src/Geant4Mapping.cpp
index 490f8bd71fa81b4a32430920a7340fcdaba42aa6..fc8abd32f0015ca37848d0e1eeba8fa756c1e5ab 100644
--- a/DDG4/src/Geant4Mapping.cpp
+++ b/DDG4/src/Geant4Mapping.cpp
@@ -68,7 +68,7 @@ void Geant4Mapping::attach(Geant4GeometryInfo* data_ptr) {
 /// Access the volume manager
 Geant4VolumeManager Geant4Mapping::volumeManager() const {
   if ( m_dataPtr ) {
-    if ( m_dataPtr->g4Paths.empty() ) {
+    if ( m_dataPtr->has_volmgr ) {
       return Geant4VolumeManager(m_detDesc, m_dataPtr);
     }
     return Geant4VolumeManager(Handle < Geant4GeometryInfo > (m_dataPtr));
diff --git a/DDG4/src/Geant4TouchableHandler.cpp b/DDG4/src/Geant4TouchableHandler.cpp
index c183677047f8f40af7e36d857abfe550a4fe674f..b6a48060bbb59299071d009a513883ec2deecc52 100644
--- a/DDG4/src/Geant4TouchableHandler.cpp
+++ b/DDG4/src/Geant4TouchableHandler.cpp
@@ -54,8 +54,24 @@ Geant4TouchableHandler::Geant4PlacementPath Geant4TouchableHandler::placementPat
   return path_val;
 }
 
+/// Assemble Geant4 volume path
+std::string Geant4TouchableHandler::placementPath(const Geant4PlacementPath& path, bool reverse)   {
+  std::string path_name;
+  if ( reverse )  {
+    for (Geant4PlacementPath::const_reverse_iterator pIt = path.rbegin(); pIt != path.rend(); ++pIt) {
+      path_name += "/"; path_name += (*pIt)->GetName();
+    }
+  }
+  else  {
+    for (Geant4PlacementPath::const_iterator pIt = path.begin(); pIt != path.end(); ++pIt) {
+      path_name += "/"; path_name += (*pIt)->GetName();
+    }
+  }
+  return path_name;
+}
+
 /// Helper: Access the placement path of a Geant4 touchable object as a string
 std::string Geant4TouchableHandler::path()  const   {
-  return Geant4GeometryInfo::placementPath(this->placementPath());
+  return Geant4TouchableHandler::placementPath(this->placementPath());
 }
 
diff --git a/DDG4/src/Geant4VolumeManager.cpp b/DDG4/src/Geant4VolumeManager.cpp
index a24ee1e5e906d87eabc9cfc474753a05ac3556e6..a89949b46f24de3c36a296dea55d79051e27e1f8 100644
--- a/DDG4/src/Geant4VolumeManager.cpp
+++ b/DDG4/src/Geant4VolumeManager.cpp
@@ -16,6 +16,8 @@
 #include <DD4hep/Volumes.h>
 #include <DD4hep/DetElement.h>
 #include <DD4hep/DetectorTools.h>
+#include <DD4hep/VolumeManager.h>
+#include <DD4hep/detail/VolumeManagerInterna.h>
 #include <DDG4/Geant4VolumeManager.h>
 #include <DDG4/Geant4TouchableHandler.h>
 #include <DDG4/Geant4Mapping.h>
@@ -37,10 +39,16 @@ using VolIDDescriptor = std::pair<VolumeID,std::vector<std::pair<const BitFieldE
 namespace  {
 
   /// Helper class to populate the Geant4 volume manager
+  /**
+   *  \author  M.Frank
+   *  \version 1.0
+   *  \ingroup DD4HEP_SIMULATION
+   */
   struct Populator {
 
     typedef std::vector<const TGeoNode*> Chain;
-    typedef std::map<VolumeID,Geant4GeometryInfo::Geant4PlacementPath> Registries;
+    // typedef std::map<VolumeID,Geant4TouchableHandler::Geant4PlacementPath> Registries;
+    typedef std::set<VolumeID> Registries;
 
     /// Reference to the Detector instance
     const Detector&     m_detDesc;
@@ -51,16 +59,32 @@ namespace  {
 
     /// Default constructor
     Populator(const Detector& description, Geant4GeometryInfo& g)
-      : m_detDesc(description), m_geo(g) {
+      : m_detDesc(description), m_geo(g)
+    {
+    }
+
+    typedef std::pair<VolumeID, VolumeID> Encoding;
+    /// Compute the encoding for a set of VolIDs within a readout descriptor
+    static Encoding encoding(const IDDescriptor iddesc, const PlacedVolume::VolIDs& ids)  {
+      VolumeID volume_id = 0, mask = 0;
+      for( const auto& id : ids )  {
+        const BitFieldElement* f = iddesc.field(id.first);
+        VolumeID msk = f->mask();
+        int      off = f->offset();
+        VolumeID val = id.second;    // Necessary to extend volume IDs > 32 bit
+        volume_id |= ((f->value(val << off) << off)&msk);
+        mask      |= msk;
+      }
+      return std::make_pair(volume_id, mask);
     }
 
     /// Populate the Volume manager
-    void populate(DetElement e) {
+    void populate(DetElement e)  {
       const DetElement::Children& c = e.children();
-      for (const auto& i : c)  {
+      for( const auto& i : c )  {
         DetElement de = i.second;
         PlacedVolume pv = de.placement();
-        if (pv.isValid()) {
+        if( pv.isValid() )  {
           Chain chain;
           SensitiveDetector sd;
           PlacedVolume::VolIDs ids;
@@ -70,15 +94,17 @@ namespace  {
           continue;
         }
         printout(WARNING, "Geant4VolumeManager",
-                 "++ Detector element %s of type %s has no placement.", de.name(), de.type().c_str());
+                 "++ Detector element %s of type %s has no placement.",
+                 de.name(), de.type().c_str());
       }
       /// Needed to compute the cellID of parameterized volumes
       for( const auto& pv : m_geo.g4Placements )  {
-        if ( pv.second->IsParameterised() )
+        if( pv.second->IsParameterised() )
           m_geo.g4Parameterised[pv.second] = pv.first;
-        if ( pv.second->IsReplicated() )
+        if( pv.second->IsReplicated() )
           m_geo.g4Replicated[pv.second] = pv.first;
       }
+      m_entries.clear();
     }
 
     /// Scan a single physical volume and look for sensitive elements below
@@ -89,21 +115,21 @@ namespace  {
 
       chain.emplace_back(node);
       ids.PlacedVolume::VolIDs::Base::insert(ids.end(), pv_ids.begin(), pv_ids.end());
-      if (vol.isSensitive()) {
+      if( vol.isSensitive() )  {
         sd = vol.sensitiveDetector();
-        if (sd.readout().isValid()) {
+        if( sd.readout().isValid() )  {
           add_entry(sd, node, ids, chain);
         }
-        else {
+        else  {
           printout(WARNING, "Geant4VolumeManager",
                    "populate: Strange constellation volume %s is sensitive, but has no readout! sd:%p", pv.volume().name(),
                    sd.ptr());
         }
       }
-      for (Int_t idau = 0, ndau = node->GetNdaughters(); idau < ndau; ++idau) {
+      for( Int_t idau = 0, ndau = node->GetNdaughters(); idau < ndau; ++idau )  {
         TGeoNode* daughter = node->GetDaughter(idau);
         PlacedVolume placement(daughter);
-        if ( placement.data() ) {
+        if( placement.data() ) {
           scanPhysicalVolume(daughter, ids, sd, chain);
         }
       }
@@ -111,26 +137,25 @@ namespace  {
     }
 
     void add_entry(SensitiveDetector sd, const TGeoNode* n, const PlacedVolume::VolIDs& ids, const Chain& nodes) {
-      Chain control;
-      Volume       vol;
-      const TGeoNode* node = nullptr;
-      Readout      ro = sd.readout();
-      IDDescriptor iddesc = ro.idSpec();
-      VolumeID     code = iddesc.encode(ids);
-      Geant4GeometryInfo::Geant4PlacementPath path;
-      Registries::const_iterator i = m_entries.find(code);
+      Chain           control;
+      Volume          vol;
+      Readout         rdout   = sd.readout();
+      IDDescriptor    iddesc  = rdout.idSpec();
+      VolumeID        code    = iddesc.encode(ids);
       PrintLevel print_level  = m_geo.printLevel;
       PrintLevel print_action = print_level;
       PrintLevel print_chain  = print_level;
       PrintLevel print_res    = print_level;
+      Geant4TouchableHandler::Geant4PlacementPath path;
+      Registries::const_iterator i = m_entries.find(code);
 
       printout(print_action,"Geant4VolumeManager","+++ Add path:%s vid:%016X",
-               detail::tools::placementPath(nodes,false).c_str(),code);
+               detail::tools::placementPath(nodes, false).c_str(), code);
 
       if( i == m_entries.end() ) {
         path.reserve(nodes.size());
         for( Chain::const_reverse_iterator k = nodes.rbegin(), kend=nodes.rend(); k != kend; ++k ) {
-          node = *(k);
+          const TGeoNode* node = *(k);
           auto g4pit = m_geo.g4Placements.find(node);
           if( g4pit != m_geo.g4Placements.end() )  {
             G4VPhysicalVolume* phys = g4pit->second;
@@ -142,8 +167,8 @@ namespace  {
               }
             }
             path.emplace_back(phys);
-            printout(print_chain, "Geant4VolumeManager", "+++     Chain: Node OK: %s [%s]",
-                     node->GetName(), phys->GetName().c_str());
+            printout(print_chain, "Geant4VolumeManager",
+                     "+++     Chain: Node OK: %s [%s]", node->GetName(), phys->GetName().c_str());
             continue;
           }
           control.insert(control.begin(),node);
@@ -165,20 +190,17 @@ namespace  {
         }
         if ( control.empty() )  {
           printout(print_res, "Geant4VolumeManager", "+++     Volume  IDs:%s",
-                   detail::tools::toString(ro.idSpec(),ids,code).c_str());
+                   detail::tools::toString(rdout.idSpec(),ids,code).c_str());
           path.erase(path.begin()+path.size()-1);
           printout(print_res, "Geant4VolumeManager", "+++     Map %016X to Geant4 Path:%s",
-                   (void*)code, Geant4GeometryInfo::placementPath(path).c_str());
-          if ( m_geo.g4Paths.find(path) == m_geo.g4Paths.end() ) {
+                   (void*)code, Geant4TouchableHandler::placementPath(path).c_str());
+          auto hash = detail::hash64(&path[0], path.size()*sizeof(path[0]));
+          if ( m_geo.g4Paths.find(hash) == m_geo.g4Paths.end() ) {
             Geant4GeometryInfo::PlacementFlags opt;
-            for(const auto* phys : path)  {
-              opt.flags.path_has_parametrised = phys->IsParameterised() ? 1 : 0;
-              opt.flags.path_has_replicated   = phys->IsReplicated()    ? 1 : 0;
-            }
             opt.flags.parametrised = path.front()->IsParameterised() ? 1 : 0;
             opt.flags.replicated   = path.front()->IsReplicated()    ? 1 : 0;
-            m_geo.g4Paths[path] = { code, opt.value };
-            m_entries.emplace(code,path);
+            m_geo.g4Paths[hash]    = { code, opt.value };
+            m_entries.emplace(code);
             return;
           }
           /// This is a normal case for parametrized volumes and no error
@@ -186,11 +208,11 @@ namespace  {
             return;
           }
           printout(ERROR, "Geant4VolumeManager", "populate: Severe error: Duplicated Geant4 path!!!! %s %s",
-                   " [THIS SHOULD NEVER HAPPEN]",Geant4GeometryInfo::placementPath(path).c_str());
+                   " [THIS SHOULD NEVER HAPPEN]", Geant4TouchableHandler::placementPath(path).c_str());
           goto Err;
         }
         printout(INFO, "Geant4VolumeManager", "Control block has still %d entries:%s",
-                 int(control.size()),detail::tools::placementPath(control,true).c_str());
+                 int(control.size()), detail::tools::placementPath(control,true).c_str());
         goto Err;
       }
       else  {
@@ -204,12 +226,12 @@ namespace  {
 
     Err:
       if ( i != m_entries.end() )
-        printout(ERROR,"Geant4VolumeManager"," Known G4 path: %s",Geant4GeometryInfo::placementPath((*i).second).c_str());
+        printout(ERROR,"Geant4VolumeManager"," Known G4 path: %s", Geant4TouchableHandler::placementPath(path).c_str());
       if ( !path.empty() )
-        printout(ERROR,"Geant4VolumeManager"," New   G4 path: %s",Geant4GeometryInfo::placementPath(path).c_str());
+        printout(ERROR,"Geant4VolumeManager"," New   G4 path: %s", Geant4TouchableHandler::placementPath(path).c_str());
       if ( !nodes.empty() )
-        printout(ERROR,"Geant4VolumeManager","     TGeo path: %s",detail::tools::placementPath(nodes,false).c_str());
-      printout(ERROR,"Geant4VolumeManager",  " Offend.VolIDs: %s",detail::tools::toString(ro.idSpec(),ids,code).c_str());
+        printout(ERROR,"Geant4VolumeManager","     TGeo path: %s", detail::tools::placementPath(nodes,false).c_str());
+      printout(ERROR,"Geant4VolumeManager",  " Offend.VolIDs: %s", detail::tools::toString(rdout.idSpec(),ids,code).c_str());
       throw std::runtime_error("Failed to populate Geant4 volume manager!");
     }
   };
@@ -218,9 +240,12 @@ namespace  {
 /// Initializing constructor. The tree will automatically be built if possible
 Geant4VolumeManager::Geant4VolumeManager(const Detector& description, Geant4GeometryInfo* info)
   : Handle<Geant4GeometryInfo>(info)  {
-  if (info && info->valid && info->g4Paths.empty()) {
-    Populator p(description, *info);
-    p.populate(description.world());
+  if( info && info->valid )  {
+    if( !info->has_volmgr )  {
+      Populator p(description, *info);
+      p.populate(description.world());
+      info->has_volmgr = true;
+    }
     return;
   }
   except("Geant4VolumeManager", "Attempt populate from invalid Geant4 geometry info [Invalid-Info]");
@@ -228,56 +253,37 @@ Geant4VolumeManager::Geant4VolumeManager(const Detector& description, Geant4Geom
 
 /// Helper: Generate placement path from touchable object
 std::vector<const G4VPhysicalVolume*>
-Geant4VolumeManager::placementPath(const G4VTouchable* touchable, bool exception) const {
+Geant4VolumeManager::placementPath(const G4VTouchable* touchable, bool exception) const  {
   Geant4TouchableHandler handler(touchable);
   return handler.placementPath(exception);
 }
 
 /// Check the validity of the information before accessing it.
-bool Geant4VolumeManager::checkValidity() const {
-  if (!isValid()) {
+bool Geant4VolumeManager::checkValidity() const  {
+  if( !isValid() )  {
     except("Geant4VolumeManager", "Attempt to use invalid Geant4 volume manager [Invalid-Handle]");
   }
-  else if (!ptr()->valid) {
+  else if( !ptr()->valid )  {
     except("Geant4VolumeManager", "Attempt to use invalid Geant4 geometry info [Invalid-Info]");
   }
   return true;
 }
 
-#if 0
-/// Access CELLID by placement path
-VolumeID Geant4VolumeManager::volumeID(const std::vector<const G4VPhysicalVolume*>& path) const {
-  if (!path.empty() && checkValidity()) {
-    const auto& mapping = ptr()->g4Paths;
-    auto i = mapping.find(path);
-    if ( i != mapping.end() )  {
-      return (*i).second.first;
-    }
-    if (!path[0])
-      return InvalidPath;
-    else if (!path[0]->GetLogicalVolume()->GetSensitiveDetector())
-      return Insensitive;
-  }
-  printout(INFO, "Geant4VolumeManager","+++   Bad volume Geant4 Path: %s",
-           Geant4GeometryInfo::placementPath(path).c_str());
-  return NonExisting;
-}
-#endif
-
 /// Access CELLID by Geant4 touchable object
-VolumeID Geant4VolumeManager::volumeID(const G4VTouchable* touchable) const {
+VolumeID Geant4VolumeManager::volumeID(const G4VTouchable* touchable) const  {
   Geant4TouchableHandler handler(touchable);
   std::vector<const G4VPhysicalVolume*> path = handler.placementPath();
-  if( !path.empty() && checkValidity() )  {
-    const auto& mapping = ptr()->g4Paths;
-    auto i = mapping.find(path);
-    if( i != mapping.end() )  {
+
+  if( checkValidity() && !path.empty() )  {
+    auto hash = detail::hash64(&path[0], sizeof(path[0])*path.size());
+    auto i = ptr()->g4Paths.find(hash);
+    if( i != ptr()->g4Paths.end() )  {
       const auto& e = (*i).second;
+      VolumeID volid = e.volumeID;
       /// No parametrization or replication.
       if( e.flags == 0 )  {
-        return e.volumeID;
+        return volid;
       }
-      VolumeID volid = e.volumeID;
       const auto& paramterised = ptr()->g4Parameterised;
       const auto& replicated   = ptr()->g4Replicated;
       /// This is incredibly slow .... but what can I do ? Need a better idea.
@@ -293,7 +299,8 @@ VolumeID Geant4VolumeManager::volumeID(const G4VTouchable* touchable) const {
             volid |= IDDescriptor::encode(field, copy_no);
             continue;
           }
-          except("Geant4VolumeManager","Error  Geant4VolumeManager::volumeID(const G4VTouchable* touchable)");
+          except("Geant4VolumeManager",
+                 "Error  Geant4VolumeManager::volumeID(const G4VTouchable* touchable)");
         }
         else if( phys->IsReplicated() )   {
           int copy_no = touchable->GetCopyNumber(j);
@@ -303,7 +310,8 @@ VolumeID Geant4VolumeManager::volumeID(const G4VTouchable* touchable) const {
             volid |= IDDescriptor::encode(field, copy_no);
             continue;
           }
-          except("Geant4VolumeManager","Error  Geant4VolumeManager::volumeID(const G4VTouchable* touchable)");
+          except("Geant4VolumeManager",
+                 "Error  Geant4VolumeManager::volumeID(const G4VTouchable* touchable)");
         }
       }
       return volid;
@@ -313,8 +321,8 @@ VolumeID Geant4VolumeManager::volumeID(const G4VTouchable* touchable) const {
     else if( !path[0]->GetLogicalVolume()->GetSensitiveDetector() )
       return Insensitive;
   }
-  printout(INFO, "Geant4VolumeManager","+++   Bad volume Geant4 Path: %s",
-           Geant4GeometryInfo::placementPath(path).c_str());
+  printout(INFO, "Geant4VolumeManager", "+++   Bad volume Geant4 Path: %s",
+           Geant4TouchableHandler::placementPath(path).c_str());
   return NonExisting;
 }
 
@@ -325,9 +333,9 @@ void Geant4VolumeManager::volumeDescriptor(const std::vector<const G4VPhysicalVo
   vol_desc.second.clear();
   vol_desc.first = NonExisting;
   if( !path.empty() && checkValidity() )  {
-    const auto& mapping = ptr()->g4Paths;
-    auto i = mapping.find(path);
-    if( i != mapping.end() ) {
+    auto hash = detail::hash64(&path[0], sizeof(path[0])*path.size());
+    auto i = ptr()->g4Paths.find(hash);
+    if( i != ptr()->g4Paths.end() )  {
       VolumeID vid = (*i).second.volumeID;
       G4LogicalVolume* lvol = path[0]->GetLogicalVolume();
       if( lvol->GetSensitiveDetector() ) {
@@ -361,3 +369,4 @@ void Geant4VolumeManager::volumeDescriptor(const G4VTouchable* touchable,
                                            VolIDDescriptor&    vol_desc)  const  {
   volumeDescriptor(placementPath(touchable), vol_desc);
 }
+