diff --git a/Simulation/DetSimCore/src/DetectorConstruction.cpp b/Simulation/DetSimCore/src/DetectorConstruction.cpp
index 61d1c3b629cf171c02cd6095e3f1cc923652eac9..1f06435134761a8c0c14f3f9627396e166eaf51b 100644
--- a/Simulation/DetSimCore/src/DetectorConstruction.cpp
+++ b/Simulation/DetSimCore/src/DetectorConstruction.cpp
@@ -66,5 +66,6 @@ DetectorConstruction::Construct() {
 
 void
 DetectorConstruction::ConstructSDandField() {
-
+    // Each detelem is responsible for associating SD/Field and its volumes.
+    m_root_detelem->ConstructSDandField();
 }
diff --git a/Simulation/DetSimGeom/src/AnExampleDetElemTool.cpp b/Simulation/DetSimGeom/src/AnExampleDetElemTool.cpp
index 54dd53e9d9873e6c47158cdfb0a46813ab3f8aea..ef1ce8d15c6fbebf593c21bcd13b1cdb0042153a 100644
--- a/Simulation/DetSimGeom/src/AnExampleDetElemTool.cpp
+++ b/Simulation/DetSimGeom/src/AnExampleDetElemTool.cpp
@@ -20,6 +20,7 @@
 #include "G4OpticalSurface.hh"
 
 #include "DD4hep/Detector.h"
+#include "DD4hep/Plugins.h"
 #include "DDG4/Geant4Converter.h"
 #include "DDG4/Geant4Mapping.h"
 
@@ -62,6 +63,63 @@ AnExampleDetElemTool::getLV() {
     return logicAnExample;
 }
 
+void
+AnExampleDetElemTool::ConstructSDandField() {
+    //
+    // Construct SD using DD4hep.
+    // Refer to FCCSW/Detector/DetComponents/src/
+    // 
+
+    typedef std::set<const TGeoVolume*> VolSet;
+    typedef std::map<dd4hep::SensitiveDetector, VolSet> _SV;
+    dd4hep::sim::Geant4GeometryInfo* p = dd4hep::sim::Geant4Mapping::instance().ptr();
+    _SV& vols = p->sensitives;
+
+    auto lcdd = &(dd4hep::Detector::getInstance());
+
+    for (_SV::const_iterator iv = vols.begin(); iv != vols.end(); ++iv) {
+        dd4hep::SensitiveDetector sd = (*iv).first;
+        std::string typ = sd.type(), nam = sd.name();
+
+        info() << "Type/Name: "
+               << typ << "/" << nam
+               << endmsg;
+        // continue;
+        // Sensitive detectors are deleted in ~G4SDManager
+        G4VSensitiveDetector* g4sd = dd4hep::PluginService::Create<G4VSensitiveDetector*>(typ, nam, lcdd);
+        if (g4sd == nullptr) {
+            std::string tmp = typ;
+            // tmp[0] = ::toupper(tmp[0]);
+            typ = "Geant4" + tmp;
+            g4sd = dd4hep::PluginService::Create<G4VSensitiveDetector*>(typ, nam, lcdd);
+            if (g4sd == nullptr) {
+                dd4hep::PluginDebug dbg;
+                g4sd = dd4hep::PluginService::Create<G4VSensitiveDetector*>(typ, nam, lcdd);
+                if (g4sd == nullptr) {
+                    throw std::runtime_error("ConstructSDandField: FATAL Failed to "
+                                             "create Geant4 sensitive detector " +
+                                             nam + " of type " + typ + ".");
+                }
+            }
+        }
+        g4sd->Activate(true);
+        G4SDManager::GetSDMpointer()->AddNewDetector(g4sd);
+        const VolSet& sens_vols = (*iv).second;
+        for (VolSet::const_iterator i = sens_vols.begin(); i != sens_vols.end(); ++i) {
+            const TGeoVolume* vol = *i;
+            G4LogicalVolume* g4v = p->g4Volumes[vol];
+            if (g4v == nullptr) {
+                throw std::runtime_error("ConstructSDandField: Failed to access G4LogicalVolume for SD " + nam + " of type " +
+                                         typ + ".");
+            }
+            G4SDManager::GetSDMpointer()->AddNewDetector(g4sd);
+            g4v->SetSensitiveDetector(g4sd);
+        }
+    }
+
+
+}
+
 StatusCode
 AnExampleDetElemTool::initialize() {
     StatusCode sc;
diff --git a/Simulation/DetSimGeom/src/AnExampleDetElemTool.h b/Simulation/DetSimGeom/src/AnExampleDetElemTool.h
index ed8089b496ab9fcc7df309842aace6d6d3e71c9f..f742c4869df57cd89e6cbd3fa92078f2fe8bfea4 100644
--- a/Simulation/DetSimGeom/src/AnExampleDetElemTool.h
+++ b/Simulation/DetSimGeom/src/AnExampleDetElemTool.h
@@ -14,6 +14,7 @@ public:
     using extends::extends;
 
     G4LogicalVolume* getLV() override;
+    void ConstructSDandField() override;
 
     StatusCode initialize() override;
     StatusCode finalize() override;
diff --git a/Simulation/DetSimGeom/src/WorldDetElemTool.cpp b/Simulation/DetSimGeom/src/WorldDetElemTool.cpp
index c4c766c1354944e04174e968d30c36c205d821ed..289157a85df107e5695b502fbc543c299cea4fd9 100644
--- a/Simulation/DetSimGeom/src/WorldDetElemTool.cpp
+++ b/Simulation/DetSimGeom/src/WorldDetElemTool.cpp
@@ -50,6 +50,14 @@ WorldDetElemTool::getLV() {
     return logicWorld;
 }
 
+void
+WorldDetElemTool::ConstructSDandField() {
+    // After the whole detector volumes are constructed,
+    // now start the construction of SD.
+   ToolHandle<IDetElemTool> inner_detelem_tool("AnExampleDetElemTool");
+   inner_detelem_tool->ConstructSDandField();
+}
+
 StatusCode
 WorldDetElemTool::initialize() {
     StatusCode sc;
diff --git a/Simulation/DetSimGeom/src/WorldDetElemTool.h b/Simulation/DetSimGeom/src/WorldDetElemTool.h
index 7612e75e8f67cfecdf2e8b4c82cec6622aa9cbf8..89601b0a08ef85c01312db10c29c0eb3c1efd121 100644
--- a/Simulation/DetSimGeom/src/WorldDetElemTool.h
+++ b/Simulation/DetSimGeom/src/WorldDetElemTool.h
@@ -10,6 +10,7 @@ public:
     using extends::extends;
 
     G4LogicalVolume* getLV() override;
+    void ConstructSDandField() override;
 
     StatusCode initialize() override;
     StatusCode finalize() override;
diff --git a/Simulation/DetSimInterface/DetSimInterface/IDetElemTool.h b/Simulation/DetSimInterface/DetSimInterface/IDetElemTool.h
index 37a361792f574cf806da98c23a0b25d705de5978..ae9386dd7ed389de7ebfb5ba0f1d343ce3518ef6 100644
--- a/Simulation/DetSimInterface/DetSimInterface/IDetElemTool.h
+++ b/Simulation/DetSimInterface/DetSimInterface/IDetElemTool.h
@@ -19,7 +19,7 @@ public:
 
     // return the constructed detector
     virtual G4LogicalVolume* getLV() = 0;
-
+    virtual void ConstructSDandField() {}
 };
 
 #endif