From a2e8ed16f7ab8bcd7a3a4e2137de7678aa83f69c Mon Sep 17 00:00:00 2001
From: lintao <lintao51@gmail.com>
Date: Tue, 15 Oct 2019 12:55:35 +0800
Subject: [PATCH] In order to get hits, need to construct SD first.

---
 .../DetSimCore/src/DetectorConstruction.cpp   |  3 +-
 .../DetSimGeom/src/AnExampleDetElemTool.cpp   | 58 +++++++++++++++++++
 .../DetSimGeom/src/AnExampleDetElemTool.h     |  1 +
 .../DetSimGeom/src/WorldDetElemTool.cpp       |  8 +++
 Simulation/DetSimGeom/src/WorldDetElemTool.h  |  1 +
 .../DetSimInterface/IDetElemTool.h            |  2 +-
 6 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/Simulation/DetSimCore/src/DetectorConstruction.cpp b/Simulation/DetSimCore/src/DetectorConstruction.cpp
index 61d1c3b6..1f064351 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 54dd53e9..ef1ce8d1 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 ed8089b4..f742c486 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 c4c766c1..289157a8 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 7612e75e..89601b0a 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 37a36179..ae9386dd 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
-- 
GitLab