11#include "G4SDManager.hh"
12#include "G4GeometryManager.hh"
13#include "G4SolidStore.hh"
14#include "G4LogicalVolumeStore.hh"
15#include "G4PhysicalVolumeStore.hh"
16#include "G4ReflectionFactory.hh"
17#include "G4RunManager.hh"
20G4ThreadLocal
GMagneto* GDetectorConstruction::gmagneto =
nullptr;
24 G4VUserDetectorConstruction(),
27 digitization_routines_map = std::make_shared<gdynamicdigitization::dRoutinesMap>();
36 G4GeometryManager::GetInstance()->OpenGeometry();
37 G4PhysicalVolumeStore::Clean();
38 G4LogicalVolumeStore::Clean();
39 G4SolidStore::Clean();
40 G4ReflectionFactory::Instance()->Clean();
49 if (gsystems.empty()) {
51 gworld = std::make_shared<GWorld>(gopt);
55 gworld = std::make_shared<GWorld>(gopt, gsystems);
59 g4world = std::make_shared<G4World>(gworld.get(), gopt);
66 nsdetectors,
" sensitive detectors\n");
75 auto sdManager = G4SDManager::GetSDMpointer();
81 std::unordered_map<std::string, GSensitiveDetector*> sensitiveDetectorsMap;
84 for (
const auto& [systemName, gsystemPtr] : *gworld->
getSystemsMap()) {
85 for (
const auto& [volumeName, gvolumePtr] : gsystemPtr->getGVolumesMap()) {
86 auto const& digitizationName = gvolumePtr->getDigitization();
87 auto const& g4name = gvolumePtr->getG4Name();
93 if (g4volume ==
nullptr) {
94 std::string copyOf = gvolumePtr->getCopyOf();
96 auto gsystem = gvolumePtr->getSystem();
97 auto volume_copy =
gsystem +
"/" + copyOf;
99 if (copyG4Volume !=
nullptr) { g4volume = copyG4Volume; }
105 if (g4volume ==
nullptr) {
113 if (sensitiveDetectorsMap.find(digitizationName) == sensitiveDetectorsMap.end()) {
114 log->
info(2,
"Creating new sensitive detector <", digitizationName,
"> for volume <", g4name,
">");
116 sensitiveDetectorsMap[digitizationName] =
new GSensitiveDetector(digitizationName, gopt);
118 else {
log->
info(2,
"Sensitive detector <", digitizationName,
"> is already created and available for volume <", g4name,
">"); }
122 const auto& vdimensions = gvolumePtr->getDetectorDimensions();
123 const auto& identity = gvolumePtr->getGIdentity();
124 auto this_gtouchable = std::make_shared<GTouchable>(gopt, digitizationName, identity, vdimensions);
125 sensitiveDetectorsMap[digitizationName]->registerGVolumeTouchable(g4name, this_gtouchable);
128 sdManager->AddNewDetector(sensitiveDetectorsMap[digitizationName]);
129 g4volume->SetSensitiveDetector(sensitiveDetectorsMap[digitizationName]);
130 log->
info(2,
"Logical Volume <" + g4name +
"> has been successfully assigned to SD.", sensitiveDetectorsMap[digitizationName]);
136 const auto& field_name = gvolumePtr->getEMField();
138 if (gmagneto ==
nullptr) { gmagneto =
new GMagneto(gopt); }
139 log->
info(2,
"Volume <", volumeName,
"> has field: <", field_name,
">. Looking into field map definitions.");
140 log->
info(2,
"Setting field manager for volume <", g4name,
"> with field <", field_name,
">");
148 loadDigitizationPlugins();
152 for (
auto& sdname : sdetectors) {
153 sensitiveDetectorsMap[sdname]->assign_digi_routine(digitization_routines_map->at(sdname));
154 log->
info(1,
"Digitization routine <" + sdname +
"> has been successfully assigned to SD.", sensitiveDetectorsMap[sdname]);
159void GDetectorConstruction::loadDigitizationPlugins() {
162 for (
auto& sdname : sdetectors) {
163 if (sdname == FLUXNAME) {
164 log->
info(1,
"Loading flux digitization plugin for routine <" + sdname +
">");
165 digitization_routines_map->emplace(sdname, std::make_shared<GFluxDigitization>(gopt));
167 else if (sdname == COUNTERNAME) {
168 log->
info(1,
"Loading particle counter digitization plugin for routine <" + sdname +
">");
169 digitization_routines_map->emplace(sdname, std::make_shared<GParticleCounterDigitization>(gopt));
171 else if (sdname == DOSIMETERNAME) {
172 log->
info(1,
"Loading dosimeter digitization plugin for routine <" + sdname +
">");
173 digitization_routines_map->emplace(sdname, std::make_shared<GDosimeterDigitization>(gopt));
177 log->
info(0,
"Loading new digitization plugin for routine <" + sdname +
">");
182 digitization_routines_map->at(sdname)->set_loggers(gopt);
184 if (digitization_routines_map->at(sdname)->defineReadoutSpecs()) {
log->
info(1,
"Digitization routine <" + sdname +
"> has been successfully defined."); }
185 else {
log->
error(ERR_DEFINESPECFAIL,
"defineReadoutSpecs failure for <" + sdname +
">"); }
198 auto rm = G4RunManager::GetRunManager();
206 else {
log->
error(1,
"GDetectorConstruction::reload_geometry",
"Geant4 Run manager not found."); }
G4VPhysicalVolume * getPhysical() const noexcept
G4LogicalVolume * getLogical() const noexcept
std::size_t number_of_volumes() const noexcept
void setFieldManagerForVolume(const std::string &volumeName, G4FieldManager *fm, bool forceToAllDaughters)
const G4Volume * getG4Volume(const std::string &volumeName) const
std::shared_ptr< GLogger > log
GDetectorConstruction(std::shared_ptr< GOptions > gopts)
Constructs a detector builder configured by the provided options.
void reload_geometry(SystemList sl)
Reloads the geometry using a new list of GSystem objects.
G4VPhysicalVolume * Construct() override
Geant4 geometry construction hook.
void ConstructSDandField() override
Geant4 SD/field construction hook.
void debug(debug_type type, Args &&... args) const
void info(int level, Args &&... args) const
void error(int exit_code, Args &&... args) const
std::shared_ptr< G4FieldManager > getFieldMgr(std::string name)
int get_number_of_volumes() const
std::vector< std::string > getSensitiveDetectorsList()
SystemMap * getSystemsMap() const
Defines the GDetectorConstruction class, the Geant4 detector-construction entry point for the gdetect...
Declares the gdetector module option aggregation entry point.
constexpr const char * GDETECTOR_LOGGER
Logger name used by the gdetector module.
#define ERR_GVOLUMENOTFOUND
#define ROOTWORLDGVOLUMENAME
std::vector< SystemPtr > SystemList
#define UNINITIALIZEDSTRINGQUANTITY
std::shared_ptr< GDynamicDigitization > load_dynamicRoutine(const std::string &plugin_name, const std::shared_ptr< GOptions > &gopts)