14#include "G4SDManager.hh"
15#include "G4GeometryManager.hh"
16#include "G4SolidStore.hh"
17#include "G4LogicalVolumeStore.hh"
18#include "G4PhysicalVolumeStore.hh"
19#include "G4ReflectionFactory.hh"
20#include "G4RunManager.hh"
21#include "G4UserLimits.hh"
23G4ThreadLocal
GMagneto *GDetectorConstruction::gmagneto =
nullptr;
27 G4VUserDetectorConstruction(),
30 digitization_routines_map = std::make_shared<gdynamicdigitization::dRoutinesMap>();
39 G4GeometryManager::GetInstance()->OpenGeometry();
40 G4PhysicalVolumeStore::Clean();
41 G4LogicalVolumeStore::Clean();
42 G4SolidStore::Clean();
43 G4ReflectionFactory::Instance()->Clean();
52 if (gsystems.empty()) {
54 gworld = std::make_shared<GWorld>(gopt);
57 gworld = std::make_shared<GWorld>(gopt, gsystems);
61 g4world = std::make_shared<G4World>(gworld.get(), gopt);
68 nsdetectors,
" sensitive detectors\n");
77 auto sdManager = G4SDManager::GetSDMpointer();
83 std::unordered_map<std::string, GSensitiveDetector *> sensitiveDetectorsMap;
86 for (
const auto &[systemName, gsystemPtr]: *gworld->
getSystemsMap()) {
87 for (
const auto &[volumeName, gvolumePtr]: gsystemPtr->getGVolumesMap()) {
88 auto const &digitizationName = gvolumePtr->getDigitization();
89 auto const &g4name = gvolumePtr->getG4Name();
95 if (g4volume ==
nullptr) {
96 std::string copyOf = gvolumePtr->getCopyOf();
98 auto gsystem = gvolumePtr->getSystem();
99 auto volume_copy =
gsystem +
"/" + copyOf;
101 if (copyG4Volume !=
nullptr) { g4volume = copyG4Volume; }
else {
103 " Logical volume copy <" + volume_copy +
"> not found.");
107 if (g4volume ==
nullptr) {
114 if (sensitiveDetectorsMap.find(digitizationName) == sensitiveDetectorsMap.end()) {
115 log->
info(2,
"Creating new sensitive detector <", digitizationName,
"> for volume <", g4name,
">");
117 sensitiveDetectorsMap[digitizationName] =
new GSensitiveDetector(digitizationName, gopt);
119 log->
info(2,
"Sensitive detector <", digitizationName,
120 "> is already created and available for volume <", g4name,
">");
125 const auto &vdimensions = gvolumePtr->getDetectorDimensions();
126 const auto &identity = gvolumePtr->getGIdentity();
127 const auto &mass = g4volume->GetMass();
128 auto this_gtouchable = std::make_shared<
129 GTouchable>(gopt, digitizationName, identity, vdimensions, mass);
130 sensitiveDetectorsMap[digitizationName]->registerGVolumeTouchable(g4name, this_gtouchable);
133 sdManager->AddNewDetector(sensitiveDetectorsMap[digitizationName]);
134 g4volume->SetSensitiveDetector(sensitiveDetectorsMap[digitizationName]);
140 log->
info(2,
"Logical Volume <" + g4name +
"> has been successfully assigned to SD.",
141 sensitiveDetectorsMap[digitizationName]);
147 const auto &field_name = gvolumePtr->getEMField();
149 if (gmagneto ==
nullptr) { gmagneto =
new GMagneto(gopt); }
150 log->
info(2,
"Volume <", volumeName,
"> has field: <", field_name,
151 ">. Looking into field map definitions.");
152 log->
info(2,
"Setting field manager for volume <", g4name,
"> with field <", field_name,
">");
160 loadDigitizationPlugins();
164 for (
auto &sdname: sdetectors) {
165 auto digitization_routine = digitization_routines_map->at(sdname);
166 double maxStep = digitization_routine->readoutSpecs->getMaxStep();
168 sensitiveDetectorsMap[sdname]->assign_digi_routine(digitization_routine);
169 log->
info(1,
"Digitization routine <" + sdname +
"> has been successfully assigned to SD.",
170 sensitiveDetectorsMap[sdname]);
174 for (
const auto &[systemName, gsystemPtr]: *gworld->
getSystemsMap()) {
175 for (
const auto &[volumeName, gvolumePtr]: gsystemPtr->getGVolumesMap()) {
176 auto const &digitizationName = gvolumePtr->getDigitization();
177 if (digitizationName == sdname) {
178 auto const &g4name = gvolumePtr->getG4Name();
183 g4volume->SetUserLimits(
new G4UserLimits(maxStep));
185 log->
info(1,
"Setting G4UserLimits for volume <", g4name,
"> with maxStep <", maxStep,
">");
193void GDetectorConstruction::loadDigitizationPlugins() {
196 for (
auto &sdname: sdetectors) {
197 if (sdname == FLUXNAME) {
198 log->
info(1,
"Loading flux digitization plugin for routine <" + sdname +
">");
199 digitization_routines_map->emplace(sdname, std::make_shared<GFluxDigitization>(gopt));
200 }
else if (sdname == COUNTERNAME) {
201 log->
info(1,
"Loading particle counter digitization plugin for routine <" + sdname +
">");
202 digitization_routines_map->emplace(sdname, std::make_shared<GParticleCounterDigitization>(gopt));
203 }
else if (sdname == DOSIMETERNAME) {
204 log->
info(1,
"Loading dosimeter digitization plugin for routine <" + sdname +
">");
205 digitization_routines_map->emplace(sdname, std::make_shared<GDosimeterDigitization>(gopt));
208 log->
info(0,
"Loading new digitization plugin for routine <" + sdname +
">");
213 digitization_routines_map->at(sdname)->set_loggers(gopt);
215 if (digitization_routines_map->at(sdname)->defineReadoutSpecs()) {
216 log->
info(1,
"Digitization routine <" + sdname +
"> has been successfully defined.");
217 }
else {
log->
error(ERR_DEFINESPECFAIL,
"defineReadoutSpecs failure for <" + sdname +
">"); }
230 auto rm = G4RunManager::GetRunManager();
237 }
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)