diff --git a/DDCore/include/DD4hep/Shapes.h b/DDCore/include/DD4hep/Shapes.h
index a41f17b645996fafb6dfb23bc2c50cf8f6a70578..daaa1c84454ed91289de416e715416b512f732ca 100644
--- a/DDCore/include/DD4hep/Shapes.h
+++ b/DDCore/include/DD4hep/Shapes.h
@@ -325,28 +325,28 @@ namespace dd4hep {
     /// Constructor to assign an object
     template <typename Q> Tube(const Handle<Q>& e) : Solid_type<Object>(e) {  }
     /// Constructor to create a new anonymous tube object with attribute initialization
-    Tube(double rmin, double rmax, double z)
-    {   make("", rmin, rmax, z, 0, 2*M_PI);               }
+    Tube(double rmin, double rmax, double dz)
+    {   make("", rmin, rmax, dz, 0, 2*M_PI);               }
     /// Constructor to create a new anonymous tube object with attribute initialization
-    Tube(double rmin, double rmax, double z, double deltaPhi)
-    {   make("", rmin, rmax, z, 0, deltaPhi);             }
+    Tube(double rmin, double rmax, double dz, double deltaPhi)
+    {   make("", rmin, rmax, dz, 0, deltaPhi);             }
     /// Constructor to create a new anonymous tube object with attribute initialization
-    Tube(double rmin, double rmax, double z, double startPhi, double deltaPhi)
-    {   make("", rmin, rmax, z, startPhi, deltaPhi);      }
+    Tube(double rmin, double rmax, double dz, double startPhi, double deltaPhi)
+    {   make("", rmin, rmax, dz, startPhi, deltaPhi);      }
     /// Legacy: Constructor to create a new identifiable tube object with attribute initialization
-    Tube(const std::string& nam, double rmin, double rmax, double z)
-    {   make(nam, rmin, rmax, z, 0, 2*M_PI);              }
+    Tube(const std::string& nam, double rmin, double rmax, double dz)
+    {   make(nam, rmin, rmax, dz, 0, 2*M_PI);              }
     /// Legacy: Constructor to create a new identifiable tube object with attribute initialization
-    Tube(const std::string& nam, double rmin, double rmax, double z, double deltaPhi)
-    {  make(nam, rmin, rmax, z, 0, deltaPhi);             }
+    Tube(const std::string& nam, double rmin, double rmax, double dz, double deltaPhi)
+    {  make(nam, rmin, rmax, dz, 0, deltaPhi);             }
     /// Constructor to create a new anonymous tube object with attribute initialization
     template <typename RMIN, typename RMAX, typename Z, typename DELTAPHI>
-    Tube(const RMIN& rmin, const RMAX& rmax, const Z& z, const DELTAPHI& deltaPhi)
-    {  make("", _toDouble(rmin), _toDouble(rmax), _toDouble(z), 0, _toDouble(deltaPhi));   }
+    Tube(const RMIN& rmin, const RMAX& rmax, const Z& dz, const DELTAPHI& deltaPhi)
+    {  make("", _toDouble(rmin), _toDouble(rmax), _toDouble(dz), 0, _toDouble(deltaPhi));   }
     /// Assignment operator
     Tube& operator=(const Tube& copy) = default;
     /// Set the tube dimensions
-    Tube& setDimensions(double rmin, double rmax, double z, double startPhi=0.0, double deltaPhi=2*M_PI);
+    Tube& setDimensions(double rmin, double rmax, double dz, double startPhi=0.0, double deltaPhi=2*M_PI);
   };
 
   /// Class describing a tube shape of a section of a cut tube segment
