diff --git a/Examples/options/tut_detsim_SDT.py b/Examples/options/tut_detsim_SDT.py
index 027d581388a4aa46983f6d34629364e4c694ce80..ca5498b772ef7afdf10146dc2a551cd4c751a277 100644
--- a/Examples/options/tut_detsim_SDT.py
+++ b/Examples/options/tut_detsim_SDT.py
@@ -121,6 +121,24 @@ detsimalg.RootDetElem = "WorldDetElemTool"
 from Configurables import AnExampleDetElemTool
 example_dettool = AnExampleDetElemTool("AnExampleDetElemTool")
 
+from Configurables import CalorimeterSensDetTool
+from Configurables import DriftChamberSensDetTool
+
+calo_sensdettool = CalorimeterSensDetTool("CalorimeterSensDetTool")
+driftchamber_sensdettool = DriftChamberSensDetTool("DriftChamberSensDetTool")
+
+# dedxoption = "DummyDedxSimTool"
+dedxoption = "BetheBlochEquationDedxSimTool"
+
+driftchamber_sensdettool.DedxSimTool = dedxoption
+
+from Configurables import DummyDedxSimTool
+from Configurables import BetheBlochEquationDedxSimTool
+
+if dedxoption == "DummyDedxSimTool":
+    dedx_simtool = DummyDedxSimTool("DummyDedxSimTool")
+elif dedxoption == "BetheBlochEquationDedxSimTool":
+    dedx_simtool = BetheBlochEquationDedxSimTool("BetheBlochEquationDedxSimTool")
 
 ##############################################################################
 # POD I/O
