diff --git a/src/TrapEndcapTracker_geo.cpp b/src/TrapEndcapTracker_geo.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..30251db0fba60c0b87b6d004185269027b129be9
--- /dev/null
+++ b/src/TrapEndcapTracker_geo.cpp
@@ -0,0 +1,144 @@
+//==========================================================================
+//  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
+//
+//==========================================================================
+//
+// Specialized generic detector constructor
+//
+//==========================================================================
+#include <map>
+#include "DD4hep/DetFactoryHelper.h"
+
+using namespace std;
+using namespace dd4hep;
+using namespace dd4hep::detail;
+
+static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
+    typedef vector<PlacedVolume> Placements;
+    xml_det_t x_det = e;
+    Material vacuum = description.vacuum();
+    int det_id = x_det.id();
+    string det_name = x_det.nameStr();
+    bool reflect = x_det.reflect(false);
+    DetElement sdet(det_name, det_id);
+    Assembly assembly(det_name);
+    // Volume      assembly    (det_name,Box(10000,10000,10000),vacuum);
+    Volume motherVol = description.pickMotherVolume(sdet);
+    int m_id = 0, c_id = 0, n_sensor = 0;
+    map<string, Volume> modules;
+    map<string, Placements> sensitives;
+    PlacedVolume pv;
+
+    assembly.setVisAttributes(description.invisible());
+    sens.setType("tracker");
+
+    for (xml_coll_t mi(x_det, _U(module)); mi; ++mi, ++m_id) {
+        xml_comp_t x_mod = mi;
+        string m_nam = x_mod.nameStr();
+        xml_comp_t trd = x_mod.trd();
+        double posY;
+        double x1 = trd.x1();
+        double x2 = trd.x2();
+        double z = trd.z();
+        double y1, y2, total_thickness = 0.;
+        xml_coll_t ci(x_mod, _U(module_component));
+        for (ci.reset(), total_thickness = 0.0; ci; ++ci) total_thickness += xml_comp_t(ci).thickness();
+
+        y1 = y2 = total_thickness / 2;
+        Volume m_volume(m_nam, Trapezoid(x1, x2, y1, y2, z), vacuum);
+        m_volume.setVisAttributes(description.visAttributes(x_mod.visStr()));
+
+        for (ci.reset(), n_sensor = 1, c_id = 0, posY = -y1; ci; ++ci, ++c_id) {
+            xml_comp_t c = ci;
+            double c_thick = c.thickness();
+            auto comp_x1   = getAttrOrDefault(c, _Unicode(x1), x1);
+            auto comp_x2   = getAttrOrDefault(c, _Unicode(x2), x2);
+            auto comp_height   = getAttrOrDefault(c, _Unicode(height), z);
+
+            Material c_mat = description.material(c.materialStr());
+            string c_name = _toString(c_id, "component%d");
+            Volume c_vol(c_name, Trapezoid(comp_x1, comp_x2, c_thick / 2e0, c_thick / 2e0, comp_height), c_mat);
+
+            c_vol.setVisAttributes(description.visAttributes(c.visStr()));
+            pv = m_volume.placeVolume(c_vol, Position(0, posY + c_thick / 2, 0));
+            if (c.isSensitive()) {
+                sdet.check(n_sensor > 2,
+                           "SiTrackerEndcap2::fromCompact: " + c_name + " Max of 2 modules allowed!");
+                pv.addPhysVolID("sensor", n_sensor);
+                c_vol.setSensitiveDetector(sens);
+                sensitives[m_nam].push_back(pv);
+                ++n_sensor;
+            }
+            posY += c_thick;
+        }
+        modules[m_nam] = m_volume;
+    }
+
+    for (xml_coll_t li(x_det, _U(layer)); li; ++li) {
+        xml_comp_t x_layer(li);
+        int l_id = x_layer.id();
+        int mod_num = 1;
+        for (xml_coll_t ri(x_layer, _U(ring)); ri; ++ri) {
+            xml_comp_t x_ring = ri;
+            double r = x_ring.r();
+            double phi0 = x_ring.phi0(0);
+            double zstart = x_ring.zstart();
+            double dz = x_ring.dz(0);
+            int nmodules = x_ring.nmodules();
+            string m_nam = x_ring.moduleStr();
+            Volume m_vol = modules[m_nam];
+            double iphi = 2 * M_PI / nmodules;
+            double phi = phi0;
+            Placements& sensVols = sensitives[m_nam];
+
+            for (int k = 0; k < nmodules; ++k) {
+                string m_base = _toString(l_id, "layer%d") + _toString(mod_num, "_module%d");
+                double x = -r * std::cos(phi);
+                double y = -r * std::sin(phi);
+                DetElement module(sdet, m_base + "_pos", det_id);
+                pv = assembly.placeVolume(m_vol, Transform3D(RotationZYX(0, -M_PI / 2 - phi, -M_PI / 2),
+                                                             Position(x, y, zstart + dz)));
+                pv.addPhysVolID("barrel", 1).addPhysVolID("layer", l_id).addPhysVolID("module", mod_num);
+                module.setPlacement(pv);
+                for (size_t ic = 0; ic < sensVols.size(); ++ic) {
+                    PlacedVolume sens_pv = sensVols[ic];
+                    DetElement comp_elt(module, sens_pv.volume().name(), mod_num);
+                    comp_elt.setPlacement(sens_pv);
+                }
+
+                if (reflect) {
+                    pv =
+                        assembly.placeVolume(m_vol, Transform3D(RotationZYX(M_PI, -M_PI / 2 - phi, -M_PI / 2),
+                                                                Position(x, y, -zstart - dz)));
+                    pv.addPhysVolID("barrel", 2).addPhysVolID("layer", l_id).addPhysVolID("module", mod_num);
+                    DetElement r_module(sdet, m_base + "_neg", det_id);
+                    r_module.setPlacement(pv);
+                    for (size_t ic = 0; ic < sensVols.size(); ++ic) {
+                        PlacedVolume sens_pv = sensVols[ic];
+                        DetElement comp_elt(r_module, sens_pv.volume().name(), mod_num);
+                        comp_elt.setPlacement(sens_pv);
+                    }
+                }
+                dz = -dz;
+                phi += iphi;
+                ++mod_num;
+            }
+        }
+    }
+    pv = motherVol.placeVolume(assembly);
+    pv.addPhysVolID("system", det_id);
+    sdet.setPlacement(pv);
+    return sdet;
+}
+
+// clang-format off
+DECLARE_DETELEMENT(refdet_TrapEndcapTracker, create_detector)
+DECLARE_DETELEMENT(refdet_GEMTrackerEndcap, create_detector)