From 041e92942aabbcbf74424672c92c6fbc80117c3a Mon Sep 17 00:00:00 2001
From: Markus Frank <markus.frank@cern.ch>
Date: Mon, 1 Dec 2014 12:38:59 +0000
Subject: [PATCH] Generic application of reconstruction plugins to SiD detector
 palette. See DDDetectors/doc/README.ExtensionPlugins for details.

---
 DDCore/include/DD4hep/SurfaceInstaller.h      |  70 ++--
 DDCore/src/SurfaceInstaller.cpp               |  18 +-
 DDDetectors/compact/SiD/SiD_Ecal.xml          |  13 +-
 DDDetectors/compact/SiD/SiD_EcalBarrel.xml    |  42 +--
 DDDetectors/compact/SiD/SiD_EcalEndcap.xml    |  28 +-
 DDDetectors/compact/SiD/SiD_Hcal.xml          |  10 +-
 DDDetectors/compact/SiD/SiD_HcalBarrel.xml    |  10 +-
 DDDetectors/compact/SiD/SiD_Muon.xml          |   8 +-
 DDDetectors/compact/SiD/SiD_MuonBarrel.xml    |  34 +-
 DDDetectors/doc/README.ExtensionPlugins       |  71 ++++
 DDDetectors/doc/README.SiD                    |   2 +-
 DDDetectors/src/EcalBarrel_geo.cpp            |  12 +-
 DDDetectors/src/LayeringExtensionPlugin.cpp   |  49 +++
 .../src/PolyhedraBarrelCalorimeter2_geo.cpp   | 314 +++++++++---------
 .../src/PolyhedraEndcapCalorimeter2_geo.cpp   |   8 +-
 DDDetectors/src/SiTrackerBarrel_surfaces.cpp  |   7 +-
 DDDetectors/src/SiTrackerEndcap_surfaces.cpp  |   8 +-
 .../src/SubdetectorExtensionPlugin.cpp        |  21 ++
 18 files changed, 449 insertions(+), 276 deletions(-)
 create mode 100644 DDDetectors/doc/README.ExtensionPlugins
 create mode 100644 DDDetectors/src/LayeringExtensionPlugin.cpp
 create mode 100644 DDDetectors/src/SubdetectorExtensionPlugin.cpp

