diff --git a/compact/ecal.xml b/compact/ecal.xml
index 4e62b49c937e10c70bb07aa5aa7d946718c30cd3..be2a125ca6a76621c663032eb0b4a74ae5d19659 100644
--- a/compact/ecal.xml
+++ b/compact/ecal.xml
@@ -119,7 +119,7 @@
     </comment>
     <detector id="ECalEndcapN_ID" 
       name="EcalEndcapN" 
-      type="topside_PolyhedraEndcapCalorimeter2" 
+      type="refdet_PolyhedraEndcapCalorimeter2" 
       reflect="true" 
       readout="EcalEndcapHits" 
       vis="EcalEndcapVis" 
diff --git a/src/PolyhedraEndcapCalorimeter2_geo.cpp b/src/PolyhedraEndcapCalorimeter2_geo.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3469a1c654074638e943b4b84442b5cfa4ef3a2b
--- /dev/null
+++ b/src/PolyhedraEndcapCalorimeter2_geo.cpp
@@ -0,0 +1,122 @@
+//==========================================================================
+//  AIDA Detector description implementation
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : M.Frank
+//
+//==========================================================================
+//
+// Modified for TOPSiDE detector
+//
+//==========================================================================
+#include "DD4hep/DetFactoryHelper.h"
+#include "XML/Layering.h"
+
+using namespace std;
+using namespace dd4hep;
+using namespace dd4hep::detail;
+
+static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
+    xml_det_t x_det = e;
+    xml_dim_t dim = x_det.dimensions();
+    int det_id = x_det.id();
+    bool reflect = x_det.reflect(true);
+    string det_name = x_det.nameStr();
+    Material air = description.air();
+    int numsides = dim.numsides();
+    double rmin = dim.rmin();
+    double rmax = dim.rmax() * std::cos(M_PI / numsides);
+    double zmin = dim.zmin();
+    Layering layering(x_det);
+    double totalThickness = layering.totalThickness();
+    Volume endcapVol("endcap", PolyhedraRegular(numsides, rmin, rmax, totalThickness), air);
+    DetElement endcap("endcap", det_id);
+
+    int l_num = 1;
+    int layerType = 0;
+    double layerZ = -totalThickness / 2;
+
+    endcapVol.setAttributes(description, x_det.regionStr(), x_det.limitsStr(), x_det.visStr());
+
+    for (xml_coll_t xc(x_det, _U(layer)); xc; ++xc) {
+        xml_comp_t x_layer = xc;
+        double l_thick = layering.layer(l_num - 1)->thickness();
+        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);
+        vector<PlacedVolume> sensitives;
+
+        int s_num = 1;
+        double sliceZ = -l_thick / 2;
+        for (xml_coll_t xs(x_layer, _U(slice)); xs; ++xs) {
+            xml_comp_t x_slice = xs;
+            string s_name = _toString(s_num, "slice%d");
+            double s_thick = x_slice.thickness();
+            Material s_mat = description.material(x_slice.materialStr());
+            Volume s_vol(s_name, PolyhedraRegular(numsides, rmin, rmax, s_thick), s_mat);
+
+            s_vol.setVisAttributes(description.visAttributes(x_slice.visStr()));
+            sliceZ += s_thick / 2;
+            PlacedVolume s_phv = l_vol.placeVolume(s_vol, Position(0, 0, sliceZ));
+            s_phv.addPhysVolID("slice", s_num);
+            if (x_slice.isSensitive()) {
+                sens.setType("calorimeter");
+                s_vol.setSensitiveDetector(sens);
+                sensitives.push_back(s_phv);
+            }
+            sliceZ += s_thick / 2;
+            s_num++;
+        }
+        l_vol.setVisAttributes(description.visAttributes(x_layer.visStr()));
+        if (l_repeat <= 0) throw std::runtime_error(x_det.nameStr() + "> Invalid repeat value");
+        for (int j = 0; j < l_repeat; ++j) {
+            string phys_lay = _toString(l_num, "layer%d");
+            layerZ += l_thick / 2;
+            DetElement layer_elt(endcap, phys_lay, l_num);
+            PlacedVolume pv = endcapVol.placeVolume(l_vol, Position(0, 0, layerZ));
+            pv.addPhysVolID("layer", l_num);
+            layer_elt.setPlacement(pv);
+            for (size_t ic = 0; ic < sensitives.size(); ++ic) {
+                PlacedVolume sens_pv = sensitives[ic];
+                DetElement comp_elt(layer_elt, sens_pv.volume().name(), l_num);
+                comp_elt.setPlacement(sens_pv);
+            }
+            layerZ += l_thick / 2;
+            ++l_num;
+        }
+        ++layerType;
+    }
+
+    double z_pos = zmin + totalThickness / 2;
+    PlacedVolume pv;
+    // Reflect it.
+    Assembly assembly(det_name);
+    DetElement endcapAssyDE(det_name, det_id);
+    Volume motherVol = description.pickMotherVolume(endcapAssyDE);
+    if (reflect) {
+        pv = assembly.placeVolume(endcapVol,
+                                  Transform3D(RotationZYX(M_PI / numsides, M_PI, 0), Position(0, 0, -z_pos)));
+        pv.addPhysVolID("barrel", 2);
+        Ref_t(endcap)->SetName((det_name + "_backward").c_str());
+        endcap.setPlacement(pv);
+    } else {
+        pv = assembly.placeVolume(endcapVol,
+                                  Transform3D(RotationZYX(M_PI / numsides, 0, 0), Position(0, 0, z_pos)));
+        pv.addPhysVolID("barrel", 1);
+        Ref_t(endcap)->SetName((det_name + "_forward").c_str());
+        endcap.setPlacement(pv);
+    }
+    endcapAssyDE.add(endcap);
+    pv = motherVol.placeVolume(assembly);
+    pv.addPhysVolID("system", det_id);
+    endcapAssyDE.setPlacement(pv);
+    return endcapAssyDE;
+}
+
+// clang-format off
+DECLARE_DETELEMENT(refdet_PolyhedraEndcapCalorimeter2, create_detector)