diff --git a/Service/DedxSvc/CMakeLists.txt b/Service/DedxSvc/CMakeLists.txt
deleted file mode 100644
index 0fce402f937a8b428db7e04bd3b82b83b963ac4b..0000000000000000000000000000000000000000
--- a/Service/DedxSvc/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-gaudi_subdir(DedxSvc v0r0)
-
-set(DedxSvc_srcs
-    src/*.cpp
-)
-find_package(Geant4 REQUIRED ui_all vis_all)
-include(${Geant4_USE_FILE})
-gaudi_install_headers(DedxSvc)
-
-gaudi_add_module(DedxSvc ${DedxSvc_srcs}
-    INCLUDE_DIRS GaudiKernel
-    LINK_LIBRARIES GaudiKernel
-)
diff --git a/Service/DedxSvc/DedxSvc/IDedxSvc.h b/Service/DedxSvc/DedxSvc/IDedxSvc.h
deleted file mode 100644
index 14b76620c9cd503bd72d724eb46acb8d9b9fc8bd..0000000000000000000000000000000000000000
--- a/Service/DedxSvc/DedxSvc/IDedxSvc.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef I_Dedx_SVC_H
-#define I_Dedx_SVC_H
-
-#include "GaudiKernel/IService.h"
-
-#include "G4Step.hh"
-
-class IDedxSvc: virtual public IService {
-public:
-    DeclareInterfaceID(IDedxSvc, 0, 1); // major/minor version
-    
-    virtual ~IDedxSvc() = default;
-    virtual float pred(const G4Step* aStep)=0 ;
-
-};
-
-
-#endif
diff --git a/Service/DedxSvc/src/DedxSvc.cpp b/Service/DedxSvc/src/DedxSvc.cpp
deleted file mode 100644
index 9a62508dd0497e95fc7cfa5dc4cd3d4504354b8b..0000000000000000000000000000000000000000
--- a/Service/DedxSvc/src/DedxSvc.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-#include "DedxSvc.h"
-
-//https://folk.uib.no/ruv004/
-DECLARE_COMPONENT(DedxSvc)
-
-DedxSvc::DedxSvc(const std::string& name, ISvcLocator* svc)
-    : base_class(name, svc)
-{
-}
-
-DedxSvc::~DedxSvc()
-{
-}
-
-float DedxSvc::pred(const G4Step* aStep)
-{
-    G4Track* gTrack = aStep->GetTrack() ;
-    G4int z = gTrack->GetDefinition()->GetPDGCharge();
-    if (z == 0) return 0;
-    G4double M = gTrack->GetDefinition()->GetPDGMass();//MeV
-    M = pow(10,6)*M; //to eV
-    G4double gammabeta=aStep->GetPreStepPoint()->GetBeta() * aStep->GetPreStepPoint()->GetGamma();
-    if(gammabeta<0.01)return 0;//too low momentum
-    float beta = gammabeta/sqrt(1.0+pow(gammabeta,2));
-    float gamma = gammabeta/beta;
-    float Tmax = 2*m_me*pow(gammabeta,2)/(1+(2*gamma*m_me/M)+pow(m_me/M,2));
-    float dedx = m_K*pow(z,2)*m_material_Z*(0.5*log(2*m_me*pow(gammabeta,2)*Tmax/pow(m_I,2))-pow(beta,2))/(m_material_A*pow(beta,2));    
-    dedx = dedx*m_scale;// the material density can be absorbed in scale 
-    dedx = dedx*(1+((*m_distribution)(m_generator)));
-    return dedx*m_material_density; // MeV / cm 
-}
-
-StatusCode DedxSvc::initialize()
-{
-    m_distribution = new std::normal_distribution<double>(0, m_resolution);
-    m_me = 0.511*pow(10,6);//0.511 MeV to eV
-    m_K = 0.307075;//const
-    m_I = m_material_Z*10;  // Approximate
-    return StatusCode::SUCCESS;
-}
-
-StatusCode DedxSvc::finalize()
-{
-    return StatusCode::SUCCESS;
-}
diff --git a/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.cpp b/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.cpp
index 9ef16425454ad9a520659b07536d7ebf344018cc..954664bf21a5897f86285f1380299bf16068df1a 100644
--- a/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.cpp
+++ b/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.cpp
@@ -173,7 +173,7 @@ Edm4hepWriterAnaElemTool::EndOfEventAction(const G4Event* anEvent) {
                 }
 
                 dd4hep::sim::Geant4TrackerHit* trk_hit = dynamic_cast<dd4hep::sim::Geant4TrackerHit*>(h);
-                if (trk_hit) {
+                if (trk_hit && tracker_col_ptr) {
                     ++n_trk_hit;
                     // auto edm_trk_hit = trackercols->create();
                     auto edm_trk_hit = tracker_col_ptr->create();
@@ -192,10 +192,11 @@ Edm4hepWriterAnaElemTool::EndOfEventAction(const G4Event* anEvent) {
                                     trk_hit->momentum.y()/CLHEP::GeV,
                                     trk_hit->momentum.z()/CLHEP::GeV};
                     edm_trk_hit.setMomentum(edm4hep::Vector3f(mom));
+
                 }
 
                 dd4hep::sim::Geant4CalorimeterHit* cal_hit = dynamic_cast<dd4hep::sim::Geant4CalorimeterHit*>(h);
-                if (cal_hit) {
+                if (cal_hit && calo_col_ptr) {
                     ++n_cal_hit;
                     auto edm_calo_hit = calo_col_ptr->create();
                     edm_calo_hit.setCellID(cal_hit->cellID);
diff --git a/Simulation/DetSimDedx/CMakeLists.txt b/Simulation/DetSimDedx/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..824c35b37314dc7b007227c1082b032ea631336b
--- /dev/null
+++ b/Simulation/DetSimDedx/CMakeLists.txt
@@ -0,0 +1,24 @@
+gaudi_subdir(DetSimDedx v0r0)
+
+gaudi_depends_on_subdirs(
+    FWCore
+    Simulation/DetSimInterface
+)
+
+find_package(Geant4 REQUIRED ui_all vis_all)
+include(${Geant4_USE_FILE})
+find_package(DD4hep COMPONENTS DDG4 REQUIRED)
+
+set(DetSimDedx_srcs
+    src/DummyDedxSimTool.cpp
+    src/BetheBlochEquationDedxSimTool.cpp
+)
+
+gaudi_add_module(DetSimDedx ${DetSimDedx_srcs}
+    INCLUDE_DIRS
+    LINK_LIBRARIES
+        DD4hep
+        ${DD4hep_COMPONENT_LIBRARIES}
+        GaudiKernel
+)
+
diff --git a/Simulation/DetSimDedx/src/BetheBlochEquationDedxSimTool.cpp b/Simulation/DetSimDedx/src/BetheBlochEquationDedxSimTool.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6aecca2bb3bf4651e1c5c06f70fc7bfd2d8ea6bc
--- /dev/null
+++ b/Simulation/DetSimDedx/src/BetheBlochEquationDedxSimTool.cpp
@@ -0,0 +1,52 @@
+#include "BetheBlochEquationDedxSimTool.h"
+#include "G4Step.hh"
+#include "G4SystemOfUnits.hh"
+
+// https://folk.uib.no/ruv004/
+DECLARE_COMPONENT(BetheBlochEquationDedxSimTool)
+
+
+double BetheBlochEquationDedxSimTool::dedx(const G4Step* aStep)
+{
+    G4Track* gTrack = aStep->GetTrack() ;
+    G4int z = gTrack->GetDefinition()->GetPDGCharge();
+    if (z == 0) return 0;
+
+    G4Material* material = gTrack->GetMaterial();
+    G4double material_density = material->GetDensity() / (CLHEP::g/CLHEP::cm3); // conert from G4 unit.
+    G4double material_Z = material->GetZ();
+    G4double material_A = material->GetA();
+
+    m_I = material_Z*10;  // Approximate
+
+    G4double M = gTrack->GetDefinition()->GetPDGMass();//MeV
+    M = pow(10,6)*M; //to eV
+    G4double gammabeta=aStep->GetPreStepPoint()->GetBeta() * aStep->GetPreStepPoint()->GetGamma();
+    if(gammabeta<0.01)return 0;//too low momentum
+    float beta = gammabeta/sqrt(1.0+pow(gammabeta,2));
+    float gamma = gammabeta/beta;
+    float Tmax = 2*m_me*pow(gammabeta,2)/(1+(2*gamma*m_me/M)+pow(m_me/M,2));
+    float dedx = m_K*pow(z,2)*material_Z*(0.5*log(2*m_me*pow(gammabeta,2)*Tmax/pow(m_I,2))-pow(beta,2))/(material_A*pow(beta,2));    
+    dedx = dedx*m_scale;// the material density can be absorbed in scale 
+    dedx = dedx*(1+((*m_distribution)(m_generator)));
+    return dedx*material_density; // MeV / cm 
+}
+
+StatusCode BetheBlochEquationDedxSimTool::initialize()
+{
+    m_distribution = new std::normal_distribution<double>(0, m_resolution);
+    m_me = 0.511*pow(10,6);//0.511 MeV to eV
+    m_K = 0.307075;//const
+
+
+    info() << "Initialize BetheBlochEquationDedxSimTool with following parameters" << endmsg;
+    info() << "-> m_me: " << m_me << endmsg;
+    info() << "-> m_K: " << m_K << endmsg;
+
+    return StatusCode::SUCCESS;
+}
+
+StatusCode BetheBlochEquationDedxSimTool::finalize()
+{
+    return StatusCode::SUCCESS;
+}
diff --git a/Service/DedxSvc/src/DedxSvc.h b/Simulation/DetSimDedx/src/BetheBlochEquationDedxSimTool.h
similarity index 71%
rename from Service/DedxSvc/src/DedxSvc.h
rename to Simulation/DetSimDedx/src/BetheBlochEquationDedxSimTool.h
index 6f1f85eb53dbabf872cbbe56aee9a44e4656a639..6e80ad7972d1fcac831f709cde20f77f8bf97f5a 100644
--- a/Service/DedxSvc/src/DedxSvc.h
+++ b/Simulation/DetSimDedx/src/BetheBlochEquationDedxSimTool.h
@@ -1,21 +1,17 @@
-#ifndef Dedx_SVC_H
-#define Dedx_SVC_H
+#ifndef BetheBlochEquationDedxSimTool_h
+#define BetheBlochEquationDedxSimTool_h
 
-#include "DedxSvc/IDedxSvc.h"
-#include <GaudiKernel/Service.h>
-#include "G4Step.hh"
+#include "DetSimInterface/IDedxSimTool.h"
+#include <GaudiKernel/AlgTool.h>
 #include <random>
 
-class DedxSvc : public extends<Service, IDedxSvc>
-{
+class BetheBlochEquationDedxSimTool: public extends<AlgTool, IDedxSimTool> {
     public:
-        DedxSvc(const std::string& name, ISvcLocator* svc);
-        ~DedxSvc();
-
+        using extends::extends;
 
         StatusCode initialize() override;
         StatusCode finalize() override;
-        float pred(const G4Step* aStep) override;
+        double dedx(const G4Step* aStep) override;
 
     private:
 
@@ -27,6 +23,7 @@ class DedxSvc : public extends<Service, IDedxSvc>
         float m_me;// Here me is the electron rest mass
         float m_K; // K was set as a constant.
         float m_I; // Mean excitation energy
+
         std::default_random_engine m_generator;
         std::normal_distribution<double>* m_distribution;
 };
diff --git a/Simulation/DetSimDedx/src/DummyDedxSimTool.cpp b/Simulation/DetSimDedx/src/DummyDedxSimTool.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..291b8c205eafd630a9e45f9be64a99cbd0827c87
--- /dev/null
+++ b/Simulation/DetSimDedx/src/DummyDedxSimTool.cpp
@@ -0,0 +1,24 @@
+#include "DummyDedxSimTool.h"
+
+#include "G4Step.hh"
+
+DECLARE_COMPONENT(DummyDedxSimTool);
+
+StatusCode DummyDedxSimTool::initialize() {
+    StatusCode sc;
+
+    return sc;
+}
+
+StatusCode DummyDedxSimTool::finalize() {
+    StatusCode sc;
+
+    return sc;
+}
+
+double DummyDedxSimTool::dedx(const G4Step* aStep) {
+    double result = aStep->GetTotalEnergyDeposit();
+
+
+    return result;
+}
diff --git a/Simulation/DetSimDedx/src/DummyDedxSimTool.h b/Simulation/DetSimDedx/src/DummyDedxSimTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..ce7f3e3e4a49430a2f9736e03c4538c2cb87878f
--- /dev/null
+++ b/Simulation/DetSimDedx/src/DummyDedxSimTool.h
@@ -0,0 +1,21 @@
+#ifndef DummyDedxSimTool_h
+#define DummyDedxSimTool_h
+
+#include "GaudiKernel/AlgTool.h"
+#include "DetSimInterface/IDedxSimTool.h"
+
+class DummyDedxSimTool: public extends<AlgTool, IDedxSimTool> {
+
+public:
+    using extends::extends;
+
+    /// Overriding initialize and finalize
+    StatusCode initialize() override;
+    StatusCode finalize() override;
+
+    /// Overriding dedx tool
+    double dedx(const G4Step* aStep) override;
+
+};
+
+#endif
diff --git a/Simulation/DetSimGeom/src/AnExampleDetElemTool.cpp b/Simulation/DetSimGeom/src/AnExampleDetElemTool.cpp
index 87ad61b35a7fb05c9bd18999bcc3ea5e40d66c9f..e78170bc5eaf9534a29126630458285166421772 100644
--- a/Simulation/DetSimGeom/src/AnExampleDetElemTool.cpp
+++ b/Simulation/DetSimGeom/src/AnExampleDetElemTool.cpp
@@ -110,6 +110,17 @@ AnExampleDetElemTool::ConstructSDandField() {
                 }
             } else if (typ=="tracker") {
 
+                // if drift chamber
+                if (nam == "DriftChamber") {
+                    m_driftchamber_sdtool = ToolHandle<ISensDetTool>("DriftChamberSensDetTool");
+                    if (m_driftchamber_sdtool) {
+                        info() << "Find the DriftChamberSensDetTool" << endmsg;
+                        g4sd = m_driftchamber_sdtool->createSD(nam);
+                    } else {
+                        warning() << "DriftChamberSensDetTool is not found. " << endmsg;
+                    }
+                }
+
             }
         }
         
@@ -186,6 +197,9 @@ AnExampleDetElemTool::initialize() {
         return StatusCode::FAILURE;
     }
 
+    m_calo_sdtool = ToolHandle<ISensDetTool>("CalorimeterSensDetTool");
+    m_driftchamber_sdtool = ToolHandle<ISensDetTool>("DriftChamberSensDetTool");
+
     return sc;
 }
 
diff --git a/Simulation/DetSimGeom/src/AnExampleDetElemTool.h b/Simulation/DetSimGeom/src/AnExampleDetElemTool.h
index b0b22861b892c0817876e9c325853e843acf7dc4..ba1990715d10ca9f07eb5a2791314f8ce0d090ee 100644
--- a/Simulation/DetSimGeom/src/AnExampleDetElemTool.h
+++ b/Simulation/DetSimGeom/src/AnExampleDetElemTool.h
@@ -33,6 +33,7 @@ private:
 
     SmartIF<IGeoSvc> m_geosvc;
     ToolHandle<ISensDetTool> m_calo_sdtool;
+    ToolHandle<ISensDetTool> m_driftchamber_sdtool;
 };
 
 #endif
diff --git a/Simulation/DetSimInterface/DetSimInterface/IDedxSimTool.h b/Simulation/DetSimInterface/DetSimInterface/IDedxSimTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..f47ceb0211c3a61553adca623e443f25e46c5038
--- /dev/null
+++ b/Simulation/DetSimInterface/DetSimInterface/IDedxSimTool.h
@@ -0,0 +1,29 @@
+#ifndef IDedxSimTool_h
+#define IDedxSimTool_h
+
+/*
+ * Description:
+ *   IDedxSimTool is used to give a dE/dx value during simulation.
+ *
+ * The interface:
+ *   * dedx: predict the dE/dx according to Geant4 Step
+ *
+ * Author: Tao Lin <lintao@ihep.ac.cn>
+ */
+
+
+#include "GaudiKernel/IAlgTool.h"
+
+class G4Step;
+
+class IDedxSimTool: virtual public IAlgTool {
+public:
+
+    DeclareInterfaceID(IDedxSimTool, 0, 1);
+    virtual ~IDedxSimTool() {}
+
+    virtual double dedx(const G4Step* aStep) = 0;
+
+};
+
+#endif
diff --git a/Simulation/DetSimSD/CMakeLists.txt b/Simulation/DetSimSD/CMakeLists.txt
index 10b1a15a3f0d9ed6cf91a635ea6d53eca49daba3..d917ecef05a6bb5253e4a1e1529472ab939e184b 100644
--- a/Simulation/DetSimSD/CMakeLists.txt
+++ b/Simulation/DetSimSD/CMakeLists.txt
@@ -16,6 +16,9 @@ set(DetSimSD_srcs
 
     src/DDG4SensitiveDetector.cpp
     src/CaloSensitiveDetector.cpp
+
+    src/DriftChamberSensDetTool.cpp
+    src/DriftChamberSensitiveDetector.cpp
 )
 
 gaudi_add_module(DetSimSD ${DetSimSD_srcs}
diff --git a/Simulation/DetSimSD/src/DriftChamberSensDetTool.cpp b/Simulation/DetSimSD/src/DriftChamberSensDetTool.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bf0532165fcf820a10563af25f9ff172fbdacc8e
--- /dev/null
+++ b/Simulation/DetSimSD/src/DriftChamberSensDetTool.cpp
@@ -0,0 +1,48 @@
+#include "DriftChamberSensDetTool.h"
+
+#include "G4VSensitiveDetector.hh"
+
+#include "DD4hep/Detector.h"
+
+#include "DriftChamberSensitiveDetector.h"
+
+DECLARE_COMPONENT(DriftChamberSensDetTool);
+
+StatusCode DriftChamberSensDetTool::initialize() {
+    StatusCode sc;
+
+    m_geosvc = service<IGeoSvc>("GeoSvc");
+    if (!m_geosvc) {
+        error() << "Failed to find GeoSvc." << endmsg;
+        return StatusCode::FAILURE;
+    }
+
+    m_dedx_simtool = ToolHandle<IDedxSimTool>(m_dedx_sim_option.value());
+    if (!m_dedx_simtool) {
+        error() << "Failed to find dedx simtoo." << endmsg;
+        return StatusCode::FAILURE;
+    }
+
+    return sc;
+}
+
+StatusCode DriftChamberSensDetTool::finalize() {
+    StatusCode sc;
+    
+    return sc;
+}
+
+G4VSensitiveDetector*
+DriftChamberSensDetTool::createSD(const std::string& name) {
+    dd4hep::Detector* dd4hep_geo = m_geosvc->lcdd();
+
+    G4VSensitiveDetector* sd = nullptr;
+
+    if (name == "DriftChamber") {
+        DriftChamberSensitiveDetector* dcsd = new DriftChamberSensitiveDetector(name, *dd4hep_geo);
+        dcsd->setDedxSimTool(m_dedx_simtool);
+    }
+
+
+    return sd;
+}
diff --git a/Simulation/DetSimSD/src/DriftChamberSensDetTool.h b/Simulation/DetSimSD/src/DriftChamberSensDetTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..ae727ed09fbcb58c5ea918cf3e86813bd2625a2f
--- /dev/null
+++ b/Simulation/DetSimSD/src/DriftChamberSensDetTool.h
@@ -0,0 +1,41 @@
+#ifndef DriftChamberSensDetTool_h
+#define DriftChamberSensDetTool_h
+
+/*
+ * DriftChamberSensDetTool is used to create Drift Chamber SD.
+ * 
+ * It will use DedxSimTool to give the dE/dx value.
+ *
+ * -- 17 Sept 2020, Tao Lin <lintao@ihep.ac.cn>
+ */
+
+#include "GaudiKernel/AlgTool.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "DetSimInterface/ISensDetTool.h"
+#include "DetSimInterface/IDedxSimTool.h"
+#include "DetInterface/IGeoSvc.h"
+
+
+class DriftChamberSensDetTool: public extends<AlgTool, ISensDetTool> {
+
+public:
+
+    using extends::extends;
+
+    /// Overriding initialize and finalize
+    StatusCode initialize() override;
+    StatusCode finalize() override;
+
+    /// Override ISensDetTool
+    virtual G4VSensitiveDetector* createSD(const std::string& name) override;
+
+private:
+
+    // in order to initialize SD, we need to get the lcdd()
+    SmartIF<IGeoSvc> m_geosvc;
+    ToolHandle<IDedxSimTool> m_dedx_simtool;
+    Gaudi::Property<std::string> m_dedx_sim_option{this, "DedxSimTool"};
+
+};
+
+#endif
diff --git a/Simulation/DetSimSD/src/DriftChamberSensitiveDetector.cpp b/Simulation/DetSimSD/src/DriftChamberSensitiveDetector.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1ba9f7bff59a19d93519bf36368daee33035a7e9
--- /dev/null
+++ b/Simulation/DetSimSD/src/DriftChamberSensitiveDetector.cpp
@@ -0,0 +1,73 @@
+#include "DriftChamberSensitiveDetector.h"
+
+#include "G4SDManager.hh"
+
+DriftChamberSensitiveDetector::DriftChamberSensitiveDetector(const std::string& name,
+                                                             dd4hep::Detector& description)
+    : DDG4SensitiveDetector(name, description),
+      m_hc(nullptr) {
+
+    const std::string& coll_name = m_sensitive.hitsCollection();
+
+    collectionName.insert(coll_name);
+}
+
+bool DriftChamberSensitiveDetector::setDedxSimTool(ToolHandle<IDedxSimTool> simtool) {
+    m_dedx_simtool = simtool;
+
+    return true;
+}
+
+void
+DriftChamberSensitiveDetector::Initialize(G4HCofThisEvent* HCE) {
+
+    const std::string& coll_name = collectionName[0];
+    m_hc = new HitCollection(GetName(), coll_name);
+
+    int HCID = -1;
+    if(HCID<0) HCID = G4SDManager::GetSDMpointer()->GetCollectionID(m_hc);
+    HCE->AddHitsCollection( HCID, m_hc ); 
+
+}
+
+G4bool
+DriftChamberSensitiveDetector::ProcessHits(G4Step* step, G4TouchableHistory*) {
+    // Refer to: DDG4/legacy/Geant4TrackerSD.cpp (note: there's bug in momentum calculation)
+    //           DDCore/include/DD4hep/Objects.h (mean_direction and mean_length)
+
+    dd4hep::sim::Geant4StepHandler h(step);
+
+    dd4hep::Position prePos    = h.prePos();
+    dd4hep::Position postPos   = h.postPos();
+    dd4hep::Position direction = postPos - prePos;
+    dd4hep::Position position  = mean_direction(prePos,postPos); // (pre+post)/2
+    double           hit_len   = direction.R();
+
+    HitContribution contrib = dd4hep::sim::Geant4Hit::extractContribution(step);
+    // Now, invokes the dE/dx simulator
+    double dedx = 0.0;
+
+    double de = hit_len * dedx;
+    // contrib.deposit = de; // if need the de from dedx simulator
+
+    // create a new hit
+    TrackerHit* hit = new TrackerHit(
+                                     h.track->GetTrackID(),
+                                     h.track->GetDefinition()->GetPDGEncoding(),
+                                     de, // not the Geant4's deposit energy. from dE/dx simulator
+                                     h.track->GetGlobalTime()
+                                     );
+    hit->cellID = getCellID(step);
+    hit->energyDeposit = de; // FIXME: also use the dedx
+    hit->position = position;
+    hit->momentum = (h.preMom() + h.postMom() )/2;
+    hit->length   = hit_len;
+    m_hc->insert(hit);
+
+    return true;
+}
+
+void
+DriftChamberSensitiveDetector::EndOfEvent(G4HCofThisEvent* HCE) {
+
+}
diff --git a/Simulation/DetSimSD/src/DriftChamberSensitiveDetector.h b/Simulation/DetSimSD/src/DriftChamberSensitiveDetector.h
new file mode 100644
index 0000000000000000000000000000000000000000..638e146bcad688dc5a0fdefb4f1178394c6c09ad
--- /dev/null
+++ b/Simulation/DetSimSD/src/DriftChamberSensitiveDetector.h
@@ -0,0 +1,40 @@
+#ifndef DriftChamberSensitiveDetector_h
+#define DriftChamberSensitiveDetector_h
+
+/*
+ * DriftChamberSensitiveDetector is used in Drift Chamber with dE/dx simulator.
+ *
+ * 19 Sept. 2020, Tao Lin <lintao@ihep.ac.cn>
+ */
+
+#include "DetSimSD/DDG4SensitiveDetector.h"
+#include "DetSimInterface/IDedxSimTool.h"
+#include "GaudiKernel/ToolHandle.h"
+
+class DriftChamberSensitiveDetector: public DDG4SensitiveDetector {
+public:
+    typedef dd4hep::sim::Geant4TrackerHit TrackerHit;
+    typedef G4THitsCollection<TrackerHit> TrackerHitCollection;
+
+public:
+    DriftChamberSensitiveDetector(const std::string& name, dd4hep::Detector& description);
+
+    bool setDedxSimTool(ToolHandle<IDedxSimTool>);
+    
+public:
+    // Geant4 interface
+
+    virtual void Initialize(G4HCofThisEvent* HCE);
+    virtual G4bool ProcessHits(G4Step* step,G4TouchableHistory* history);
+    virtual void EndOfEvent(G4HCofThisEvent* HCE);
+
+protected:
+
+    HitCollection* m_hc;
+
+    // this is passed from SensDetTool
+    ToolHandle<IDedxSimTool> m_dedx_simtool;
+
+};
+
+#endif