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);
58 gworld = std::make_shared<GWorld>(gopt, gsystems);
62 g4world = std::make_shared<G4World>(gworld.get(), gopt);
69 nsdetectors,
" sensitive detectors\n");
78 auto sdManager = G4SDManager::GetSDMpointer();
84 std::unordered_map<std::string, GSensitiveDetector*> sensitiveDetectorsMap;
87 for (
const auto& [systemName, gsystemPtr] : *gworld->
getSystemsMap()) {
88 for (
const auto& [volumeName, gvolumePtr] : gsystemPtr->getGVolumesMap()) {
89 auto const& digitizationName = gvolumePtr->getDigitization();
90 auto const& g4name = gvolumePtr->getG4Name();
96 if (g4volume ==
nullptr) {
97 std::string copyOf = gvolumePtr->getCopyOf();
99 auto gsystem = gvolumePtr->getSystem();
100 auto volume_copy =
gsystem +
"/" + copyOf;
102 if (copyG4Volume !=
nullptr) { g4volume = copyG4Volume; }
105 " Logical volume copy <" + volume_copy +
"> not found.");
109 if (g4volume ==
nullptr) {
116 if (sensitiveDetectorsMap.find(digitizationName) == sensitiveDetectorsMap.end()) {
117 log->
info(2,
"Creating new sensitive detector <", digitizationName,
"> for volume <", g4name,
">");
119 sensitiveDetectorsMap[digitizationName] =
new GSensitiveDetector(digitizationName, gopt);
122 log->
info(2,
"Sensitive detector <", digitizationName,
123 "> is already created and available for volume <", g4name,
">");
128 const auto& vdimensions = gvolumePtr->getDetectorDimensions();
129 const auto& identity = gvolumePtr->getGIdentity();
130 const auto& mass = g4volume->GetMass();
131 auto this_gtouchable = std::make_shared<
132 GTouchable>(gopt, digitizationName, identity, vdimensions, mass);
133 sensitiveDetectorsMap[digitizationName]->registerGVolumeTouchable(g4name, this_gtouchable);
136 sdManager->AddNewDetector(sensitiveDetectorsMap[digitizationName]);
137 g4volume->SetSensitiveDetector(sensitiveDetectorsMap[digitizationName]);
143 log->
info(2,
"Logical Volume <" + g4name +
"> has been successfully assigned to SD.",
144 sensitiveDetectorsMap[digitizationName]);
150 const auto& field_name = gvolumePtr->getEMField();
152 if (gmagneto ==
nullptr) { gmagneto =
new GMagneto(gopt); }
153 log->
info(2,
"Volume <", volumeName,
"> has field: <", field_name,
154 ">. Looking into field map definitions.");
155 log->
info(2,
"Setting field manager for volume <", g4name,
"> with field <", field_name,
">");
163 loadDigitizationPlugins();
167 for (
auto& sdname : sdetectors) {
168 auto digitization_routine = digitization_routines_map->at(sdname);
169 double maxStep = digitization_routine->readoutSpecs->getMaxStep();
171 sensitiveDetectorsMap[sdname]->assign_digi_routine(digitization_routine);
172 log->
info(1,
"Digitization routine <" + sdname +
"> has been successfully assigned to SD.",
173 sensitiveDetectorsMap[sdname]);
177 for (
const auto& [systemName, gsystemPtr] : *gworld->
getSystemsMap()) {
178 for (
const auto& [volumeName, gvolumePtr] : gsystemPtr->getGVolumesMap()) {
179 auto const& digitizationName = gvolumePtr->getDigitization();
180 if (digitizationName == sdname) {
181 auto const& g4name = gvolumePtr->getG4Name();
186 g4volume->SetUserLimits(
new G4UserLimits(maxStep));
188 log->
info(1,
"Setting G4UserLimits for volume <", g4name,
"> with maxStep <", maxStep,
">");
197void GDetectorConstruction::loadDigitizationPlugins() {
200 for (
auto& sdname : sdetectors) {
201 if (sdname == FLUXNAME) {
202 log->
info(1,
"Loading flux digitization plugin for routine <" + sdname +
">");
203 digitization_routines_map->emplace(sdname, std::make_shared<GFluxDigitization>(gopt));
205 else if (sdname == COUNTERNAME) {
206 log->
info(1,
"Loading particle counter digitization plugin for routine <" + sdname +
">");
207 digitization_routines_map->emplace(sdname, std::make_shared<GParticleCounterDigitization>(gopt));
209 else if (sdname == DOSIMETERNAME) {
210 log->
info(1,
"Loading dosimeter digitization plugin for routine <" + sdname +
">");
211 digitization_routines_map->emplace(sdname, std::make_shared<GDosimeterDigitization>(gopt));
215 log->
info(0,
"Loading new digitization plugin for routine <" + sdname +
">");
220 digitization_routines_map->at(sdname)->set_loggers(gopt);
222 if (digitization_routines_map->at(sdname)->defineReadoutSpecs()) {
223 log->
info(1,
"Digitization routine <" + sdname +
"> has been successfully defined.");
225 else {
log->
error(ERR_DEFINESPECFAIL,
"defineReadoutSpecs failure for <" + sdname +
">"); }
238 auto rm = G4RunManager::GetRunManager();
246 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)