diff --git a/Simulation/DetSimSD/CMakeLists.txt b/Simulation/DetSimSD/CMakeLists.txt
index f982aaec3440cb5ab461206402150f340b65e1a6..10b1a15a3f0d9ed6cf91a635ea6d53eca49daba3 100644
--- a/Simulation/DetSimSD/CMakeLists.txt
+++ b/Simulation/DetSimSD/CMakeLists.txt
@@ -15,6 +15,7 @@ set(DetSimSD_srcs
     src/CalorimeterSensDetTool.cpp
 
     src/DDG4SensitiveDetector.cpp
+    src/CaloSensitiveDetector.cpp
 )
 
 gaudi_add_module(DetSimSD ${DetSimSD_srcs}
diff --git a/Simulation/DetSimSD/DetSimSD/CaloSensitiveDetector.h b/Simulation/DetSimSD/DetSimSD/CaloSensitiveDetector.h
new file mode 100644
index 0000000000000000000000000000000000000000..f9cbda02c03823ddf02d05d4642eab4d015e4f2c
--- /dev/null
+++ b/Simulation/DetSimSD/DetSimSD/CaloSensitiveDetector.h
@@ -0,0 +1,36 @@
+#ifndef CaloSensitiveDetector_h
+#define CaloSensitiveDetector_h
+
+/*
+ * This is an implementation of Calo SD.
+ *
+ * -- 13 June 2020, Tao Lin <lintao@ihep.ac.cn>
+ */
+
+#include "DetSimSD/DDG4SensitiveDetector.h"
+
+class CaloSensitiveDetector: public DDG4SensitiveDetector {
+public:
+    typedef dd4hep::sim::Geant4CalorimeterHit CalorimeterHit;
+    typedef G4THitsCollection<CalorimeterHit> HitCollection;
+
+public:
+    CaloSensitiveDetector(const std::string& name, dd4hep::Detector& description);
+
+public:
+    // Geant4 interface
+
+    virtual void Initialize(G4HCofThisEvent* HCE);
+    virtual G4bool ProcessHits(G4Step* step,G4TouchableHistory* history);
+    virtual void EndOfEvent(G4HCofThisEvent* HCE);
+
+protected:
+    CalorimeterHit* find(const HitCollection*, const dd4hep::sim::HitCompare<CalorimeterHit>&);
+    
+protected:
+
+    HitCollection* m_hc;
+};
+
+
+#endif
diff --git a/Simulation/DetSimSD/DetSimSD/DDG4SensitiveDetector.h b/Simulation/DetSimSD/DetSimSD/DDG4SensitiveDetector.h
index 846044b953e10913b6768c4e66a7a117b33ca38a..94d9525b3f76ff596094911f39b80ec5518e11d3 100644
--- a/Simulation/DetSimSD/DetSimSD/DDG4SensitiveDetector.h
+++ b/Simulation/DetSimSD/DetSimSD/DDG4SensitiveDetector.h
@@ -65,9 +65,6 @@ protected:
     /// Reference to the readout structure
     dd4hep::Readout m_readout;
 
-    /// Geant4 event context
-    G4HCofThisEvent* m_hce;
-
 };
 
 #endif
diff --git a/Simulation/DetSimSD/src/CaloSensitiveDetector.cpp b/Simulation/DetSimSD/src/CaloSensitiveDetector.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..10993d325fbbc342273e2242a588acbe5088323f
--- /dev/null
+++ b/Simulation/DetSimSD/src/CaloSensitiveDetector.cpp
@@ -0,0 +1,65 @@
+#include "DetSimSD/CaloSensitiveDetector.h"
+
+#include "G4SDManager.hh"
+
+#include <algorithm>
+
+CaloSensitiveDetector::CaloSensitiveDetector(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);
+}
+
+void
+CaloSensitiveDetector::Initialize(G4HCofThisEvent* HCE) {
+
+    // the collection name is provided by DD4hep
+    const std::string& coll_name = collectionName[0];
+    m_hc = new G4THitsCollection<CalorimeterHit>(GetName(), coll_name);
+
+    int HCID = -1;
+    if(HCID<0) HCID = G4SDManager::GetSDMpointer()->GetCollectionID(m_hc);
+    HCE->AddHitsCollection( HCID, m_hc ); 
+
+}
+
+G4bool
+CaloSensitiveDetector::ProcessHits(G4Step* step, G4TouchableHistory*) {
+
+    dd4hep::sim::Geant4StepHandler h(step);
+    dd4hep::Position pos = 0.5 * (h.prePos() + h.postPos());
+    HitContribution contrib = dd4hep::sim::Geant4Hit::extractContribution(step);
+    CalorimeterHit* hit=find(m_hc,dd4hep::sim::HitPositionCompare<CalorimeterHit>(pos));
+
+    //    G4cout << "----------- Geant4GenericSD<Calorimeter>::buildHits : position : " << pos << G4endl;
+    if ( !hit ) {
+        hit = new CalorimeterHit(pos);
+        hit->cellID  = getCellID( step );
+        m_hc->insert(hit);
+    }
+    hit->truth.push_back(contrib);
+    hit->energyDeposit += contrib.deposit;
+
+
+    
+    return true;
+}
+
+void
+CaloSensitiveDetector::EndOfEvent(G4HCofThisEvent* HCE) {
+
+}
+
+CaloSensitiveDetector::CalorimeterHit*
+CaloSensitiveDetector::find(const CaloSensitiveDetector::HitCollection* c,
+                            const dd4hep::sim::HitCompare<CaloSensitiveDetector::CalorimeterHit>& cmp) {
+    typedef std::vector<CalorimeterHit*> _V;
+    const _V* v = (const _V*) c->GetVector();
+    for (_V::const_iterator i = v->begin(); i != v->end(); ++i) {
+        if (cmp(*i)) {
+            return *i;
+        }
+    }
+    return 0;
+}
diff --git a/Simulation/DetSimSD/src/DDG4SensitiveDetector.cpp b/Simulation/DetSimSD/src/DDG4SensitiveDetector.cpp
index e4b86aa9f4a4d2df3ac82c5319021146dc7cf7cf..25ce06c0a2da935a1d8d7e4bad09e360962f1985 100644
--- a/Simulation/DetSimSD/src/DDG4SensitiveDetector.cpp
+++ b/Simulation/DetSimSD/src/DDG4SensitiveDetector.cpp
@@ -24,8 +24,7 @@ static const double MM_2_CM = (dd4hep::millimeter/CLHEP::millimeter);
 
 DDG4SensitiveDetector::DDG4SensitiveDetector(const std::string& name, dd4hep::Detector& description)
     : G4VSensitiveDetector(name), m_detDesc(description),
-      m_detector(), m_sensitive(), m_readout(),
-      m_hce(nullptr) {
+      m_detector(), m_sensitive(), m_readout() {
     m_detector = description.detector(name);
     m_sensitive = description.sensitiveDetector(name);
     m_readout = m_sensitive.readout();