15#include "G4SDManager.hh"
16#include "G4RunManager.hh"
17#include "G4Threading.hh"
18#include "G4UserLimits.hh"
19#include "G4VVisManager.hh"
22class GVisManagerGuard :
public G4VVisManager {
24 static void set(G4VVisManager* visManager) { SetConcreteInstance(visManager); }
26 void Draw(
const G4Circle&,
const G4Transform3D&)
override {}
27 void Draw(
const G4Polyhedron&,
const G4Transform3D&)
override {}
28 void Draw(
const G4Polyline&,
const G4Transform3D&)
override {}
29 void Draw(
const G4Polymarker&,
const G4Transform3D&)
override {}
30 void Draw(
const G4Square&,
const G4Transform3D&)
override {}
31 void Draw(
const G4Text&,
const G4Transform3D&)
override {}
32 void Draw2D(
const G4Circle&,
const G4Transform3D&)
override {}
33 void Draw2D(
const G4Polyhedron&,
const G4Transform3D&)
override {}
34 void Draw2D(
const G4Polyline&,
const G4Transform3D&)
override {}
35 void Draw2D(
const G4Polymarker&,
const G4Transform3D&)
override {}
36 void Draw2D(
const G4Square&,
const G4Transform3D&)
override {}
37 void Draw2D(
const G4Text&,
const G4Transform3D&)
override {}
38 void Draw(
const G4VTrajectory&)
override {}
39 void Draw(
const G4VHit&)
override {}
40 void Draw(
const G4VDigi&)
override {}
41 void Draw(
const G4LogicalVolume&,
const G4VisAttributes&,
const G4Transform3D&)
override {}
42 void Draw(
const G4VPhysicalVolume&,
const G4VisAttributes&,
const G4Transform3D&)
override {}
43 void Draw(
const G4VSolid&,
const G4VisAttributes&,
const G4Transform3D&)
override {}
44 void BeginDraw(
const G4Transform3D&)
override {}
45 void EndDraw()
override {}
46 void BeginDraw2D(
const G4Transform3D&)
override {}
47 void EndDraw2D()
override {}
48 void GeometryHasChanged()
override {}
49 void DispatchToModel(
const G4VTrajectory&)
override {}
50 G4bool FilterTrajectory(
const G4VTrajectory&)
override {
return true; }
51 G4bool FilterHit(
const G4VHit&)
override {
return true; }
52 G4bool FilterDigi(
const G4VDigi&)
override {
return true; }
56G4ThreadLocal
GMagneto *GDetectorConstruction::gmagneto =
nullptr;
57G4ThreadLocal std::map<std::string, GSensitiveDetector*>* GDetectorConstruction::tlSDMap =
nullptr;
61 G4VUserDetectorConstruction(),
64 digitization_routines_map = std::make_shared<gdynamicdigitization::dRoutinesMap>();
78 if (gsystems.empty()) {
80 gworld = std::make_shared<GWorld>(gopt);
83 gworld = std::make_shared<GWorld>(gopt, cloneSystemDescriptors(gsystems));
87 g4world = std::make_shared<G4World>(gworld.get(), gopt);
94 nsdetectors,
" sensitive detectors\n");
103 auto sdManager = G4SDManager::GetSDMpointer();
113 tlSDMap =
new std::map<std::string, GSensitiveDetector*>();
115 for (
auto& [name, sd] : *tlSDMap) {
121 std::unordered_map<std::string, GSensitiveDetector *> sensitiveDetectorsMap;
124 for (
const auto &[systemName, gsystemPtr]: *gworld->
getSystemsMap()) {
125 for (
const auto &[volumeName, gvolumePtr]: gsystemPtr->getGVolumesMap()) {
126 auto const &digitizationName = gvolumePtr->getDigitization();
127 auto const &g4name = gvolumePtr->getG4Name();
133 if (g4volume ==
nullptr) {
134 std::string copyOf = gvolumePtr->getCopyOf();
136 auto gsystem = gvolumePtr->getSystem();
137 auto volume_copy =
gsystem +
"/" + copyOf;
139 if (copyG4Volume !=
nullptr) { g4volume = copyG4Volume; }
else {
141 " Logical volume copy <" + volume_copy +
"> not found.");
145 if (g4volume ==
nullptr) {
157 if (sensitiveDetectorsMap.find(digitizationName) == sensitiveDetectorsMap.end()) {
162 auto tlIt = tlSDMap->find(digitizationName);
163 if (tlIt != tlSDMap->end()) {
164 log->
info(2,
"Reusing existing sensitive detector <", digitizationName,
"> for volume <", g4name,
">");
165 tlIt->second->resetTouchableMap();
166 tlIt->second->Activate(
true);
167 sensitiveDetectorsMap[digitizationName] = tlIt->second;
169 log->
info(2,
"Creating new sensitive detector <", digitizationName,
"> for volume <", g4name,
">");
171 sdManager->AddNewDetector(newSD);
172 sensitiveDetectorsMap[digitizationName] = newSD;
173 (*tlSDMap)[digitizationName] = newSD;
176 log->
info(2,
"Sensitive detector <", digitizationName,
177 "> is already created and available for volume <", g4name,
">");
182 const auto &vdimensions = gvolumePtr->getDetectorDimensions();
183 const auto &identity = gvolumePtr->getGIdentity();
184 const auto &mass = g4volume->GetMass();
185 auto this_gtouchable = std::make_shared<
186 GTouchable>(gopt, digitizationName, identity, vdimensions, mass);
187 sensitiveDetectorsMap[digitizationName]->registerGVolumeTouchable(g4name, this_gtouchable);
190 g4volume->SetSensitiveDetector(sensitiveDetectorsMap[digitizationName]);
196 log->
info(2,
"Logical Volume <" + g4name +
"> has been successfully assigned to SD.",
197 sensitiveDetectorsMap[digitizationName]);
203 const auto &field_name = gvolumePtr->getEMField();
205 if (gmagneto ==
nullptr) { gmagneto =
new GMagneto(gopt); }
206 log->
info(2,
"Volume <", volumeName,
"> has field: <", field_name,
207 ">. Looking into field map definitions.");
208 log->
info(2,
"Setting field manager for volume <", g4name,
"> with field <", field_name,
">");
218 if (G4Threading::IsMasterThread() && digiplugins_need_reload) {
219 loadDigitizationPlugins();
220 digiplugins_need_reload =
false;
225 for (
auto &sdname: sdetectors) {
226 auto digitization_routine = digitization_routines_map->at(sdname);
227 double maxStep = digitization_routine->readoutSpecs->getMaxStep();
229 sensitiveDetectorsMap[sdname]->assign_digi_routine(digitization_routine);
230 log->
info(1,
"Digitization routine <" + sdname +
"> has been successfully assigned to SD.",
231 sensitiveDetectorsMap[sdname]);
235 for (
const auto &[systemName, gsystemPtr]: *gworld->
getSystemsMap()) {
236 for (
const auto &[volumeName, gvolumePtr]: gsystemPtr->getGVolumesMap()) {
237 auto const &digitizationName = gvolumePtr->getDigitization();
238 if (digitizationName == sdname) {
239 auto const &g4name = gvolumePtr->getG4Name();
244 g4volume->SetUserLimits(
new G4UserLimits(maxStep));
246 log->
info(1,
"Setting G4UserLimits for volume <", g4name,
"> with maxStep <", maxStep,
">");
254void GDetectorConstruction::loadDigitizationPlugins() {
258 digitization_routines_map->clear();
263 const std::string digiVariationOverride = gopt->
getScalarString(
"digitization_variation");
267 std::map<std::string, std::string> systemVariationFor;
268 for (
const auto& [systemName, gsystemPtr] : *gworld->getSystemsMap()) {
269 for (
const auto& [volumeName, gvolumePtr] : gsystemPtr->getGVolumesMap()) {
270 const auto& digiName = gvolumePtr->getDigitization();
271 if (digiName !=
"" && digiName != UNINITIALIZEDSTRINGQUANTITY) {
272 systemVariationFor.emplace(digiName, gsystemPtr->getVariation());
279 for (
auto &sdname: sdetectors) {
280 if (sdname == FLUXNAME) {
281 log->
info(1,
"Loading flux digitization plugin for routine <" + sdname +
">");
282 digitization_routines_map->emplace(sdname, std::make_shared<GFluxDigitization>(gopt));
283 }
else if (sdname == GPHOTON_DETECTORNAME) {
284 log->
info(1,
"Loading gPhotonDetector digitization plugin for routine <" + sdname +
">");
285 digitization_routines_map->emplace(sdname, std::make_shared<GPhotonDetectorDigitization>(gopt));
286 }
else if (sdname == COUNTERNAME) {
287 log->
info(1,
"Loading particle counter digitization plugin for routine <" + sdname +
">");
288 digitization_routines_map->emplace(sdname, std::make_shared<GParticleCounterDigitization>(gopt));
289 }
else if (sdname == DOSIMETERNAME) {
290 log->
info(1,
"Loading dosimeter digitization plugin for routine <" + sdname +
">");
291 digitization_routines_map->emplace(sdname, std::make_shared<GDosimeterDigitization>(gopt));
294 log->
info(0,
"Loading new digitization plugin for routine <" + sdname +
">");
299 digitization_routines_map->at(sdname)->set_loggers(gopt);
303 std::string variation =
"default";
304 if (
const auto it = systemVariationFor.find(sdname); it != systemVariationFor.end()) {
305 variation = it->second;
307 if (overrideVariation) { variation = digiVariationOverride; }
308 digitization_routines_map->at(sdname)->setDigitizationVariation(variation);
310 if (digitization_routines_map->at(sdname)->defineReadoutSpecs()) {
311 log->
info(1,
"Digitization routine <" + sdname +
"> has been successfully defined.");
312 }
else {
log->
error(ERR_DEFINESPECFAIL,
"defineReadoutSpecs failure for <" + sdname +
">"); }
319 descriptors.reserve(systems.size());
321 for (
const auto& system: systems) {
322 if (system !=
nullptr) {
323 descriptors.emplace_back(system->descriptorClone(gopt));
333 digiplugins_need_reload =
true;
337 gsystems = cloneSystemDescriptors(sl);
342 auto rm = G4RunManager::GetRunManager();
349 auto* visManager = G4VVisManager::GetConcreteInstance();
350 GVisManagerGuard::set(
nullptr);
352 GVisManagerGuard::set(visManager);
354 }
else {
log->
error(1,
"GDetectorConstruction::reload_geometry",
"Geant4 Run manager not found."); }
358 auto rm = G4RunManager::GetRunManager();
361 auto* visManager = G4VVisManager::GetConcreteInstance();
362 GVisManagerGuard::set(
nullptr);
364 digiplugins_need_reload =
true;
365 rm->ReinitializeGeometry(
true,
true);
366 rm->GeometryHasBeenModified();
371 rm->PhysicsHasBeenModified();
373 GVisManagerGuard::set(visManager);
374 }
else {
log->
error(1,
"GDetectorConstruction::prepare_geometry_for_run",
"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 prepare_geometry_for_run()
Reinitializes geometry through Geant4 before running events.
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)
std::string getScalarString(const std::string &tag) const
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)