diff --git a/DDCore/include/DD4hep/Volumes.h b/DDCore/include/DD4hep/Volumes.h
index 9ffecd72199bc2bc90d1c81c1840bd8088402b26..f0bbe256ade3d91d8e14538b3e49e30548fabbd2 100644
--- a/DDCore/include/DD4hep/Volumes.h
+++ b/DDCore/include/DD4hep/Volumes.h
@@ -181,6 +181,10 @@ namespace dd4hep {
     Volume volume() const;
     /// Parent volume (envelope)
     Volume motherVol() const;
+    /// Access the full transformation matrix to the parent volume
+    const TGeoMatrix& matrix()  const;
+    /// Access the translation vector to the parent volume
+    Position position()  const;
     /// Access to the volume IDs
     const PlacedVolumeExtension::VolIDs& volIDs() const;
     /// String dump
diff --git a/DDCore/include/XML/VolumeBuilder.h b/DDCore/include/XML/VolumeBuilder.h
index 3e465cd68a7ff556781bc8294af8de7263de477d..28ee06671d2c28fe3faa30f9c39ec24892660ee4 100644
--- a/DDCore/include/XML/VolumeBuilder.h
+++ b/DDCore/include/XML/VolumeBuilder.h
@@ -152,6 +152,7 @@ namespace dd4hep {
         Materials             materials;
         Transformations       transformations;
         std::set<std::string> shape_veto, vol_veto;
+        bool                  debug = false;
 
         /// Inhibit default constructor
         VolumeBuilder() = delete;
@@ -177,6 +178,12 @@ namespace dd4hep {
         Solid getShape(const std::string& nam)  const;
         /// Create a new shape from the information given in the xml handle
         Solid makeShape(Handle_t handle);
+        /// Access a registered volume by name
+        Volume volume(const std::string& nam)  const;
+        /// Register shape to map
+        void registerShape(const std::string& nam, Solid shape);
+        /// Register volume to map
+        void registerVolume(const std::string& nam, Volume volume);
         /// Build all <shape/> identifiers in the passed parent xml element
         size_t buildShapes(Handle_t handle);
         /// Build all <volume/> identifiers in the passed parent xml element
diff --git a/DDCore/src/Volumes.cpp b/DDCore/src/Volumes.cpp
index 01af6b037882bb9d94556181ee70d80651e2b71b..039be1bf55b92312bf1ff0c4dbf25068aba95dab 100644
--- a/DDCore/src/Volumes.cpp
+++ b/DDCore/src/Volumes.cpp
@@ -442,11 +442,26 @@ const PlacedVolume::VolIDs& PlacedVolume::volIDs() const {
   return _data(*this)->volIDs;
 }
 
+/// Translation vector within parent volume
+const TGeoMatrix& PlacedVolume::matrix()  const    {
+  if ( !isValid() )  {
+    except("PlacedVolume","+++ matrix: Failed to access invalid PlacedVolume! [Invalid handle]");
+  }
+  return *(m_element->GetMatrix());  
+}
+
+/// Translation vector within parent volume
+Position PlacedVolume::position()  const    {
+  const double* ptr = matrix().GetTranslation();
+  return Position(ptr[0],ptr[1],ptr[2]);
+}
+
 /// String dump
 string PlacedVolume::toString() const {
   stringstream s;
   Object* obj = _data(*this);
-  s << m_element->GetName() << ":  vol='" << m_element->GetVolume()->GetName() << "' mat:'" << m_element->GetMatrix()->GetName()
+  s << m_element->GetName() << ":  vol='" << m_element->GetVolume()->GetName()
+    << "' mat:'" << m_element->GetMatrix()->GetName()
     << "' volID[" << obj->volIDs.size() << "] ";
   for (VolIDs::const_iterator i = obj->volIDs.begin(); i != obj->volIDs.end(); ++i)
     s << (*i).first << "=" << (*i).second << "  ";
diff --git a/DDCore/src/XML/VolumeBuilder.cpp b/DDCore/src/XML/VolumeBuilder.cpp
index 37d43138ef1c70868ff8e951bf70516ae4afa632..c2924347399e5ad2006ea134541764ed4162e863 100644
--- a/DDCore/src/XML/VolumeBuilder.cpp
+++ b/DDCore/src/XML/VolumeBuilder.cpp
@@ -53,6 +53,44 @@ size_t VolumeBuilder::collectMaterials(xml_h element)   {
   return materials.size()-len;
 }
 
+/// Register shape to map
+void VolumeBuilder::registerShape(const std::string& nam, Solid shape)   {
+  auto is = shapes.find(nam);
+  if ( is == shapes.end() )  {
+    shapes[nam] = make_pair(xml_h(0), shape);
+    return;
+  }
+  except("VolumeBuilder","+++ Shape %s is already known to this builder unit. ",nam.c_str());
+}
+
+/// Register volume to map
+void VolumeBuilder::registerVolume(const std::string& nam, Volume volume)   {
+  auto is = volumes.find(nam);
+  if ( is == volumes.end() )  {
+    volumes[nam] = make_pair(xml_h(0), volume);
+    return;
+  }
+  except("VolumeBuilder","+++ Volume %s is already known to this builder unit. ",nam.c_str());
+}
+
+/// Access a registered volume by name
+Volume VolumeBuilder::volume(const std::string& nam)  const    {
+  auto iv = volumes.find(nam);
+  if ( iv == volumes.end() )  {
+    auto ib = vol_veto.find(nam);
+    if ( ib != vol_veto.end() )  {
+      // Veto'ed shape. Ignore it.
+      return Volume();
+    }
+    except("VolumeBuilder","+++ Volume %s is not known to this builder unit. ",nam.c_str());
+  }
+  Volume vol = (*iv).second.second;
+  if ( !vol.isValid() )   {
+    except("VolumeBuilder","+++ Failed to access volume %s from the local cache.",nam.c_str());
+  }
+  return vol;
+}
+
 /// Access element from shape cache by name. Invalid returns means 'veto'. Otherwise exception
 Solid VolumeBuilder::getShape(const string& nam)  const   {
   auto is = shapes.find(nam);
@@ -190,7 +228,9 @@ size_t VolumeBuilder::buildVolumes(xml_h handle)    {
       if ( c.attr_nothrow(_U(sensitive)) )   {
         vol.setSensitiveDetector(sensitive);
       }
-      printout(ALWAYS,"VolumeBuilder","+++ Building volume %s",nam.c_str());
+      if ( debug )  {
+        printout(ALWAYS,"VolumeBuilder","+++ Building volume %s",nam.c_str());
+      }
       continue;
     }
     bool is_assembly = true;
diff --git a/DDCore/src/plugins/StandardPlugins.cpp b/DDCore/src/plugins/StandardPlugins.cpp
index a5c975a05cddf78e82248113ac728fbe3900f128..3ac559c1714f2cac9ea4a82ee5df05ee7f3fcbe3 100644
--- a/DDCore/src/plugins/StandardPlugins.cpp
+++ b/DDCore/src/plugins/StandardPlugins.cpp
@@ -1138,11 +1138,11 @@ template <int flag> long dump_detelement_tree(Detector& description, int argc, c
     string path;
     long count = 0;
     int have_match = -1, analysis_level = 999999;
-    bool dump_materials = false, dump_shapes = false;
+    bool dump_materials = false, dump_shapes = false, dump_positions = false;
     bool sensitive_only = false;
 
-    Actor(const string& p, int level, bool mat, bool shap, bool sens)
-      : path(p), analysis_level(level), dump_materials(mat), dump_shapes(shap), sensitive_only(sens) {}
+    Actor(const string& p, int level, bool mat, bool shap, bool pos, bool sens)
+      : path(p), analysis_level(level), dump_materials(mat), dump_shapes(shap), dump_positions(pos), sensitive_only(sens) {}
     ~Actor() {
       printout(ALWAYS,"DetectorDump", "+++ Scanned a total of %ld elements.",count);
     }
@@ -1199,6 +1199,14 @@ template <int flag> long dump_detelement_tree(Detector& description, int argc, c
             ::snprintf(fmt,sizeof(fmt), "%03d %%-%ds Material: %%-12s Shape: %%s", level+1,2*level+3);
             printout(INFO,"DetectorDump",fmt,"", mat.name(), toStringSolid(vol->GetShape()).c_str());
           }
+          if ( dump_positions && place.isValid() )  {
+            Position pos = place.position();
+            Box box = place.volume().solid();
+            ::snprintf(fmt,sizeof(fmt), "%03d %%-%ds BBox:     (%%9.4f,%%9.4f,%%9.4f) [cm]", level+1,2*level+3);
+            printout(INFO,"DetectorDump",fmt,"", box.x(), box.y(), box.z());
+            ::snprintf(fmt,sizeof(fmt), "%03d %%-%ds Position: (%%9.4f,%%9.4f,%%9.4f) [cm]", level+1,2*level+3);
+            printout(INFO,"DetectorDump",fmt,"", pos.X(), pos.Y(), pos.Z());
+          }
         }
       }
       for (DetElement::Children::const_iterator i = c.begin(); i != c.end(); ++i)
@@ -1207,7 +1215,7 @@ template <int flag> long dump_detelement_tree(Detector& description, int argc, c
     }
   };
   int  level = 999999;
-  bool sensitive_only = false, materials = false, shapes = false;
+  bool sensitive_only = false, materials = false, shapes = false, positions = false;
   string path;
   for(int i=0; i<argc; ++i)  {
     if      ( ::strncmp(argv[i],"--sensitive",     5)==0 ) { sensitive_only = true;    }
@@ -1217,6 +1225,8 @@ template <int flag> long dump_detelement_tree(Detector& description, int argc, c
     else if ( ::strncmp(argv[i], "--materials",    5)==0 ) { materials = true;         }
     else if ( ::strncmp(argv[i], "-shapes",        4)==0 ) { shapes = true;            }
     else if ( ::strncmp(argv[i], "--shapes",       5)==0 ) { shapes = true;            }
+    else if ( ::strncmp(argv[i], "-positions",     4)==0 ) { positions = true;         }
+    else if ( ::strncmp(argv[i], "--positions",    5)==0 ) { positions = true;         }
     else if ( ::strncmp(argv[i], "-no-sensitive",  7)==0 ) { sensitive_only = false;   }
     else if ( ::strncmp(argv[i], "--detector",     5)==0 ) { path = argv[++i];         }
     else if ( ::strncmp(argv[i], "-detector",      5)==0 ) { path = argv[++i];         }
@@ -1229,6 +1239,8 @@ template <int flag> long dump_detelement_tree(Detector& description, int argc, c
         "    -sensitive             dto.                                                           \n"
         "    --shapes               Print shape information.                                       \n"
         "    -shapes                dto.                                                           \n"
+        "    --positions            Print position information.                                    \n"
+        "    -positions             dto.                                                           \n"
         "    --materials            Print material information.                                    \n"
         "    -materials             dto.                                                           \n"
         "    --detector   <path>    Process elements only if <path> is part of the DetElement path.\n"
@@ -1237,7 +1249,7 @@ template <int flag> long dump_detelement_tree(Detector& description, int argc, c
       ::exit(EINVAL);
     }
   }
-  Actor a(path, level, materials, shapes, sensitive_only);
+  Actor a(path, level, materials, shapes, positions, sensitive_only);
   return a.dump(description.world(),0);
 }
 DECLARE_APPLY(DD4hep_DetectorDump,dump_detelement_tree<0>)