diff --git a/DDCore/include/DD4hep/SurfaceInstaller.h b/DDCore/include/DD4hep/SurfaceInstaller.h
index b0af1ddcc..8ef49c749 100644
--- a/DDCore/include/DD4hep/SurfaceInstaller.h
+++ b/DDCore/include/DD4hep/SurfaceInstaller.h
@@ -61,7 +61,8 @@ namespace DD4hep  {
     DetElement    m_det;
     /// Map of surface instances keyed by the logical volume
     Surfaces      m_surfaces;
-
+    /// Flag to inhibit useless further scans
+    bool          m_stopScanning;
     /// Scan through tree of detector elements
     void scan(DetElement de);
 
@@ -70,8 +71,14 @@ namespace DD4hep  {
     SurfaceInstaller(LCDD& lcdd, const std::string& det_name);
     /// Default destructor
     virtual ~SurfaceInstaller() {}
+    /// Set flag to stop scanning volumes and detector elements
+    void stopScanning()   {  m_stopScanning = true;   }
     /// Indicate error message and throw exception
     void invalidInstaller(const std::string& msg) const;
+    /// Shortcut to access the parent detectorelement's volume
+    Volume parentVolume(DetElement component)  const;
+    /// Shortcut to access the translation vector of a given component
+    const double* placementTranslation(DetElement component)  const;
     /// Scan through tree of detector elements
     void scan();
     /// Install volume information. Default implementation only prints!
@@ -100,7 +107,7 @@ namespace DD4hep  {
 }   // End namespace DD4hep
 
 
-#ifdef DD4HEP_USE_SURFACEINSTALL_HELPER
+#if defined(DD4HEP_USE_SURFACEINSTALL_HELPER)
 
 #include "DDRec/Surface.h"
 #include "DDRec/DetectorData.h"
@@ -125,12 +132,13 @@ namespace {
    *  \version 1.0
    *  \ingroup DD4HEP
    */
-  class Installer : public DD4hep::SurfaceInstaller {
+  template <typename UserData> class Installer : public DD4hep::SurfaceInstaller {
   public:
     typedef DD4hep::DDRec::Vector3D     Vector3D;
     typedef DD4hep::DDRec::VolSurface   VolSurface;
     typedef DD4hep::DDRec::VolPlane     VolPlane;
     typedef DDSurfaces::SurfaceType     Type;
+    UserData data;
   public:
     /// Initializing constructor
     Installer(LCDD& lcdd, const std::string& nam) : DD4hep::SurfaceInstaller(lcdd, nam) {}
@@ -139,41 +147,43 @@ namespace {
     /// Install volume information. Default implementation only prints!
     virtual void install(DetElement component, PlacedVolume pv);
     /// Try to handle surface using the surface cache
-    bool handleUsingCache(DetElement comp, Volume vol)  const  {
-      Surfaces::const_iterator is = m_surfaces.find(vol.ptr());
-      if ( is != m_surfaces.end() )  {
-	VolSurface surf((*is).second);
-	DD4hep::DDRec::volSurfaceList(comp)->push_back(surf);
-	return true;
-      }
-      return false;
-    }
-    Volume parentVolume(DetElement component)  const  {
-      DetElement module = component.parent();
-      if ( module.isValid() )   {
-	return module.placement().volume();
-      }
-      return Volume();
-    }
-    const double* placementTranslation(DetElement component)  const  {
-      TGeoMatrix* mat = component.placement()->GetMatrix();
-      const double* trans = mat->GetTranslation();
-      return trans;
-    }
-    void addSurface(DetElement component, const DD4hep::DDRec::VolSurface& surf)   {
-      m_surfaces.insert(std::make_pair(surf.volume().ptr(),surf.ptr()));
-      DD4hep::DDRec::volSurfaceList(component)->push_back(surf);
-    }
+    bool handleUsingCache(DetElement comp, Volume vol)  const;
+    /// Add a new surface to the surface manager and the local cache
+    void addSurface(DetElement component, const DD4hep::DDRec::VolSurface& surf);
     template <typename T> bool checkShape(const T& shape) const   {
       if ( shape.isValid() ) return true;
       invalidInstaller("Shape is not of the required type:"+DD4hep::typeName(typeid(T)));
      return false;
     }
   };
+
+  /// Handle surface installation using cached surfaces.
+  template <typename UserData> 
+    bool Installer<UserData>::handleUsingCache(DetElement comp, Volume vol)  const  {
+    Surfaces::const_iterator is = m_surfaces.find(vol.ptr());
+    if ( is != m_surfaces.end() )  {
+      VolSurface surf((*is).second);
+      DD4hep::DDRec::volSurfaceList(comp)->push_back(surf);
+      return true;
+    }
+    return false;
+  }
+
+  /// Add a new surface to the surface manager and the local cache
+  template <typename UserData> 
+    void Installer<UserData>::addSurface(DetElement component, const DD4hep::DDRec::VolSurface& surf)   {
+    m_surfaces.insert(std::make_pair(surf.volume().ptr(),surf.ptr()));
+    DD4hep::DDRec::volSurfaceList(component)->push_back(surf);
+  }
+
 }
+#ifndef SURFACEINSTALLER_DATA
+typedef void* SURFACEINSTALLER_DATA;
+#endif
 
-DECLARE_SURFACE_INSTALLER(DD4HEP_USE_SURFACEINSTALL_HELPER,Installer)
+typedef Installer<SURFACEINSTALLER_DATA> InstallerClass;
+DECLARE_SURFACE_INSTALLER(DD4HEP_USE_SURFACEINSTALL_HELPER,InstallerClass)
 
-#endif /* DD4HEP_USE_SURFACEINSTALL_HELPER */
+#endif /* defined(DD4HEP_USE_SURFACEINSTALL_HELPER) */
 
 #endif /* DD4HEP_DDREC_SURFACEINSTALLER_H */
diff --git a/DDCore/src/SurfaceInstaller.cpp b/DDCore/src/SurfaceInstaller.cpp
index e94670f1a..29de01640 100644
--- a/DDCore/src/SurfaceInstaller.cpp
+++ b/DDCore/src/SurfaceInstaller.cpp
@@ -45,6 +45,22 @@ void SurfaceInstaller::invalidInstaller(const std::string& msg)   const  {
   throw std::runtime_error("+++ Failed to install Surfaces to detector "+string(det));
 }
 
+/// Shortcut to access the parent detectorelement's volume
+Volume SurfaceInstaller::parentVolume(DetElement component)  const  {
+  DetElement module = component.parent();
+  if ( module.isValid() )   {
+    return module.placement().volume();
+  }
+  return Volume();
+}
+
+/// Shortcut to access the translation vector of a given component
+const double* SurfaceInstaller::placementTranslation(DetElement component)  const  {
+  TGeoMatrix* mat = component.placement()->GetMatrix();
+  const double* trans = mat->GetTranslation();
+  return trans;
+}
+
 /// Printout volume information
 void SurfaceInstaller::install(DetElement component, PlacedVolume pv)   {
   if ( pv.volume().isSensitive() )  {
@@ -89,7 +105,7 @@ void SurfaceInstaller::install(DetElement component, PlacedVolume pv)   {
 void SurfaceInstaller::scan(DetElement e)  {
   const _C& children = e.children();  
   install(e,e.placement());
-  for (_C::const_iterator i=children.begin(); i!=children.end(); ++i)
+  for (_C::const_iterator i=children.begin(); !m_stopScanning && i!=children.end(); ++i)
     scan((*i).second);
 }
 
diff --git a/DDDetectors/compact/SiD/SiD_Ecal.xml b/DDDetectors/compact/SiD/SiD_Ecal.xml
index 681be63d6..95bebae6f 100644
--- a/DDDetectors/compact/SiD/SiD_Ecal.xml
+++ b/DDDetectors/compact/SiD/SiD_Ecal.xml
@@ -24,10 +24,14 @@
 
   <!--  Definition of the used visualization attributes    -->
   <display>
-    <vis name="EcalBarrelVis"       alpha="1.0" r="0" g="0" b="0.3" showDaughters="true" visible="true"/>
-    <vis name="EcalBarrelStaveVis"  alpha="1.0" r="1" g="0.9" b="0.5" showDaughters="false" visible="true"/>
+    <vis name="EcalBarrelVis"       alpha="1.0" r="1.0"  g="1.0"  b="0.0"  showDaughters="true" visible="false"/>
+    <vis name="EcalStaveVis"        alpha="1.0" r="0.0"  g="0.0"  b="1.0"  showDaughters="true" visible="true"/>
+    <vis name="EcalLayerVis"        alpha="1.0" r="0.8"  g="0.8"  b="0.0"  showDaughters="true" visible="true"/>
 
-    <vis name="EcalEndcapVis"       alpha="1" r="0.77" g="0.74" b="0.86" showDaughters="false" visible="true"/>
+    <vis name="EcalSensitiveVis"    alpha="1.0" r="0.7"  g="0.3"  b="0.0"  showDaughters="false" visible="true"/>
+    <vis name="EcalAbsorberVis"     alpha="1.0" r="0.4"  g="0.4"  b="0.0"  showDaughters="false" visible="true"/>
+
+    <vis name="EcalEndcapVis"       alpha="1.0" r="0.77" g="0.74" b="0.86" showDaughters="false" visible="true"/>
   </display>
 
   <!--  Definition of the readout segmentation/definition  -->
@@ -45,5 +49,6 @@
   <!--  Includes for sensitives and support                -->
   <include ref="SiD_EcalBarrel.xml"/>
   <include ref="SiD_EcalEndcap.xml"/>
-
+<!--
+-->
 </lccdd>
diff --git a/DDDetectors/compact/SiD/SiD_EcalBarrel.xml b/DDDetectors/compact/SiD/SiD_EcalBarrel.xml
index e9aa6a737..1b0c54865 100644
--- a/DDDetectors/compact/SiD/SiD_EcalBarrel.xml
+++ b/DDDetectors/compact/SiD/SiD_EcalBarrel.xml
@@ -11,28 +11,28 @@
     <comment>Electromagnetic Calorimeter Barrel</comment>
 
     <dimensions numsides="(int) CaloSides" rmin="EcalBarrel_rmin" z="EcalBarrel_zmax*2" />
-    <staves vis="EcalBarrelStaveVis"/>
-    <layer repeat="1">
-      <slice material = "Silicon" thickness = "0.032*cm" sensitive = "yes" limits="cal_limits" />
-      <slice material = "Copper"  thickness = "0.005*cm" />
-      <slice material = "Kapton"  thickness = "0.030*cm" />
-      <slice material = "Air"     thickness = "0.033*cm" />
-    </layer>      
-    <layer repeat="20">
-      <slice material = "TungstenDens24" thickness = "0.25*cm" />
-      <slice material = "Air"     thickness = "0.025*cm" />
-      <slice material = "Silicon" thickness = "0.032*cm" sensitive = "yes" limits="cal_limits" />
-      <slice material = "Copper"  thickness = "0.005*cm" />
-      <slice material = "Kapton"  thickness = "0.030*cm" />
-      <slice material = "Air"     thickness = "0.033*cm" />
+    <staves vis="EcalStaveVis"/>
+    <layer repeat="1" vis="EcalLayerVis">
+      <slice material = "Silicon" thickness = "0.032*cm" sensitive="yes" limits="cal_limits" vis="EcalSensitiveVis"/>
+      <slice material = "Copper"  thickness = "0.005*cm" vis="EcalAbsorberVis"/>
+      <slice material = "Kapton"  thickness = "0.030*cm" vis="EcalAbsorberVis"/>
+      <slice material = "Air"     thickness = "0.033*cm" vis="InvisibleNoDaughters"/>
     </layer>
-    <layer repeat="10">
-      <slice material = "TungstenDens24" thickness = "0.5*cm" />
-      <slice material = "Air"     thickness = "0.025*cm" />
-      <slice material = "Silicon" thickness = "0.032*cm" sensitive = "yes" limits="cal_limits" />
-      <slice material = "Copper"  thickness = "0.005*cm" />
-      <slice material = "Kapton"  thickness = "0.030*cm" />
-      <slice material = "Air"     thickness = "0.033*cm" />
+    <layer repeat="20" vis="EcalLayerVis">
+      <slice material = "TungstenDens24" thickness = "0.25*cm" vis="EcalAbsorberVis"/>
+      <slice material = "Air"     thickness = "0.025*cm" vis="InvisibleNoDaughters"/>
+      <slice material = "Silicon" thickness = "0.032*cm" sensitive="yes" limits="cal_limits" vis="EcalSensitiveVis"/>
+      <slice material = "Copper"  thickness = "0.005*cm" vis="EcalAbsorberVis"/>
+      <slice material = "Kapton"  thickness = "0.030*cm" vis="EcalAbsorberVis"/>
+      <slice material = "Air"     thickness = "0.033*cm" vis="InvisibleNoDaughters"/>
+    </layer>
+    <layer repeat="10" vis="EcalLayerVis">
+      <slice material = "TungstenDens24" thickness = "0.5*cm" vis="EcalAbsorberVis"/>
+      <slice material = "Air"     thickness = "0.025*cm" vis="InvisibleNoDaughters"/>
+      <slice material = "Silicon" thickness = "0.032*cm" sensitive="yes" limits="cal_limits" vis="EcalSensitiveVis"/>
+      <slice material = "Copper"  thickness = "0.005*cm" vis="EcalAbsorberVis"/>
+      <slice material = "Kapton"  thickness = "0.030*cm" vis="EcalAbsorberVis"/>
+      <slice material = "Air"     thickness = "0.033*cm" vis="InvisibleNoDaughters"/>
     </layer>
   </detector>
 </detectors>
diff --git a/DDDetectors/compact/SiD/SiD_EcalEndcap.xml b/DDDetectors/compact/SiD/SiD_EcalEndcap.xml
index 12597ade0..910d35bd6 100644
--- a/DDDetectors/compact/SiD/SiD_EcalEndcap.xml
+++ b/DDDetectors/compact/SiD/SiD_EcalEndcap.xml
@@ -12,26 +12,26 @@
 
     <dimensions numsides="(int) CaloSides" zmin="EcalEndcap_zmin" rmin="EcalEndcap_rmin" rmax="EcalEndcap_rmax" />
     <layer repeat="1">
-      <slice material = "Silicon" thickness = "0.032*cm" sensitive = "yes" limits="cal_limits" />
-      <slice material = "Copper"  thickness = "0.005*cm" />
-      <slice material = "Kapton"  thickness = "0.030*cm" />
-      <slice material = "Air"     thickness = "0.033*cm" />
+      <slice material = "Silicon" thickness = "0.032*cm" sensitive="yes" limits="cal_limits" vis="EcalSensitiveVis"/>
+      <slice material = "Copper"  thickness = "0.005*cm" vis="EcalAbsorberVis"/>
+      <slice material = "Kapton"  thickness = "0.030*cm" vis="EcalAbsorberVis"/>
+      <slice material = "Air"     thickness = "0.033*cm" vis="InvisibleNoDaughters"/>
     </layer>       
     <layer repeat="20">
       <slice material = "TungstenDens24" thickness = "0.25*cm" />
-      <slice material = "Air"     thickness = "0.025*cm" />
-      <slice material = "Silicon" thickness = "0.032*cm" sensitive = "yes" limits="cal_limits" />
-      <slice material = "Copper"  thickness = "0.005*cm" />
-      <slice material = "Kapton"  thickness = "0.030*cm" />
-      <slice material = "Air"     thickness = "0.033*cm" />
+      <slice material = "Air"     thickness = "0.025*cm" vis="InvisibleNoDaughters"/>
+      <slice material = "Silicon" thickness = "0.032*cm" sensitive="yes" limits="cal_limits" vis="EcalSensitiveVis"/>
+      <slice material = "Copper"  thickness = "0.005*cm" vis="EcalAbsorberVis"/>
+      <slice material = "Kapton"  thickness = "0.030*cm" vis="EcalAbsorberVis"/>
+      <slice material = "Air"     thickness = "0.033*cm" vis="InvisibleNoDaughters"/>
     </layer>
     <layer repeat="10">
       <slice material = "TungstenDens24" thickness = "0.5*cm" />
-      <slice material = "Air"     thickness = "0.025*cm" />
-      <slice material = "Silicon" thickness = "0.032*cm" sensitive = "yes" limits="cal_limits" />
-      <slice material = "Copper"  thickness = "0.005*cm" />
-      <slice material = "Kapton"  thickness = "0.030*cm" />
-      <slice material = "Air"     thickness = "0.033*cm" />
+      <slice material = "Air"     thickness = "0.025*cm" vis="InvisibleNoDaughters"/>
+      <slice material = "Silicon" thickness = "0.032*cm" sensitive="yes" limits="cal_limits" vis="EcalSensitiveVis"/>
+      <slice material = "Copper"  thickness = "0.005*cm" vis="EcalAbsorberVis"/>
+      <slice material = "Kapton"  thickness = "0.030*cm" vis="EcalAbsorberVis"/>
+      <slice material = "Air"     thickness = "0.033*cm" vis="InvisibleNoDaughters"/>
     </layer>
   </detector>
 </detectors>
diff --git a/DDDetectors/compact/SiD/SiD_Hcal.xml b/DDDetectors/compact/SiD/SiD_Hcal.xml
index 2dee1d988..5846b5887 100644
--- a/DDDetectors/compact/SiD/SiD_Hcal.xml
+++ b/DDDetectors/compact/SiD/SiD_Hcal.xml
@@ -24,10 +24,11 @@
 
   <!--  Definition of the used visualization attributes    -->
   <display>
-    <vis name="HcalBarrelVis"          alpha="1" r="1"    g="1"    b="0.1" showDaughters="true" visible="true"/>
-    <vis name="HcalBarrelStavesVis"    alpha="1" r="1"    g="0"    b="0.3" showDaughters="true" visible="true"/>
-    <vis name="HcalBarrelLayerVis"     alpha="1" r="1"    g="0"    b="0.5" showDaughters="true" visible="true"/>
-    <vis name="HcalBarrelSensorVis"    alpha="1" r="1"    g="1"    b="0.7" showDaughters="true" visible="true"/>
+    <vis name="HcalBarrelVis"    alpha="1" r="0.0"  g="0.3"  b="0.8" showDaughters="true" visible="true"/>
+    <vis name="HcalStavesVis"    alpha="1" r="0.0"  g="0.0"  b="0.1" showDaughters="true" visible="false"/>
+    <vis name="HcalLayerVis"     alpha="1" r="0.0"  g="0.5"  b="1.0" showDaughters="true" visible="false"/>
+    <vis name="HcalSensorVis"    alpha="1" r="1.0"  g="0.0"  b="0.2" showDaughters="true" visible="true"/>
+    <vis name="HcalAbsorberVis"  alpha="1" r="0.4"  g="0.4"  b="0.6" showDaughters="true" visible="true"/>
 
     <vis name="HcalEndcapVis"          alpha="1" r="1"    g="1"    b="0.1" showDaughters="false" visible="true"/>
     <vis name="HcalEndcapLayerVis"     alpha="1" r="1"    g="0"    b="0.5" showDaughters="false" visible="true"/>
@@ -52,5 +53,4 @@
   <!--  Includes for sensitives and support                -->
   <include ref="SiD_HcalBarrel.xml"/>
   <include ref="SiD_HcalEndcap.xml"/>
-
 </lccdd>
diff --git a/DDDetectors/compact/SiD/SiD_HcalBarrel.xml b/DDDetectors/compact/SiD/SiD_HcalBarrel.xml
index f115bc44b..8dce6fc71 100644
--- a/DDDetectors/compact/SiD/SiD_HcalBarrel.xml
+++ b/DDDetectors/compact/SiD/SiD_HcalBarrel.xml
@@ -11,11 +11,11 @@
     <comment>Hadron Calorimeter Barrel</comment>
 
     <dimensions numsides="(int) CaloSides" rmin="HcalBarrel_rmin" z="EcalBarrel_zmax*2"/>
-    <staves vis="HcalBarrelStavesVis"/>
-    <layer repeat="(int) HcalBarrel_layers">
-      <slice material = "TungstenDens24" thickness = "1.00*cm" />
-      <slice material = "Polystyrene" thickness = "0.50*cm" sensitive = "yes" limits="cal_limits" vis="HcalBarrelSensorVis"/>       
-      <slice material = "Air" thickness = "0.15*cm" />
+    <staves vis="HcalStavesVis"/>
+    <layer repeat="(int)HcalBarrel_layers">
+      <slice material="TungstenDens24" thickness="1.00*cm" vis="HcalAbsorberVis"/>
+      <slice material="Polystyrene" thickness="0.50*cm" sensitive="yes" limits="cal_limits" vis="HcalSensorVis"/>
+      <slice material="Air" thickness="0.15*cm" vis="InvisibleNoDaughters"/>
     </layer>
   </detector>
 </detectors>
diff --git a/DDDetectors/compact/SiD/SiD_Muon.xml b/DDDetectors/compact/SiD/SiD_Muon.xml
index fca11e51b..896f2ef2b 100644
--- a/DDDetectors/compact/SiD/SiD_Muon.xml
+++ b/DDDetectors/compact/SiD/SiD_Muon.xml
@@ -25,10 +25,10 @@
   <!--  Definition of the used visualization attributes    -->
   <display>
     <vis name="MuonBarrelVis"          alpha="1" r="1"    g="0.4"  b="0.62" showDaughters="true" visible="true"/>
-    <vis name="MuonBarrelStavesVis"    alpha="1" r="0"    g="0.7"  b="0.3" showDaughters="true" visible="true"/>
-    <vis name="MuonBarrelLayerVis"     alpha="1" r="0"    g="1"    b="0.3" showDaughters="true" visible="true"/>
-    <vis name="MuonBarrelSensorVis"    alpha="1" r="0.54" g="0.4"  b="0.41" visible="true"/>
-    <vis name="MuonBarrelAbsorberVis"  alpha="1" r="0.28" g="0.4"  b="0.62" visible="true"/>        
+    <vis name="MuonStavesVis"    alpha="1" r="0"    g="0.7"  b="0.3" showDaughters="true" visible="true"/>
+    <vis name="MuonLayerVis"     alpha="1" r="0"    g="1"    b="0.3" showDaughters="true" visible="true"/>
+    <vis name="MuonSensorVis"    alpha="1" r="0.54" g="0.4"  b="0.41" visible="true"/>
+    <vis name="MuonAbsorberVis"  alpha="1" r="0.28" g="0.4"  b="0.62" visible="true"/>        
 
     <vis name="MuonEndcapVis"          alpha="1" r="1"    g="0.4"  b="0.62" showDaughters="true" visible="true"/>
     <vis name="MuonEndcapLayerVis"     alpha="1" r="0"    g="1"    b="0.3"  showDaughters="true" visible="true"/>
diff --git a/DDDetectors/compact/SiD/SiD_MuonBarrel.xml b/DDDetectors/compact/SiD/SiD_MuonBarrel.xml
index c12e86fdd..76e683e25 100644
--- a/DDDetectors/compact/SiD/SiD_MuonBarrel.xml
+++ b/DDDetectors/compact/SiD/SiD_MuonBarrel.xml
@@ -11,80 +11,80 @@
     <comment>Muon Calorimeter Barrel</comment>
 
     <dimensions numsides="(int) MuonSides" rmin="MuonBarrel_rmin" z="MuonBarrel_zmax * 2"/>
-    <staves vis="MuonBarrelStavesVis"/>
+    <staves vis="MuonStavesVis"/>
 
-    <layer repeat="1" vis="MuonBarrelLayerVis">
+    <layer repeat="1" vis="MuonLayerVis">
       <slice material="Aluminum" thickness="0.1*cm" />
       <slice material="Air" thickness="0.35*cm" />
       <slice material="PyrexGlass" thickness="0.2*cm" />
-      <slice material="RPCGasDefault" thickness="0.2*cm" sensitive="yes" vis="MuonBarrelSensorVis"/>
+      <slice material="RPCGasDefault" thickness="0.2*cm" sensitive="yes" vis="MuonSensorVis"/>
       <slice material="PyrexGlass" thickness="0.2*cm" />
       <slice material="Air" thickness="0.35*cm" />
       <slice material="Aluminum" thickness="0.1*cm" />
       <slice material="Aluminum" thickness="0.1*cm" />
       <slice material="Air" thickness="0.35*cm" />
       <slice material="PyrexGlass" thickness="0.2*cm" />
-      <slice material="RPCGasDefault" thickness="0.2*cm" sensitive="yes" vis="MuonBarrelSensorVis"/>
+      <slice material="RPCGasDefault" thickness="0.2*cm" sensitive="yes" vis="MuonSensorVis"/>
       <slice material="PyrexGlass" thickness="0.2*cm" />
       <slice material="Air" thickness="0.35*cm" />
       <slice material="Aluminum" thickness="0.1*cm" />
       <slice material="Air" thickness="1.0*cm" />
-      <slice material="Iron" thickness="5.0*cm" vis="MuonBarrelAbsorberVis"/>
+      <slice material="Iron" thickness="5.0*cm" vis="MuonAbsorberVis"/>
     </layer>
-    <layer repeat="1" vis="MuonBarrelLayerVis">
+    <layer repeat="1" vis="MuonLayerVis">
       <slice material="Aluminum" thickness="0.1*cm" />
       <slice material="Air" thickness="0.35*cm" />
       <slice material="PyrexGlass" thickness="0.2*cm" />
-      <slice material="RPCGasDefault" thickness="0.2*cm" sensitive="yes" vis="MuonBarrelSensorVis"/>
+      <slice material="RPCGasDefault" thickness="0.2*cm" sensitive="yes" vis="MuonSensorVis"/>
       <slice material="PyrexGlass" thickness="0.2*cm" />
       <slice material="Air" thickness="0.35*cm" />
       <slice material="Aluminum" thickness="0.1*cm" />
       <slice material="Aluminum" thickness="0.1*cm" />
       <slice material="Air" thickness="0.35*cm" />
       <slice material="PyrexGlass" thickness="0.2*cm" />
-      <slice material="RPCGasDefault" thickness="0.2*cm" sensitive="yes" vis="MuonBarrelSensorVis"/>
+      <slice material="RPCGasDefault" thickness="0.2*cm" sensitive="yes" vis="MuonSensorVis"/>
       <slice material="PyrexGlass" thickness="0.2*cm" />
       <slice material="Air" thickness="0.35*cm" />
       <slice material="Aluminum" thickness="0.1*cm" />
       <slice material="Air" thickness="1.0*cm" />
-      <slice material="Iron" thickness="20.0*cm" vis="MuonBarrelAbsorberVis"/>
+      <slice material="Iron" thickness="20.0*cm" vis="MuonAbsorberVis"/>
     </layer>
-    <layer repeat="(int) MuonBarrel_layers" vis="MuonBarrelLayerVis">
+    <layer repeat="(int) MuonBarrel_layers" vis="MuonLayerVis">
       <slice material="Aluminum" thickness="0.1*cm" />
       <slice material="Air" thickness="0.35*cm" />
       <slice material="PyrexGlass" thickness="0.2*cm" />
-      <slice material="RPCGasDefault" thickness="0.2*cm" sensitive="yes" vis="MuonBarrelSensorVis"/>
+      <slice material="RPCGasDefault" thickness="0.2*cm" sensitive="yes" vis="MuonSensorVis"/>
       <slice material="PyrexGlass" thickness="0.2*cm" />
       <slice material="Air" thickness="0.35*cm" />
       <slice material="Aluminum" thickness="0.1*cm" />
       <slice material="Aluminum" thickness="0.1*cm" />
       <slice material="Air" thickness="0.35*cm" />
       <slice material="PyrexGlass" thickness="0.2*cm" />
-      <slice material="RPCGasDefault" thickness="0.2*cm" sensitive="yes" vis="MuonBarrelSensorVis"/>
+      <slice material="RPCGasDefault" thickness="0.2*cm" sensitive="yes" vis="MuonSensorVis"/>
       <slice material="PyrexGlass" thickness="0.2*cm" />
       <slice material="Air" thickness="0.35*cm" />
       <slice material="Aluminum" thickness="0.1*cm" />
       <slice material="Air" thickness="1.0*cm" />
-      <slice material="Iron" thickness="10.0*cm" vis="MuonBarrelAbsorberVis"/>
+      <slice material="Iron" thickness="10.0*cm" vis="MuonAbsorberVis"/>
     </layer>
 
-    <layer repeat="1" vis="MuonBarrelLayerVis">
+    <layer repeat="1" vis="MuonLayerVis">
       <slice material="Aluminum" thickness="0.1*cm" />
       <slice material="Air" thickness="0.35*cm" />
       <slice material="PyrexGlass" thickness="0.2*cm" />
-      <slice material="RPCGasDefault" thickness="0.2*cm" sensitive="yes" vis="MuonBarrelSensorVis"/>
+      <slice material="RPCGasDefault" thickness="0.2*cm" sensitive="yes" vis="MuonSensorVis"/>
       <slice material="PyrexGlass" thickness="0.2*cm" />
       <slice material="Air" thickness="0.35*cm" />
       <slice material="Aluminum" thickness="0.1*cm" />
       <slice material="Aluminum" thickness="0.1*cm" />
       <slice material="Air" thickness="0.35*cm" />
       <slice material="PyrexGlass" thickness="0.2*cm" />
-      <slice material="RPCGasDefault" thickness="0.2*cm" sensitive="yes" vis="MuonBarrelSensorVis"/>
+      <slice material="RPCGasDefault" thickness="0.2*cm" sensitive="yes" vis="MuonSensorVis"/>
       <slice material="PyrexGlass" thickness="0.2*cm" />
       <slice material="Air" thickness="0.35*cm" />
       <slice material="Aluminum" thickness="0.1*cm" />
       <slice material="Air" thickness="1.0*cm" />
-      <slice material="Iron" thickness="20.0*cm" vis="MuonBarrelAbsorberVis"/>
+      <slice material="Iron" thickness="20.0*cm" vis="MuonAbsorberVis"/>
     </layer>
   </detector>
 </detectors>
diff --git a/DDDetectors/doc/README.ExtensionPlugins b/DDDetectors/doc/README.ExtensionPlugins
new file mode 100644
index 000000000..c35c76a83
--- /dev/null
+++ b/DDDetectors/doc/README.ExtensionPlugins
@@ -0,0 +1,71 @@
+
+Extension plugins for reconstruction
+====================================
+
+The need of the various reconstruction programs used to create e.g. tracks
+from hits may differ significantly and may require different helper data
+to perform the required functions.
+In general the reconstruction is supported by the detector elements with
+helper objects (in DD4hep speak these are called Views). Some default views 
+are provided by this package for some of the detector constructors of the 
+"default subdetector palette".
+We first show how to invoke these plugins in order to attach the required 
+extension object and then briefly discuss the plugin palette and it's 
+applicability to the various detector constructor types.
+
+Invokation of Extension Plugins
+===============================
+
+To add DetElement extensions simply add the corresponding plugin.
+This could be performed either by loading a seperate lccdd XML from the 
+command line/python interface or adding the corrsponding structures directly
+into the primary lccdd file:
+
+<lccdd ..../>
+  ....
+  <plugins>
+    <plugin name="....plugin name.....">
+      <argument value="......subdetector name......"/>
+      ....
+      <argument value="......another subdetector name......"/>
+    </plugin>
+    ....
+  </plugins>
+  ....
+</lccdd>
+
+
+
+Available plugins
+=================
+
+-- "SubdetectorExtensionPlugin"
+   argument: subdetector name as registered to LCDD
+   Adds an extension of type DD4hep::DDRec::SubdetectorExtension.
+   Please see documentation in DDRec for details.
+   In general applicable to any top level detector object.
+
+-- "LayeringExtensionPlugin"
+   argument: subdetector name as registered to LCDD
+   Adds an extension of the interface type DD4hep::DDRec::LayeringExtension
+   and the implementation type DD4hep::DDRec::LayeringExtensionImpl.
+   Please see documentation in DDRec for details.
+
+-- "DD4hep_SiTrackerBarrelSurfacePlugin"
+   argument: subdetector name as registered to LCDD
+   This plugin adds measurement surfaces of interface type DDSurfaces::ISurface
+   to each detector element which has a placement with a sensitive volume.
+
+   Applicable to all instances of type [list to be maintained!]:
+    - PolyhedraBarrelCalorimeter2  
+    - SiTrackerBarrel
+    - EcalBarrel
+
+-- "DD4hep_SiTrackerEndcapSurfacePlugin"
+   argument: subdetector name as registered to LCDD
+   This plugin adds measurement surfaces of interface type DDSurfaces::ISurface
+   to each detector element which has a placement with a sensitive volume.
+
+   Applicable to all instances of type [list to be maintained!]:
+    - SiTrackerEndcap2
+
diff --git a/DDDetectors/doc/README.SiD b/DDDetectors/doc/README.SiD
index 16d8cdf3e..92f205ac6 100644
--- a/DDDetectors/doc/README.SiD
+++ b/DDDetectors/doc/README.SiD
@@ -39,4 +39,4 @@ Shields and dead material:	DD4hep_PolyconeSupport
 
 Note:
 The palette drivers allow for many other designs. This explicit design is only an example
-how to use the palette.
\ No newline at end of file
+how to use the palette.
diff --git a/DDDetectors/src/EcalBarrel_geo.cpp b/DDDetectors/src/EcalBarrel_geo.cpp
index 8e55650c2..45b88d487 100644
--- a/DDDetectors/src/EcalBarrel_geo.cpp
+++ b/DDDetectors/src/EcalBarrel_geo.cpp
@@ -33,7 +33,7 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
   DetElement    sdet      (det_name,det_id);
   Volume        motherVol = lcdd.pickMotherVolume(sdet);
   PolyhedraRegular hedra  (nsides,inner_r,inner_r+totThick+tolerance*2e0,x_dim.z());
-  Volume        envelope  (det_name+"_envelope",hedra,air);
+  Volume        envelope  (det_name,hedra,air);
   PlacedVolume  env_phv   = motherVol.placeVolume(envelope,RotationZYX(0,0,M_PI/nsides));
 
   env_phv.addPhysVolID("system",det_id);
@@ -58,7 +58,7 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
 		trd_y2, //
 		trd_z); // Thickness, in Y for top stave, when rotated.
 
-  Volume mod_vol(det_name+"_module",trd,air);
+  Volume mod_vol("stave",trd,air);
 
   sens.setType("calorimeter");
   { // =====  buildBarrelStave(lcdd, sens, module_volume) =====
@@ -85,7 +85,7 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
 
 	Position   l_pos(0,0,l_pos_z+l_thickness/2);      // Position of the layer.
 	Box        l_box(l_dim_x*2-tolerance,stave_z*2-tolerance,l_thickness-tolerance);
-	Volume     l_vol(det_name+"_"+l_name,l_box,air);
+	Volume     l_vol(l_name,l_box,air);
 	DetElement layer(stave_det, l_name, det_id);
 
 	// Loop over the sublayers or slices for this layer.
@@ -93,10 +93,10 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
 	double s_pos_z = -(l_thickness / 2);
 	for(xml_coll_t si(x_layer,_U(slice)); si; ++si)  {
 	  xml_comp_t x_slice = si;
-	  string     s_name  =  _toString(s_num,"slice%d");
+	  string     s_name  = _toString(s_num,"slice%d");
 	  double     s_thick = x_slice.thickness();
 	  Box        s_box(l_dim_x*2-tolerance,stave_z*2-tolerance,s_thick-tolerance);
-	  Volume     s_vol(det_name+"_"+l_name+"_"+s_name,s_box,lcdd.material(x_slice.materialStr()));
+	  Volume     s_vol(s_name,s_box,lcdd.material(x_slice.materialStr()));
           DetElement slice(layer,s_name,det_id);
 
           if ( x_slice.isSensitive() ) {
@@ -129,7 +129,7 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
   }
 
   // Set stave visualization.
-  if (x_staves)   {
+  if ( x_staves )   {
     mod_vol.setVisAttributes(lcdd.visAttributes(x_staves.visStr()));
   }
   // Phi start for a stave.
diff --git a/DDDetectors/src/LayeringExtensionPlugin.cpp b/DDDetectors/src/LayeringExtensionPlugin.cpp
new file mode 100644
index 000000000..74fa30de4
--- /dev/null
+++ b/DDDetectors/src/LayeringExtensionPlugin.cpp
@@ -0,0 +1,49 @@
+// $Id: SiTrackerBarrel_geo.cpp 1360 2014-10-27 16:32:06Z Nikiforos.Nikiforou@cern.ch $
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+#include <map>
+#include "DDRec/Extensions/LayeringExtensionImpl.h"
+using namespace DD4hep::DDRec;
+using namespace DD4hep::Geometry;
+
+namespace  {
+  struct  LayeringContext {
+  public:
+    DetElement det, parent;
+    std::map<int,DetElement> layers;
+    LayeringContext() {}
+    ~LayeringContext()  {
+      LayeringExtensionImpl* e = new LayeringExtensionImpl();
+      det.addExtension<LayeringExtension>(e);
+      for(std::map<int,DetElement>::const_iterator i=layers.begin(); i!=layers.end();++i)   {
+	DetElement de = (*i).second;
+	e->setLayer(de.id(), de, Position(0,0,1));
+	std::cout << " Add layer:" << de.name() 
+		  << " ID: " << de.id() 
+		  << " Parent:" << de.parent().name() << std::endl;
+      }
+    }
+  };
+}
+#define SURFACEINSTALLER_DATA LayeringContext
+#define DD4HEP_USE_SURFACEINSTALL_HELPER LayeringExtensionPlugin
+#include "DD4hep/SurfaceInstaller.h"
+
+/// Install volume information. Default implementation only prints!
+template <typename T> void Installer<T>::install(DetElement de, PlacedVolume pv) {
+  if ( ::strstr(de.name(),"layer") != 0 )   {
+    if ( !data.parent.isValid() )  {
+      data.det = m_det;
+      data.parent = de.parent();
+    }
+    if ( data.parent == de.parent() && data.layers.find(de.id()) == data.layers.end() )  {
+      data.layers[de.id()] = de;
+    }
+  }
+}
+
diff --git a/DDDetectors/src/PolyhedraBarrelCalorimeter2_geo.cpp b/DDDetectors/src/PolyhedraBarrelCalorimeter2_geo.cpp
index 02f02b971..7c3390699 100644
--- a/DDDetectors/src/PolyhedraBarrelCalorimeter2_geo.cpp
+++ b/DDDetectors/src/PolyhedraBarrelCalorimeter2_geo.cpp
@@ -9,173 +9,171 @@
 #include "DD4hep/DetFactoryHelper.h"
 #include "XML/Layering.h"
 
-#include "DDRec/Extensions/LayeringExtensionImpl.h"
-#include "DDRec/Extensions/SubdetectorExtensionImpl.h"
-
 using namespace std;
 using namespace DD4hep;
 using namespace DD4hep::Geometry;
-using namespace DD4hep::DDRec;
 
 static void placeStaves(DetElement& parent, DetElement& stave, double rmin, int numsides, double total_thickness,
-		Volume envelopeVolume, double innerAngle, Volume sectVolume) {
-	double innerRotation = innerAngle;
-	double offsetRotation = -innerRotation / 2;
-	double sectCenterRadius = rmin + total_thickness / 2;
-	double rotX = M_PI / 2;
-	double rotY = -offsetRotation;
-	double posX = -sectCenterRadius * std::sin(rotY);
-	double posY = sectCenterRadius * std::cos(rotY);
-
-	for (int module = 1; module <= numsides; ++module) {
-		DetElement det = module > 1 ? stave.clone(_toString(module, "stave%d")) : stave;
-		PlacedVolume pv = envelopeVolume.placeVolume(sectVolume,
-				Transform3D(RotationZYX(0, rotY, rotX), Translation3D(-posX, -posY, 0)));
-		// Not a valid volID: pv.addPhysVolID("stave", 0);
-		pv.addPhysVolID("module", module);
-		det.setPlacement(pv);
-		parent.add(det);
-		rotY -= innerRotation;
-		posX = -sectCenterRadius * std::sin(rotY);
-		posY = sectCenterRadius * std::cos(rotY);
-	}
+			Volume envelopeVolume, double innerAngle, Volume sectVolume) {
+  double innerRotation = innerAngle;
+  double offsetRotation = -innerRotation / 2;
+  double sectCenterRadius = rmin + total_thickness / 2;
+  double rotX = M_PI / 2;
+  double rotY = -offsetRotation;
+  double posX = -sectCenterRadius * std::sin(rotY);
+  double posY = sectCenterRadius * std::cos(rotY);
+
+  for (int module = 1; module <= numsides; ++module) {
+    DetElement det = module > 1 ? stave.clone(_toString(module,"stave%d")) : stave;
+    Transform3D trafo(RotationZYX(0, rotY, rotX), Translation3D(-posX, -posY, 0));
+    PlacedVolume pv = envelopeVolume.placeVolume(sectVolume,trafo);
+    // Not a valid volID: pv.addPhysVolID("stave", 0);
+    pv.addPhysVolID("module", module);
+    det.setPlacement(pv);
+    parent.add(det);
+    rotY -= innerRotation;
+    posX = -sectCenterRadius * std::sin(rotY);
+    posY = sectCenterRadius * std::cos(rotY);
+  }
 }
 
 static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens) {
-	xml_det_t x_det = e;
-	Layering layering(x_det);
-	xml_comp_t staves = x_det.staves();
-	xml_dim_t dim = x_det.dimensions();
-	string det_name = x_det.nameStr();
-	string det_type = x_det.typeStr();
-	Material air = lcdd.air();
-	double totalThickness = layering.totalThickness();
-	int totalRepeat = 0;
-	int totalSlices = 0;
-	double gap = xml_dim_t(x_det).gap();
-	int numSides = dim.numsides();
-	double detZ = dim.z();
-	double rmin = dim.rmin();
-	DetElement sdet(det_name, x_det.id());
-	DetElement stave("stave1", x_det.id());
-	Volume motherVol = lcdd.pickMotherVolume(sdet);
-
-	for (xml_coll_t c(x_det, _U(layer)); c; ++c) {
-		xml_comp_t x_layer = c;
-		int repeat = x_layer.repeat();
-		totalRepeat += repeat;
-		totalSlices += x_layer.numChildren(_U(slice));
+  xml_det_t x_det = e;
+  Layering layering(x_det);
+  xml_comp_t staves = x_det.staves();
+  xml_dim_t dim = x_det.dimensions();
+  string det_name = x_det.nameStr();
+  string det_type = x_det.typeStr();
+  Material air = lcdd.air();
+  double totalThickness = layering.totalThickness();
+  int totalRepeat = 0;
+  int totalSlices = 0;
+  double gap = xml_dim_t(x_det).gap();
+  int numSides = dim.numsides();
+  double detZ = dim.z();
+  double rmin = dim.rmin();
+  DetElement sdet(det_name, x_det.id());
+  DetElement stave("stave1", x_det.id());
+  Volume motherVol = lcdd.pickMotherVolume(sdet);
+
+  for (xml_coll_t c(x_det, _U(layer)); c; ++c) {
+    xml_comp_t x_layer = c;
+    int repeat = x_layer.repeat();
+    totalRepeat += repeat;
+    totalSlices += x_layer.numChildren(_U(slice));
+  }
+
+  PolyhedraRegular polyhedra(numSides, rmin, rmin + totalThickness, detZ);
+  Volume envelopeVol(det_name, polyhedra, air);
+
+  // Add the subdetector envelope to the structure.
+  double innerAngle = 2 * M_PI / numSides;
+  double halfInnerAngle = innerAngle / 2;
+  double tan_inner = std::tan(halfInnerAngle) * 2;
+  double innerFaceLen = rmin * tan_inner;
+  double outerFaceLen = (rmin + totalThickness) * tan_inner;
+  double staveThickness = totalThickness;
+
+  Trapezoid staveTrdOuter(innerFaceLen / 2, outerFaceLen / 2, detZ / 2, detZ / 2, staveThickness / 2);
+  Volume staveOuterVol("stave_outer", staveTrdOuter, air);
+
+  Trapezoid staveTrdInner(innerFaceLen / 2 - gap, outerFaceLen / 2 - gap, detZ / 2, detZ / 2, staveThickness / 2);
+  Volume staveInnerVol("stave_inner", staveTrdInner, air);
+
+  double layerOuterAngle = (M_PI - innerAngle) / 2;
+  double layerInnerAngle = (M_PI / 2 - layerOuterAngle);
+  double layer_pos_z = -(staveThickness / 2);
+  double layer_dim_x = innerFaceLen / 2 - gap * 2;
+  int layer_num = 1;
+
+  //#### LayeringExtensionImpl* layeringExtension = new LayeringExtensionImpl();
+  //#### Position layerNormal(0,0,1);
+
+  for (xml_coll_t c(x_det, _U(layer)); c; ++c) {
+    xml_comp_t x_layer = c;
+    int repeat = x_layer.repeat();            // Get number of times to repeat this layer.
+    const Layer* lay = layering.layer(layer_num - 1); // Get the layer from the layering engine.
+    // Loop over repeats for this layer.
+    for (int j = 0; j < repeat; j++) {
+      string layer_name = _toString(layer_num, "layer%d");
+      double layer_thickness = lay->thickness();
+      DetElement layer(stave, layer_name, layer_num);
+      //### layeringExtension->setLayer(layer_num, layer, layerNormal);
+
+      // Layer position in Z within the stave.
+      layer_pos_z += layer_thickness / 2;
+      // Layer box & volume
+      Volume layer_vol(layer_name, Box(layer_dim_x, detZ / 2, layer_thickness / 2), air);
+
+      // Create the slices (sublayers) within the layer.
+      double slice_pos_z = -(layer_thickness / 2);
+      int slice_number = 1;
+      for (xml_coll_t k(x_layer, _U(slice)); k; ++k) {
+	xml_comp_t x_slice = k;
+	string slice_name = _toString(slice_number, "slice%d");
+	double slice_thickness = x_slice.thickness();
+	Material slice_material = lcdd.material(x_slice.materialStr());
+	DetElement slice(layer, slice_name, slice_number);
+
+	slice_pos_z += slice_thickness / 2;
+	// Slice volume & box
+	Volume slice_vol(slice_name, Box(layer_dim_x, detZ / 2, slice_thickness / 2), slice_material);
+
+	if (x_slice.isSensitive()) {
+	  sens.setType("calorimeter");
+	  slice_vol.setSensitiveDetector(sens);
 	}
-
-	PolyhedraRegular polyhedra(numSides, rmin, rmin + totalThickness, detZ);
-	Volume envelopeVol(det_name + "_envelope", polyhedra, air);
-
-	// Add the subdetector envelope to the structure.
-	double innerAngle = 2 * M_PI / numSides;
-	double halfInnerAngle = innerAngle / 2;
-	double tan_inner = std::tan(halfInnerAngle) * 2;
-	double innerFaceLen = rmin * tan_inner;
-	double outerFaceLen = (rmin + totalThickness) * tan_inner;
-	double staveThickness = totalThickness;
-
-	Trapezoid staveTrdOuter(innerFaceLen / 2, outerFaceLen / 2, detZ / 2, detZ / 2, staveThickness / 2);
-	Volume staveOuterVol(det_name + "_stave", staveTrdOuter, air);
-
-	Trapezoid staveTrdInner(innerFaceLen / 2 - gap, outerFaceLen / 2 - gap, detZ / 2, detZ / 2, staveThickness / 2);
-	Volume staveInnerVol(det_name + "_inner", staveTrdInner, air);
-
-	double layerOuterAngle = (M_PI - innerAngle) / 2;
-	double layerInnerAngle = (M_PI / 2 - layerOuterAngle);
-	double layer_pos_z = -(staveThickness / 2);
-	double layer_dim_x = innerFaceLen / 2 - gap * 2;
-	int layer_num = 1;
-
-	LayeringExtensionImpl* layeringExtension = new LayeringExtensionImpl();
-	Position layerNormal(0,0,1);
-
-	// Set envelope volume attributes.
-	envelopeVol.setAttributes(lcdd, x_det.regionStr(), x_det.limitsStr(), x_det.visStr());
-
-	for (xml_coll_t c(x_det, _U(layer)); c; ++c) {
-		xml_comp_t x_layer = c;
-		int repeat = x_layer.repeat();            // Get number of times to repeat this layer.
-		const Layer* lay = layering.layer(layer_num - 1); // Get the layer from the layering engine.
-		// Loop over repeats for this layer.
-		for (int j = 0; j < repeat; j++) {
-			string layer_name = det_name + _toString(layer_num, "_layer%d");
-			double layer_thickness = lay->thickness();
-			DetElement layer(stave, _toString(layer_num, "layer%d"), x_det.id());
-			layeringExtension->setLayer(layer_num, layer, layerNormal);
-
-			// Layer position in Z within the stave.
-			layer_pos_z += layer_thickness / 2;
-			// Layer box & volume
-			Volume layer_vol(layer_name, Box(layer_dim_x, detZ / 2, layer_thickness / 2), air);
-
-			// Create the slices (sublayers) within the layer.
-			double slice_pos_z = -(layer_thickness / 2);
-			int slice_number = 1;
-			for (xml_coll_t k(x_layer, _U(slice)); k; ++k) {
-				xml_comp_t x_slice = k;
-				string slice_name = layer_name + _toString(slice_number, "_slice%d");
-				double slice_thickness = x_slice.thickness();
-				Material slice_material = lcdd.material(x_slice.materialStr());
-				DetElement slice(layer, _toString(slice_number, "slice%d"), x_det.id());
-
-				slice_pos_z += slice_thickness / 2;
-				// Slice volume & box
-				Volume slice_vol(slice_name, Box(layer_dim_x, detZ / 2, slice_thickness / 2), slice_material);
-
-				if (x_slice.isSensitive()) {
-					sens.setType("calorimeter");
-					slice_vol.setSensitiveDetector(sens);
-				}
-				// Set region, limitset, and vis.
-				slice_vol.setAttributes(lcdd, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr());
-				// slice PlacedVolume
-				PlacedVolume slice_phv = layer_vol.placeVolume(slice_vol, Position(0, 0, slice_pos_z));
-				slice_phv.addPhysVolID("slice", slice_number);
-
-				slice.setPlacement(slice_phv);
-				// Increment Z position for next slice.
-				slice_pos_z += slice_thickness / 2;
-				// Increment slice number.
-				++slice_number;
-			}
-			// Set region, limitset, and vis.
-			layer_vol.setAttributes(lcdd, x_layer.regionStr(), x_layer.limitsStr(), x_layer.visStr());
-
-			// Layer physical volume.
-			PlacedVolume layer_phv = staveInnerVol.placeVolume(layer_vol, Position(0, 0, layer_pos_z));
-			layer_phv.addPhysVolID("layer", layer_num);
-			layer.setPlacement(layer_phv);
-
-			// Increment the layer X dimension.
-			layer_dim_x += layer_thickness * std::tan(layerInnerAngle);    // * 2;
-			// Increment the layer Z position.
-			layer_pos_z += layer_thickness / 2;
-			// Increment the layer number.
-			++layer_num;
-		}
-	}
-
-	// Add stave inner physical volume to outer stave volume.
-	staveOuterVol.placeVolume(staveInnerVol);
-	// Set the vis attributes of the outer stave section.
-	stave.setVisAttributes(lcdd, staves.visStr(), staveOuterVol);
-	// Place the staves.
-	placeStaves(sdet, stave, rmin, numSides, totalThickness, envelopeVol, innerAngle, staveOuterVol);
-
-	double z_offset = dim.hasAttr(_U(z_offset)) ? dim.z_offset() : 0.0;
-	Transform3D transform(RotationZ(M_PI / numSides), Translation3D(0, 0, z_offset));
-	PlacedVolume env_phv = motherVol.placeVolume(envelopeVol, transform);
-	env_phv.addPhysVolID("system", sdet.id());
-	env_phv.addPhysVolID("barrel", 0);
-	sdet.setPlacement(env_phv);
-
-	sdet.addExtension<SubdetectorExtension>(new SubdetectorExtensionImpl(sdet));
-	sdet.addExtension<LayeringExtension>(layeringExtension);
-	return sdet;
+	// Set region, limitset, and vis.
+	slice_vol.setAttributes(lcdd, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr());
+	// slice PlacedVolume
+	PlacedVolume slice_phv = layer_vol.placeVolume(slice_vol, Position(0, 0, slice_pos_z));
+	slice_phv.addPhysVolID("slice", slice_number);
+
+	slice.setPlacement(slice_phv);
+	// Increment Z position for next slice.
+	slice_pos_z += slice_thickness / 2;
+	// Increment slice number.
+	++slice_number;
+      }
+      // Set region, limitset, and vis.
+      layer_vol.setAttributes(lcdd, x_layer.regionStr(), x_layer.limitsStr(), x_layer.visStr());
+
+      // Layer physical volume.
+      PlacedVolume layer_phv = staveInnerVol.placeVolume(layer_vol, Position(0, 0, layer_pos_z));
+      layer_phv.addPhysVolID("layer", layer_num);
+      layer.setPlacement(layer_phv);
+
+      // Increment the layer X dimension.
+      layer_dim_x += layer_thickness * std::tan(layerInnerAngle);    // * 2;
+      // Increment the layer Z position.
+      layer_pos_z += layer_thickness / 2;
+      // Increment the layer number.
+      ++layer_num;
+    }
+  }
+
+  // Add stave inner physical volume to outer stave volume.
+  staveOuterVol.placeVolume(staveInnerVol);
+  if ( staves )  {
+    // Set the vis attributes of the outer stave section.
+    stave.setVisAttributes(lcdd, staves.visStr(), staveInnerVol);
+    stave.setVisAttributes(lcdd, staves.visStr(), staveOuterVol);
+  }
+  // Place the staves.
+  placeStaves(sdet, stave, rmin, numSides, totalThickness, envelopeVol, innerAngle, staveOuterVol);
+  // Set envelope volume attributes.
+  envelopeVol.setAttributes(lcdd, x_det.regionStr(), x_det.limitsStr(), x_det.visStr());
+
+  double z_offset = dim.hasAttr(_U(z_offset)) ? dim.z_offset() : 0.0;
+  Transform3D transform(RotationZ(M_PI / numSides), Translation3D(0, 0, z_offset));
+  PlacedVolume env_phv = motherVol.placeVolume(envelopeVol, transform);
+  env_phv.addPhysVolID("system", sdet.id());
+  env_phv.addPhysVolID("barrel", 0);
+  sdet.setPlacement(env_phv);
+
+  //#### sdet.addExtension<SubdetectorExtension>(new SubdetectorExtensionImpl(sdet));
+  //#### sdet.addExtension<LayeringExtension>(layeringExtension);
+  return sdet;
 }
 
 DECLARE_DETELEMENT(DD4hep_PolyhedraBarrelCalorimeter2, create_detector)
diff --git a/DDDetectors/src/PolyhedraEndcapCalorimeter2_geo.cpp b/DDDetectors/src/PolyhedraEndcapCalorimeter2_geo.cpp
index 51773c3ac..d81deb668 100644
--- a/DDDetectors/src/PolyhedraEndcapCalorimeter2_geo.cpp
+++ b/DDDetectors/src/PolyhedraEndcapCalorimeter2_geo.cpp
@@ -26,7 +26,7 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
   double      zmin      = dim.zmin();
   Layering    layering(x_det);
   double      totalThickness = layering.totalThickness();
-  Volume      envelopeVol(det_name+"_envelope",PolyhedraRegular(numsides,rmin,rmax,totalThickness),air);
+  Volume      envelopeVol("envelope",PolyhedraRegular(numsides,rmin,rmax,totalThickness),air);
     
   int l_num = 1;
   int layerType   = 0;
@@ -37,7 +37,7 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
   for(xml_coll_t c(x_det,_U(layer)); c; ++c)  {
     xml_comp_t       x_layer  = c;
     double           l_thick  = layering.layer(l_num-1)->thickness();
-    string           l_name   = det_name + _toString(layerType,"_layer%d");
+    string           l_name   = _toString(layerType,"layer%d");
     int              l_repeat = x_layer.repeat();
     Volume           l_vol(l_name,PolyhedraRegular(numsides,rmin,rmax,l_thick),air);
       
@@ -45,7 +45,7 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
     double sliceZ = -l_thick/2;
     for(xml_coll_t s(x_layer,_U(slice)); s; ++s)  {
       xml_comp_t x_slice = s;
-      string     s_name  = l_name + _toString(s_num,"_slice%d");
+      string     s_name  = _toString(s_num,"slice%d");
       double     s_thick = x_slice.thickness();
       Material   s_mat   = lcdd.material(x_slice.materialStr());
       Volume     s_vol(s_name,PolyhedraRegular(numsides,rmin,rmax,s_thick),s_mat);
@@ -77,7 +77,7 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
   Volume motherVol = lcdd.pickMotherVolume(sdet);
   // Reflect it.
   if ( reflect )  {
-    Assembly assembly(det_name+"_assembly");
+    Assembly assembly(det_name);
     PlacedVolume pv = motherVol.placeVolume(assembly);
     pv.addPhysVolID("system", det_id);
     sdet.setPlacement(pv);
diff --git a/DDDetectors/src/SiTrackerBarrel_surfaces.cpp b/DDDetectors/src/SiTrackerBarrel_surfaces.cpp
index 6d88ea229..f093d721b 100644
--- a/DDDetectors/src/SiTrackerBarrel_surfaces.cpp
+++ b/DDDetectors/src/SiTrackerBarrel_surfaces.cpp
@@ -7,11 +7,12 @@
 //
 //====================================================================
 // Framework include files
-#define DD4HEP_USE_SURFACEINSTALL_HELPER DD4hep_SiTrackerBarrel_Surfaces
+#define DD4HEP_USE_SURFACEINSTALL_HELPER DD4hep_SiTrackerBarrelSurfacePlugin
 #include "DD4hep/SurfaceInstaller.h"
 
-/// Install volume information. Default implementation only prints!
-void Installer::install(DetElement component, PlacedVolume pv)   {
+/// Install measurement surfaces
+template <typename UserData> 
+void Installer<UserData>::install(DetElement component, PlacedVolume pv)   {
   Volume comp_vol = pv.volume();
   if ( comp_vol.isSensitive() )  {  
     Volume mod_vol  = parentVolume(component);
diff --git a/DDDetectors/src/SiTrackerEndcap_surfaces.cpp b/DDDetectors/src/SiTrackerEndcap_surfaces.cpp
index 297a54e57..52fd3c271 100644
--- a/DDDetectors/src/SiTrackerEndcap_surfaces.cpp
+++ b/DDDetectors/src/SiTrackerEndcap_surfaces.cpp
@@ -7,11 +7,13 @@
 //
 //====================================================================
 // Framework include files
-#define  DD4HEP_USE_SURFACEINSTALL_HELPER  DD4hep_SiTrackerEndcap_Surfaces
+#define  DD4HEP_USE_SURFACEINSTALL_HELPER  DD4hep_SiTrackerEndcapSurfacePlugin
 #include "DD4hep/SurfaceInstaller.h"
 
-void Installer::install(DetElement component, PlacedVolume pv)   {
-  Volume comp_vol = pv.volume();
+/// Install measurement surfaces
+template <typename UserData> 
+void Installer<UserData>::install(DetElement component, PlacedVolume pv)   {
+   Volume comp_vol = pv.volume();
   if ( comp_vol.isSensitive() )  {  
     Volume mod_vol = parentVolume(component);
     DD4hep::Geometry::Trapezoid comp_shape(comp_vol.solid()), mod_shape(mod_vol.solid());
diff --git a/DDDetectors/src/SubdetectorExtensionPlugin.cpp b/DDDetectors/src/SubdetectorExtensionPlugin.cpp
new file mode 100644
index 000000000..ee32c42e6
--- /dev/null
+++ b/DDDetectors/src/SubdetectorExtensionPlugin.cpp
@@ -0,0 +1,21 @@
+// $Id: SiTrackerBarrel_geo.cpp 1360 2014-10-27 16:32:06Z Nikiforos.Nikiforou@cern.ch $
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+// Framework include files
+#include "DDRec/Extensions/SubdetectorExtensionImpl.h"
+#define DD4HEP_USE_SURFACEINSTALL_HELPER SubdetectorExtensionPlugin
+#include "DD4hep/SurfaceInstaller.h"
+
+/// Install volume information. Default implementation only prints!
+template <typename T> void Installer<T>::install(DetElement layer, PlacedVolume pv)   {
+  using namespace DD4hep::DDRec;
+  SubdetectorExtensionImpl* e = new SubdetectorExtensionImpl(m_det);
+  m_det.addExtension<SubdetectorExtension>(e);
+  stopScanning();
+  std::cout << " Installed subdetector extension:" << m_det.name() << " id: " << m_det.id() << std::endl;
+}
-- 
GitLab