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