diff --git a/DDCore/include/DD4hep/Factories.h b/DDCore/include/DD4hep/Factories.h
index 12c6ae6b98d74975370ed9e7df097761c7697d6c..92116429056e921cef0134dd5535ae69bc08abed 100644
--- a/DDCore/include/DD4hep/Factories.h
+++ b/DDCore/include/DD4hep/Factories.h
@@ -284,7 +284,12 @@ namespace {
 
 // Call function of the type [void* (*func)(dd4hep::Detector& description, xml_h handle)]
 #define DECLARE_XML_SHAPE(name,func)  DD4HEP_OPEN_PLUGIN(dd4hep,xml_element_##name)  {\
-    template <> Handle<TObject> XMLObjectFactory<xml_element_##name>::create(dd4hep::Detector& l,ns::xml_h e) {return func(l,e);} \
+    template <> Handle<TObject> XMLObjectFactory<xml_element_##name>::create(dd4hep::Detector& l,ns::xml_h e) {return func(l,e);}\
+    DD4HEP_PLUGINSVC_FACTORY(xml_element_##name,name,TObject*(dd4hep::Detector*,ns::xml_h*),__LINE__)  }
+
+// Call function of the type [void* (*func)(dd4hep::Detector& description, xml_h handle)]
+#define DECLARE_XML_VOLUME(name,func)  DD4HEP_OPEN_PLUGIN(dd4hep,xml_element_##name)  {\
+    template <> Handle<TObject> XMLObjectFactory<xml_element_##name>::create(dd4hep::Detector& l,ns::xml_h e) {return func(l,e);}\
     DD4HEP_PLUGINSVC_FACTORY(xml_element_##name,name,TObject*(dd4hep::Detector*,ns::xml_h*),__LINE__)  }
 
 // Call function of the type [long (*func)(dd4hep::Detector& description, xml_h handle)]
diff --git a/DDCore/include/DD4hep/Objects.h b/DDCore/include/DD4hep/Objects.h
index 3b8e8ebbcffc5ff96b843348a6ba97046db38aac..3f80f71ee26c61bc33d348a1b7c49123a906cb6e 100644
--- a/DDCore/include/DD4hep/Objects.h
+++ b/DDCore/include/DD4hep/Objects.h
@@ -71,9 +71,12 @@ namespace dd4hep {
   class RegionObject;
   class LimitSetObject;
 
-  typedef ROOT::Math::XYZVector Position;
-  typedef ROOT::Math::XYZVector Direction;
-  typedef ROOT::Math::XYZVector XYZAngles;
+  typedef ROOT::Math::RhoZPhiVector PositionRhoZPhi;
+  typedef ROOT::Math::Polar3DVector PositionPolar;
+  typedef ROOT::Math::XYZVector     Position;
+  typedef ROOT::Math::XYZVector     Position;
+  typedef ROOT::Math::XYZVector     Direction;
+  typedef ROOT::Math::XYZVector     XYZAngles;
   
   template <class V> V RotateX(const V& v, double a) {
     return ROOT::Math::VectorUtil::RotateX(v, a);
diff --git a/DDCore/include/XML/UnicodeValues.h b/DDCore/include/XML/UnicodeValues.h
index 91e02862d8209235630cf2311376f06b2f62e45a..b6affce1eb9eb3d1544a6e85869804b68f0b7aec 100644
--- a/DDCore/include/XML/UnicodeValues.h
+++ b/DDCore/include/XML/UnicodeValues.h
@@ -321,6 +321,7 @@ UNICODE (parallelworld_volume);
 UNICODE (param);
 UNICODE (parameter);
 UNICODE (parameters);
+UNICODE (paramphysvol);
 UNICODE (params);
 UNICODE (parent);
 UNICODE (particles);
diff --git a/DDCore/include/XML/Utilities.h b/DDCore/include/XML/Utilities.h
index 8d92a4089d6001028173c95f5505c1559d9e1342..cc68e2c88a7388bc4c79256363ee9b4330a35a6c 100644
--- a/DDCore/include/XML/Utilities.h
+++ b/DDCore/include/XML/Utilities.h
@@ -50,8 +50,11 @@ namespace dd4hep {
      */
     Transform3D createTransformation(xml::Element element);
 
+    /// Create a simple volume using the shape plugin mechanism from the attributes of the XML element
+    Volume createStdVolume(Detector& description, xml::Element element);
+
     /// Create a volume using the plugin mechanism from the attributes of the XML element
-    Volume createVolume(Detector& description, xml::Element element);
+    Volume createVolume(Detector& description, const std::string& type, xml::Element element);
 
 
     /// Create a solid shape using the plugin mechanism from the attributes of the XML element
diff --git a/DDCore/include/XML/VolumeBuilder.h b/DDCore/include/XML/VolumeBuilder.h
index 63759cbd0b91e861230e971f264554fb915049c3..82a0a41d92ae1c96453e2f158345fd40332a1571 100644
--- a/DDCore/include/XML/VolumeBuilder.h
+++ b/DDCore/include/XML/VolumeBuilder.h
@@ -15,6 +15,7 @@
 
 // Framework include files
 #include "XML/XMLElements.h"
+#include "XML/XMLDetector.h"
 #include "DD4hep/Detector.h"
 
 // C/C++ include files
@@ -136,14 +137,15 @@ namespace dd4hep {
        *   \date    12/10/2018
        */
       class VolumeBuilder   {
-      public:
+      public:        
         typedef ::dd4hep::DetElement DetElement;
+        typedef ::dd4hep::xml::DetElement xml_det_h;
         typedef std::map<std::string,std::pair<Handle_t,Solid> >       Shapes;
         typedef std::map<std::string,std::pair<Handle_t,Volume> >      Volumes;
         typedef std::map<std::string,Material>                         Materials;
         typedef std::map<std::string,std::pair<Handle_t,Transform3D> > Transformations;
         Detector&             description;
-        Handle_t              x_det;
+        xml_det_h             x_det;
         int                   id = -1;
         std::string           name;
         DetElement            detector;
@@ -156,6 +158,13 @@ namespace dd4hep {
         std::set<std::string> shape_veto, vol_veto;
         bool                  debug = false;
 
+      protected:
+        /// Place single volumes
+        void _placeSingleVolume(DetElement de, Volume vol, Handle_t c);
+        /// Place parametrized volumes
+        void _placeParamVolumes(DetElement de, Volume vol, Handle_t c);
+
+      public:
         /// Inhibit default constructor
         VolumeBuilder() = delete;
         /// Inhibit move constructor
diff --git a/DDCore/src/XML/Utilities.cpp b/DDCore/src/XML/Utilities.cpp
index 37a39ac10dbf1acf335c24a9a23a1c2cca03f9af..fe52c62a1981edd5787263bb0aee26d5f4bd1a69 100644
--- a/DDCore/src/XML/Utilities.cpp
+++ b/DDCore/src/XML/Utilities.cpp
@@ -37,7 +37,7 @@ Transform3D dd4hep::xml::createTransformation(xml::Element e)   {
     if ( tag == "positionRPhiZ" )   {
       if      ( flag == 1 ) result = position  * result;
       else if ( flag == 2 ) result = (position * rotation) * result;
-      ROOT::Math::RhoZPhiVector pos(x_elt.r(0), x_elt.z(0), x_elt.phi(0));
+      PositionRhoZPhi pos(x_elt.r(0), x_elt.z(0), x_elt.phi(0));
       position = Transform3D(pos);
       rotation = Transform3D();
       flag = 1;
@@ -78,7 +78,7 @@ Solid dd4hep::xml::createShape(Detector& description,
   Solid solid = Solid(PluginService::Create<TObject*>(fac, &description, &solid_elt));
   if ( !solid.isValid() )  {
     PluginDebug dbg;
-    PluginService::Create<TObject*>(shape_type, &description, &solid_elt);
+    PluginService::Create<TObject*>(fac, &description, &solid_elt);
     except("xml::createShape","Failed to create solid of type %s [%s]", 
            shape_type.c_str(),dbg.missingFactory(shape_type).c_str());
   }
@@ -86,7 +86,7 @@ Solid dd4hep::xml::createShape(Detector& description,
 }
 
 /// Create a volume using the plugin mechanism from the attributes of the XML element
-Volume dd4hep::xml::createVolume(Detector& description, xml::Element element)    {
+Volume dd4hep::xml::createStdVolume(Detector& description, xml::Element element)    {
   xml_dim_t e(element);
   if ( e.hasAttr(_U(material)) )   {
     xml_dim_t x_s = e.child(_U(shape));
@@ -113,6 +113,30 @@ Volume dd4hep::xml::createVolume(Detector& description, xml::Element element)
   return Volume();
 }
 
+/// Create a volume using the plugin mechanism from the attributes of the XML element
+Volume dd4hep::xml::createVolume(Detector& description,
+                                 const std::string& typ,
+                                 xml::Element element)   {
+  if ( !typ.empty() )   {
+    xml_dim_t e(element);
+    string fac = typ + "__volume_constructor";
+    xml::Handle_t elt = element;
+    TObject* obj = PluginService::Create<TObject*>(fac, &description, &elt);
+    Volume vol = Volume(dynamic_cast<TGeoVolume*>(obj));
+    if ( !vol.isValid() )  {
+      PluginDebug dbg;
+      PluginService::Create<TObject*>(fac, &description, &elt);
+      except("xml::createShape","Failed to create volume of type %s [%s]", 
+             typ.c_str(),dbg.missingFactory(typ).c_str());
+    }
+    if ( e.hasAttr(_U(name)) ) vol->SetName(e.attr<string>(_U(name)).c_str());
+    vol.setAttributes(description,e.regionStr(),e.limitsStr(),e.visStr());
+    return vol;
+  }
+  except("xml::createVolume","Failed to create volume. No materiaWNo type specified!");
+  return Volume();
+}
+
 Volume dd4hep::xml::createPlacedEnvelope( dd4hep::Detector& description,
                                           dd4hep::xml::Handle_t e, 
                                           dd4hep::DetElement sdet)
diff --git a/DDCore/src/XML/VolumeBuilder.cpp b/DDCore/src/XML/VolumeBuilder.cpp
index f7f354111f5b9211ed4cc7de94df5136cb6d95b0..3169d1860b90f103d5db9a33dbfd95fdcca13b42 100644
--- a/DDCore/src/XML/VolumeBuilder.cpp
+++ b/DDCore/src/XML/VolumeBuilder.cpp
@@ -33,12 +33,12 @@ VolumeBuilder::VolumeBuilder(Detector& dsc, xml_h x_parent, SensitiveDetector sd
   : description(dsc), x_det(x_parent), sensitive(sd)
 {
   if ( x_det )   {
-    xml_det_t c(x_det);
-    name     = c.nameStr();
-    id       = c.id();
+    name     = x_det.nameStr();
+    id       = x_det.id();
     detector = DetElement(name, id);
   }
   buildType = description.buildType();
+  debug = true;
 }
 
 /// Collect a set of materials from the leafs of an xml tag
@@ -153,6 +153,8 @@ Solid VolumeBuilder::makeShape(xml_h handle)   {
     solid.setName(nam);
     shapes.insert(make_pair(nam,make_pair(handle,solid)));
   }
+  printout(debug ? ALWAYS : INFO, "VolumeBuilder",
+           "+++ Created shape of type: %s name: %s",type.c_str(), nam.c_str());
   return solid;
 }
 
@@ -211,6 +213,23 @@ size_t VolumeBuilder::buildVolumes(xml_h handle)    {
         continue;
       }
     }
+    /// Check if the volume is implemented by a factory
+    if ( (attr=c.attr_nothrow(_U(type))) )   {
+      string typ = c.attr<string>(attr);
+      Volume vol = xml::createVolume(description, typ, c);
+      vol.setAttributes(description,x.regionStr(),x.limitsStr(),x.visStr());
+      volumes.insert(make_pair(nam,make_pair(c,vol)));
+      /// Check if the volume is sensitive
+      if ( c.attr_nothrow(_U(sensitive)) )   {
+        vol.setSensitiveDetector(sensitive);
+      }
+      if ( debug )  {
+        printout(ALWAYS,"VolumeBuilder","+++ Building volume from XML: %s",nam.c_str());
+      }
+      buildVolumes(c);
+      continue;
+    }
+    
     /// Check if the volume has a shape attribute --> shape reference
     if ( (attr=c.attr_nothrow(_U(shape))) )   {
       string ref = c.attr<string>(attr);
@@ -249,107 +268,165 @@ size_t VolumeBuilder::buildVolumes(xml_h handle)    {
       buildVolumes(c);
       continue;
     }
-    except("VolumeBuilder","+++ Failed to create volume %s. "
+    except("VolumeBuilder","+++ Failed to create volume %s - "
            "It is neither Volume nor assembly....", nam.c_str());
   }
   return volumes.size()-len;
 }
 
-/// Build all <physvol/> identifiers as PlaceVolume daughters. Ignores structure
-VolumeBuilder& VolumeBuilder::placeDaughters(Volume vol, xml_h handle)   {
-  for( xml_coll_t c(handle,_U(physvol)); c; ++c )   {
-    xml_attr_t attr = c.attr_nothrow(_U(logvol));
-    if ( !attr )   {
-      attr = c.attr_nothrow(_U(volume));
-    }
-    if ( !attr )   {
-      except("VolumeBuilder","+++ The xml volume element has no 'logvol' or 'volume' attribute!");
+/// Place single volumes
+void VolumeBuilder::_placeSingleVolume(DetElement parent, Volume vol, xml_h c)   {
+  xml_attr_t attr = c.attr_nothrow(_U(logvol));
+  if ( !attr )   {
+    attr = c.attr_nothrow(_U(volume));
+  }
+  if ( !attr )   {
+    except("VolumeBuilder","+++ The xml volume element has no 'logvol' or 'volume' attribute!");
+  }
+  string nam = c.attr<string>(attr);
+  if ( vol_veto.find(nam) != vol_veto.end() )   {
+    return;
+  }
+  auto iv = volumes.find(nam);
+  if ( iv == volumes.end() )  {
+    except("VolumeBuilder",
+           "+++ Failed to locate volume %s [typo somewhere in the XML?]",
+           nam.c_str());      
+  }
+  PlacedVolume pv;
+  Volume daughter = (*iv).second.second;
+  attr = c.attr_nothrow(_U(transformation));
+  if ( attr )   {
+    string tr_nam = c.attr<string>(attr);
+    auto it = transformations.find(tr_nam);
+    if ( it == transformations.end() )   {
+      except("VolumeBuilder",
+             "+++ Failed to locate name transformation %s "
+             "[typo somewhere in the XML?]",
+             nam.c_str());      
     }
-    string nam = c.attr<string>(attr);
-    if ( vol_veto.find(nam) == vol_veto.end() )   {
-      auto iv = volumes.find(nam);
-      if ( iv == volumes.end() )  {
-        except("VolumeBuilder","+++ Failed to locate volume %s. [typo somewhere in the XML?]",
-               nam.c_str());      
-      }
-      attr = c.attr_nothrow(_U(transformation));
-      if ( attr )   {
-        string tr_nam = c.attr<string>(attr);
-        auto it = transformations.find(tr_nam);
-        if ( it == transformations.end() )   {
-          except("VolumeBuilder",
-                 "+++ Failed to locate name transformation %s. "
-                 "[typo somewhere in the XML?]",
-                 nam.c_str());      
-        }
-        const Transform3D& tr = (*it).second.second;
-        vol.placeVolume((*iv).second.second, tr);
-        placeDaughters(vol, c);
-      }
-      else   {
-        Transform3D tr = xml::createTransformation(c);
-        vol.placeVolume((*iv).second.second, tr);
-        placeDaughters(vol, c);
-      }
+    const Transform3D& tr = (*it).second.second;
+    pv = vol.placeVolume(daughter, tr);
+  }
+  else  {
+    Transform3D tr = xml::createTransformation(c);
+    pv = vol.placeVolume(daughter, tr);
+  }
+  xml_attr_t attr_nam = c.attr_nothrow(_U(name));
+  if ( attr_nam )  {
+    string phys_nam = c.attr<string>(attr_nam);
+    pv->SetName(phys_nam.c_str());
+  }
+  attr = c.attr_nothrow(_U(element));
+  if ( attr && !parent.isValid() )  {
+    except("VolumeBuilder",
+           "+++ Failed to set DetElement placement for volume %s [Invalid parent]",
+           nam.c_str());      
+  }
+  else if ( attr )  {
+    int parent_id = parent.id();
+    string elt = c.attr<string>(attr);
+    attr = c.attr_nothrow(_U(id));
+    if ( attr )   {
+      id = c.attr<int>(attr);
+      elt += c.attr<string>(attr);
     }
+    DetElement de(parent,elt,parent_id);
+    de.setPlacement(pv);
+    placeDaughters(de, daughter, c);
+  }
+  else  {
+    placeDaughters(parent, daughter, c);
   }
-  return *this;
 }
 
-/// Build all <physvol/> identifiers as PlaceVolume daughters. Also handles structure
-VolumeBuilder& VolumeBuilder::placeDaughters(DetElement parent, Volume vol, xml_h handle)
-{
-  for( xml_coll_t c(handle,_U(physvol)); c; ++c )   {
-    xml_attr_t attr = c.attr_nothrow(_U(logvol));
-    if ( !attr )   {
-      attr = c.attr_nothrow(_U(volume));
+/// Place parametrized volumes
+void VolumeBuilder::_placeParamVolumes(DetElement parent, Volume vol, xml_h c)   {
+  xml_attr_t attr_tr, attr_elt, attr_nam;
+  xml_h      x_phys = c.child(_U(physvol));
+  xml_attr_t attr = x_phys.attr_nothrow(_U(logvol));
+  if ( !attr )   {
+    attr = x_phys.attr_nothrow(_U(volume));
+  }
+  if ( !attr )   {
+    except("VolumeBuilder","+++ The xml volume element has no 'logvol' or 'volume' attribute!");
+  }
+  string nam = x_phys.attr<string>(attr);
+  if ( vol_veto.find(nam) != vol_veto.end() )   {
+    return;
+  }
+  auto iv = volumes.find(nam);
+  if ( iv == volumes.end() )  {
+    except("VolumeBuilder",
+           "+++ Failed to locate volume %s [typo somewhere in the XML?]",
+           nam.c_str());      
+  }
+  attr_elt = c.attr_nothrow(_U(element));
+  if ( attr_elt && !parent.isValid() )  {
+    except("VolumeBuilder",
+           "+++ Failed to set DetElement placement for volume %s [Invalid parent]",
+           nam.c_str());      
+  }
+  Volume daughter = (*iv).second.second;
+  attr_tr = c.attr_nothrow(_U(transformation));
+  Transform3D tr;
+  if ( attr_tr )   {
+    string tr_nam = c.attr<string>(attr_tr);
+    auto it = transformations.find(tr_nam);
+    if ( it == transformations.end() )   {
+      except("VolumeBuilder",
+             "+++ Failed to locate name transformation %s "
+             "[typo somewhere in the XML?]",
+             nam.c_str());      
     }
-    if ( !attr )   {
-      except("VolumeBuilder","+++ The xml volume element has no 'logvol' or 'volume' attribute!");
+    tr = (*it).second.second;
+  }
+  else  {
+    tr = xml::createTransformation(c);
+  }
+  Transform3D transformation(Position(0,0,0));
+  int parent_id = -1;
+  string elt, phys_nam;
+  attr_nam = x_phys.attr_nothrow(_U(name));
+  if ( attr_nam )  {
+    phys_nam = x_phys.attr<string>(_U(name))+"_%d";
+  }
+  if ( attr_elt )  {
+    parent_id = parent.id();
+    elt = c.attr<string>(attr_elt);
+  }
+  int number = c.attr<int>(_U(number));
+  printout(debug ? ALWAYS : DEBUG,"VolumeBuilder","+++ Mother:%s place volume %s  %d times.",
+           vol.name(), daughter.name(), number);
+  for(int i=0; i<number; ++i)    {
+    PlacedVolume pv = vol.placeVolume(daughter, transformation);
+    if ( attr_nam )  {
+      //pv->SetName(_toString(i,phys_nam.c_str()).c_str());
     }
-    string nam = c.attr<string>(attr);
-    if ( vol_veto.find(nam) == vol_veto.end() )   {
-      auto iv = volumes.find(nam);
-      if ( iv == volumes.end() )  {
-        except("VolumeBuilder",
-               "+++ Failed to locate volume %s. [typo somewhere in the XML?]",
-               nam.c_str());      
-      }
-      PlacedVolume pv;
-      attr = c.attr_nothrow(_U(transformation));
-      if ( attr )   {
-        string tr_nam = c.attr<string>(attr);
-        auto it = transformations.find(tr_nam);
-        if ( it == transformations.end() )   {
-          except("VolumeBuilder",
-                 "+++ Failed to locate name transformation %s. "
-                 "[typo somewhere in the XML?]",
-                 nam.c_str());      
-        }
-        const Transform3D& tr = (*it).second.second;
-        pv = vol.placeVolume((*iv).second.second, tr);
-      }
-      else  {
-        Transform3D tr = xml::createTransformation(c);
-        pv = vol.placeVolume((*iv).second.second, tr);
-      }
-      if ( (attr=c.attr_nothrow(_U(element))) )  {
-        int parent_id = parent.id();
-        string elt = c.attr<string>(attr);
-        attr = c.attr_nothrow(_U(id));
-        if ( attr )   {
-          id = c.attr<int>(attr);
-          elt += c.attr<string>(attr);
-        }
-        DetElement de(parent,elt,parent_id);
-        de.setPlacement(pv);
-        placeDaughters(de, vol, c);
-      }
-      else  {
-        placeDaughters(parent, vol, c);
-      }
+    if ( attr_elt )  {
+      DetElement de(parent,elt,parent_id);
+      de.setPlacement(pv);
+      //placeDaughters(de, daughter, c);
     }
+    else  {
+      //placeDaughters(parent, daughter, c);
+    }
+    transformation *= tr;
   }
+}
+
+/// Build all <physvol/> identifiers as PlaceVolume daughters. Ignores structure
+VolumeBuilder& VolumeBuilder::placeDaughters(Volume vol, xml_h handle)   {
+  DetElement null_de;
+  return placeDaughters(null_de, vol, handle);
+}
+
+/// Build all <physvol/> identifiers as PlaceVolume daughters. Also handles structure
+VolumeBuilder& VolumeBuilder::placeDaughters(DetElement parent, Volume vol, xml_h handle)   {
+  for( xml_coll_t c(handle,_U(physvol)); c; ++c )
+    _placeSingleVolume(parent, vol, c);
+  for( xml_coll_t c(handle,_U(paramphysvol)); c; ++c )
+    _placeParamVolumes(parent, vol, c);
   return *this;
 }
 
diff --git a/DDDetectors/src/VolumeAssembly_geo.cpp b/DDDetectors/src/VolumeAssembly_geo.cpp
index e430d7a79141dad43878436db46ca53c867763ac..f50f99625213dc1bb165c5565ec06352450429c4 100644
--- a/DDDetectors/src/VolumeAssembly_geo.cpp
+++ b/DDDetectors/src/VolumeAssembly_geo.cpp
@@ -34,22 +34,23 @@ static Ref_t create_element(Detector& description, xml_h e, SensitiveDetector se
   Volume      assembly;
   xml::tools::VolumeBuilder builder(description, e, sens);
 
-  builder.debug = x_dbg != 0;
-  builder.buildShapes(x_det);
-  builder.buildShapes(x_env);
-  builder.buildVolumes(x_det);
-  builder.buildVolumes(x_env);
+  builder.debug = x_dbg != 0 || true;
 
   // Need to keep these alive as long as the volumebuilder lives
-  map<string, xml::DocumentHolder*> docs;
+  map<string, unique_ptr<xml::DocumentHolder> > docs;
   for( xml_coll_t c(x_det,_U(include)); c; ++c )   {
     string ref = c.attr<string>(_U(ref));
-    docs[ref]  = new xml::DocumentHolder(xml::DocumentHandler().load(e, c.attr_value(_U(ref))));
+    docs[ref]  = unique_ptr<xml::DocumentHolder>(new xml::DocumentHolder(xml::DocumentHandler().load(e, c.attr_value(_U(ref)))));
     xml_h vols = docs[ref]->root();
+    printout(builder.debug ? ALWAYS : DEBUG, "VolumeAssembly","++ Processing xml document %s.",
+             docs[ref]->uri().c_str());
     builder.buildShapes(vols);
     builder.buildVolumes(vols);
   }
-  for(auto& d : docs) delete d.second;
+  builder.buildShapes(x_det);
+  builder.buildShapes(x_env);
+  builder.buildVolumes(x_det);
+  builder.buildVolumes(x_env);
   
   // Now we build the envelope
   if ( !x_shp ) x_shp = x_env;
@@ -67,6 +68,12 @@ static Ref_t create_element(Detector& description, xml_h e, SensitiveDetector se
   if ( x_env.hasAttr(_U(vis)) )  {
     assembly.setVisAttributes(description, x_env.visStr());
   }
+  if ( x_env.hasAttr(_U(region)) )  {
+    assembly.setRegion(description, x_env.regionStr());
+  }
+  if ( x_env.hasAttr(_U(limits)) )  {
+    assembly.setLimitSet(description, x_env.limitsStr());
+  }
   if ( x_det.hasAttr(_U(sensitive)) )  {
     sens.setType(x_det.attr<string>(_U(sensitive)));
   }
@@ -80,7 +87,8 @@ static Ref_t create_element(Detector& description, xml_h e, SensitiveDetector se
   x_tr  = x_env.child(_U(transformation),false);
   builder.placeDetector(assembly, (x_pos || x_rot || x_tr) ? x_env : x_det);
   printout(builder.debug ? ALWAYS : DEBUG, "VolumeBuilder",
-           "+++ Created subdetector instance %s",builder.name.c_str());
+           "+++ Created subdetector instance %s vis:",
+           builder.name.c_str(), x_det.visStr().c_str());
   return builder.detector;
 }
 DECLARE_DETELEMENT(DD4hep_VolumeAssembly,create_element)