Geant4 VMC Version 6.8
Loading...
Searching...
No Matches
TG4GeometryManager.cxx
Go to the documentation of this file.
1//------------------------------------------------
2// The Geant4 Virtual Monte Carlo package
3// Copyright (C) 2007 - 2015 Ivana Hrivnacova
4// All rights reserved.
5//
6// For the licensing terms see geant4_vmc/LICENSE.
7// Contact: root-vmc@cern.ch
8//-------------------------------------------------
9
14
15#include "TG4GeometryManager.h"
16#include "TG4BiasingManager.h"
17#include "TG4Field.h"
18#include "TG4MagneticField.h"
19#include "TG4G3ControlVector.h"
20#include "TG4G3CutVector.h"
21#include "TG4G3Units.h"
22#include "TG4GeometryServices.h"
23#include "TG4Globals.h"
24#include "TG4Limits.h"
25#include "TG4MCGeometry.h"
26#include "TG4Medium.h"
27#include "TG4MediumMap.h"
31#include "TG4SDManager.h"
32#include "TG4StateManager.h"
35
36#ifdef USE_G4ROOT
37#include "TG4RootDetectorConstruction.h"
38#endif
39
40#include <G4FieldManager.hh>
41#include <G4FieldBuilder.hh>
42#include <G4FieldParameters.hh>
43#include <G4LogicalVolumeStore.hh>
44#include <G4Material.hh>
46#include <G4PVPlacement.hh>
47//#include <G4SystemOfUnits.hh>
48#include <G4TransportationManager.hh>
49
50#include <TGeoMCGeometry.h>
51#include <TGeoManager.h>
52#include <TGeoMedium.h>
53#include <TGeoVolume.h>
54#include <TList.h>
55#include <TVirtualMC.h>
56#include <TVirtualMCApplication.h>
57
58// Moved after ROOT includes to avoid warnings about shadowing variables
59// from CLHEP units
60#include <G4SystemOfUnits.hh>
61
62#ifdef USE_G3TOG4
63#include <G3MatTable.hh>
64#include <G3MedTable.hh>
65#include <G3SensVolVector.hh>
66#include <G3VolTable.hh>
67#include <G3toG4.hh>
68#include <G3toG4BuildTree.hh>
69#include <G3toG4MANY.hh>
70#endif
71
72#ifdef USE_VGM
73#include <Geant4GM/volumes/Factory.h>
74#include <RootGM/volumes/Factory.h>
75#endif
76
78const G4double TG4GeometryManager::fgDefaultLimitDensity = 0.001 * (g / cm3);
79const G4double TG4GeometryManager::fgDefaultMaxStep = 10 * cm;
80
81G4ThreadLocal std::vector<TG4Field*>* TG4GeometryManager::fgFields = 0;
82
83//_____________________________________________________________________________
84TG4GeometryManager::TG4GeometryManager(const TString& userGeometry)
85 : TG4Verbose("geometryManager"),
86 fMessenger(this),
88 fMCGeometry(0),
90 fOpManager(0),
94 fUserGeometry(userGeometry),
97 fIsLocalField(false),
98 fIsZeroField(false),
99 fIsMonopoleField(false),
100 fIsUserMaxStep(false),
104
105{
107
108 if (fgInstance) {
109 TG4Globals::Exception("TG4GeometryManager",
110 "TG4GeometryManager:", "Cannot create two instances of singleton.");
111 }
112
113 // Geant4 field builder, it creates field parameters for global field
114 G4FieldBuilder::Instance();
115
117
119
120 fFastModelsManager = new TG4ModelConfigurationManager("fastSimulation");
122 fBiasingManager = new TG4BiasingManager("biasing");
123
124 fgInstance = this;
125}
126
127//_____________________________________________________________________________
129{
131
132 delete fgFields;
133 // magnetic field objects are deleted via G4 kernel
134
135 delete fGeometryServices;
136 delete fOpManager;
137 delete fFastModelsManager;
138 delete fEmModelsManager;
139 delete fBiasingManager;
140
141 fgInstance = 0;
142 fgFields = 0;
143}
144
145//
146// private methods
147//
148
149//_____________________________________________________________________________
151{
153
154 if (fUserGeometry == "VMCtoGeant4" || fUserGeometry == "Geant4" ||
155 fUserGeometry == "RootToGeant4") {
157 }
158
159 if (fUserGeometry == "VMCtoRoot" || fUserGeometry == "Root" ||
160 fUserGeometry == "VMC+RootToGeant4") {
161 if (!gGeoManager) new TGeoManager("TGeo", "Root geometry manager");
162 fMCGeometry = new TGeoMCGeometry();
163 }
164}
165
166//_____________________________________________________________________________
168{
170
171#ifdef USE_G3TOG4
172 if (VerboseLevel() > 1)
173 G4cout << "TG4GeometryManager::ConstructG4GeometryViaVMC" << G4endl;
174
175 // check if G4 tables were filled
176 /*
177 if ( ! TG4G3MCGeometry::Instance()->IsGeometryDefined() ) {
178 TG4Globals::Exception(
179 "TG4GeometryManager", "ConstructG4GeometryViaVMC",
180 "Geometry was not defined via VMC.");
181 }
182 */
183 // pass info about using G3toG4 to geometry services
184 fGeometryServices->SetIsG3toG4(true);
185
186 // set the first entry in the G3Vol table
187 G4ggclos();
188 G3VolTableEntry* first = G3Vol.GetFirstVTE();
189
190 // transform MANY to Boolean solids
191 G3toG4MANY(first);
192
193 // create G4 geometry
194 G3toG4BuildTree(first, 0);
195
196 // fill medium map
197 // FillMediumMapFromG3();
198
199 // position the first entry with copyNo = 1
200 // (in Geant3 the top volume cannot be positioned)
201 //
202 if (!fGeometryServices->GetWorld()) {
203 G4VPhysicalVolume* world = new G4PVPlacement(
204 0, G4ThreeVector(), first->GetName(), first->GetLV(), 0, false, 1);
205 fGeometryServices->SetWorld(world);
206 }
207
208 // print G3 volume table statistics
209 G3Vol.VTEStat();
210
211#else
212 TG4Globals::Exception("TG4GeometryManager", "ConstructG4GeometryViaVMC",
213 "Geant4 VMC has been installed without G3toG4." + TG4Globals::Endl() +
214 "Geometry construction via VMC is not supported.");
215#endif
216}
217
218//_____________________________________________________________________________
220{
223
224#ifdef USE_VGM
225 if (VerboseLevel() > 1)
226 G4cout << "TG4GeometryManager::ConstructG4GeometryViaVGM" << G4endl;
227
228 // Check Root manager
229 if (!gGeoManager) {
230 TG4Globals::Exception("TG4GeometryManager", "ConstructG4GeometryViaVGM",
231 "Geometry was not defined via Root.");
232 }
233
234 // Get and eventually also set the Root top volume
235 TGeoVolume* topVolume = gGeoManager->GetTopVolume();
236 if (!topVolume) {
237 topVolume = (TGeoVolume*)gGeoManager->GetListOfVolumes()->First();
238 if (!topVolume) {
239 TG4Globals::Exception("TG4GeometryManager", "ConstructG4GeometryViaVGM",
240 "Root top volume not found.");
241 }
242 gGeoManager->SetTopVolume(topVolume);
243 }
244
245 // Close Root geometry
246 if (!gGeoManager->IsClosed()) gGeoManager->CloseGeometry();
247
248 // Convert Root geometry to G4
249 if (VerboseLevel() > 0)
250 G4cout << "Converting Root geometry to Geant4 via VGM ... " << G4endl;
251
252 // import Root geometry in VGM
253 RootGM::Factory rootFactory;
254 if (VerboseLevel() > 1) rootFactory.SetDebug(1);
255 rootFactory.SetIgnore(true);
256 rootFactory.Import(gGeoManager->GetTopNode());
257
258 // export Root VGM geometry in Geant4
259 Geant4GM::Factory g4Factory;
260 if (VerboseLevel() > 1) g4Factory.SetDebug(1);
261 rootFactory.Export(&g4Factory);
262
263 G4VPhysicalVolume* g4World = g4Factory.World();
264 fGeometryServices->SetWorld(g4World);
265
266#else
267 TG4Globals::Exception("TG4GeometryManager", "ConstructG4GeometryViaVGM",
268 "Geant4 VMC has been installed without VGM." + TG4Globals::Endl() +
269 "Root geometry conversion is not supported.");
270#endif
271}
272
273//_____________________________________________________________________________
275{
277
278 if (VerboseLevel() > 1) {
279 G4cout << "TG4GeometryManager::ConstructG4Geometry: "
280 << "userGeometry=" << fUserGeometry << G4endl;
281 }
282
283 // VMC application construct geometry
284 if (fUserGeometry == "VMCtoGeant4") {
285
286 if (VerboseLevel() > 1)
287 G4cout << "Running TVirtualMCApplication::ConstructGeometry" << G4endl;
288
290 TVirtualMCApplication::Instance()->ConstructGeometry();
292 TVirtualMCApplication::Instance()->MisalignGeometry();
294 }
295
296 // VMC application construct geometry
297 if (fUserGeometry == "RootToGeant4" || fUserGeometry == "VMC+RootToGeant4") {
298 if (VerboseLevel() > 1)
299 G4cout << "Running TVirtualMCApplication::ConstructGeometry" << G4endl;
300
301#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 22, 8)
302 // Set Root default units to TGeo
303 TGeoManager::LockDefaultUnits(false);
304 TGeoManager::SetDefaultUnits(TGeoManager::kRootUnits);
305 TGeoManager::LockDefaultUnits(true);
306#endif
307
309 TVirtualMCApplication::Instance()->ConstructGeometry();
311
312 // If Root geometry was not closed by user
313 // we have to do it here
314 if (!gGeoManager->IsClosed()) {
315 TGeoVolume* top = (TGeoVolume*)gGeoManager->GetListOfVolumes()->First();
316 gGeoManager->SetTopVolume(top);
317 gGeoManager->CloseGeometry();
318 }
319
321 TVirtualMCApplication::Instance()->MisalignGeometry();
323 }
324
325 // Build G4 geometry
326 if (fUserGeometry == "VMCtoGeant4") ConstructG4GeometryViaVMC();
327
328 if (fUserGeometry == "RootToGeant4" || fUserGeometry == "VMC+RootToGeant4")
330
331 // print G4 geometry statistics
332 if (VerboseLevel() > 0) {
333 G4cout << "G4 Stat: instantiated "
334 << fGeometryServices->NofG4LogicalVolumes() << " logical volumes \n"
335 << " "
336 << fGeometryServices->NofG4PhysicalVolumes() << " physical volumes"
337 << G4endl;
338 }
339}
340
341//_____________________________________________________________________________
343{
345
346#ifdef USE_G3TOG4
347 if (VerboseLevel() > 1)
348 G4cout << "TG4GeometryManager::FillMediumMapFromG3()" << G4endl;
349
350 TG4MediumMap* mediumMap = fGeometryServices->GetMediumMap();
351
352 // Create medium for each medium entry
353 for (G4int i = 0; i < G4int(G3Med.GetSize()); i++) {
354 G3MedTableEntry* mediumEntry = G3Med.GetMTE(i);
355 G4int mediumID = mediumEntry->GetID();
356
357 if (VerboseLevel() > 2) {
358 G4cout << "Getting medium ID=" << mediumID << G4endl;
359 }
360 // Get medium from medium map
361 TG4Medium* medium = mediumMap->GetMedium(mediumID);
362
363 // Create a medium if it does not exist
364 // (This should not happen, but let's check it anyway)
365 if (!medium) {
366 medium = mediumMap->AddMedium(mediumID, false);
367
368 TString message = "Medium ";
369 message += mediumID;
370 message += " was not found in medium map. New medium will be created";
371 TG4Globals::Warning("TG4GeometryManager", "FillMediumMapFromG3", message);
372 }
373
374 medium->SetLimits(mediumEntry->GetLimits());
375 medium->SetMaterial(mediumEntry->GetMaterial());
376 }
377
378 if (VerboseLevel() > 2) G3Vol.PrintAll();
379
380 // Map media to logical volumes
381 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
382 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
383 G4LogicalVolume* lv = (*lvStore)[i];
384
385 // Get medium ID from G3 tables
386 G4String name = lv->GetName();
387 G4String g3Name = fGeometryServices->UserVolumeName(lv);
388 G4int mediumID = G3Vol.GetVTE(g3Name)->GetNmed();
389
390 if (VerboseLevel() > 2)
391 G4cout << "Mapping medium Id " << mediumID << " to LV " << name << G4endl;
392
393 // Map medium to LV
394 mediumMap->MapMedium(lv, mediumID);
395 }
396
397 // clear G3 tables
398 G3Vol.Clear();
399 G3SensVol.clear();
400 G3Mat.Clear();
401 G3Med.Clear();
402#else
403 TG4Globals::Exception("TG4GeometryManager", "FillMediumMapFromG3",
404 "Geant4 VMC has been installed without G3toG4." + TG4Globals::Endl() +
405 "Geometry construction via VMC is not supported.");
406#endif
407}
408
409//_____________________________________________________________________________
411{
414
415 if (VerboseLevel() > 1)
416 G4cout << "TG4GeometryManager::FillMediumMapFromG4()" << G4endl;
417
418 TG4MediumMap* mediumMap = fGeometryServices->GetMediumMap();
419
420 // Create medium for each material
421 const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
422 for (G4int i = 0; i < G4int(materialTable->size()); i++) {
423 G4Material* material = (*materialTable)[i];
424
425 if (VerboseLevel() > 2) {
426 G4cout << "Adding medium name= " << material->GetName()
427 << " Id=" << material->GetIndex() << G4endl;
428 }
429 TG4Medium* medium = mediumMap->AddMedium(material->GetIndex());
430 medium->SetName(material->GetName());
431 medium->SetMaterial(material);
432 }
433
434 // Map media to logical volumes
435 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
436 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
437 G4LogicalVolume* lv = (*lvStore)[i];
438 G4int mediumID = lv->GetMaterial()->GetIndex();
439
440 if (VerboseLevel() > 2) {
441 G4cout << "Mapping medium Id=" << mediumID << " to LV= " << lv->GetName()
442 << G4endl;
443 }
444 mediumMap->MapMedium(lv, mediumID);
445 }
446}
447
448//_____________________________________________________________________________
450{
452
453 if (VerboseLevel() > 1)
454 G4cout << "TG4GeometryManager::FillMediumMapFromRoot()" << G4endl;
455
456 // fGeometryServices->PrintLogicalVolumeStore();
457
458 TG4MediumMap* mediumMap = fGeometryServices->GetMediumMap();
459
460 // Create TG4 medium for each TGeo madium
461 TIter next(gGeoManager->GetListOfMedia());
462 TGeoMedium* geoMedium;
463 while ((geoMedium = (TGeoMedium*)next())) {
464 Int_t mediumId = geoMedium->GetId();
465 G4String mediumName = geoMedium->GetName();
466
467 // Int_t isvol = (Int_t) geoMedium->GetParam(0);
468 Int_t ifield = (Int_t)geoMedium->GetParam(1);
469 // Double_t fieldm = geoMedium->GetParam(2);
470 // Double_t tmaxfd = geoMedium->GetParam(3);
471 Double_t stemax = geoMedium->GetParam(4);
472 // Double_t deemax = geoMedium->GetParam(5);
473 // Double_t epsil = geoMedium->GetParam(6);
474 // Double_t stmin = geoMedium->GetParam(7);
475
476 // Only stemax parameter is passed to G4 if it is positive
477 G4UserLimits* limits = 0;
478 if (stemax > 0) {
479 limits = new G4UserLimits();
480 limits->SetMaxAllowedStep(stemax * cm);
481 }
482
483 if (VerboseLevel() > 2) {
484 G4cout << "Adding medium Id=" << mediumId << " name=" << mediumName
485 << " limits=" << limits << G4endl;
486 }
487 TG4Medium* medium = mediumMap->AddMedium(mediumId);
488 medium->SetName(mediumName);
489 medium->SetLimits(limits);
490 medium->SetIfield(ifield);
491
492 G4String matName = geoMedium->GetMaterial()->GetName();
493 G4Material* material = G4Material::GetMaterial(matName);
494 if (!material) {
495 TG4Globals::Exception("TG4GeometryManager", "FillMediumMapFromRoot",
496 "Material " + TString(matName) + " not found.");
497 }
498 medium->SetMaterial(material);
499 }
500
501 // Map media to logical volumes
502 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
503 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
504 G4LogicalVolume* lv = (*lvStore)[i];
505
506 TGeoVolume* geoVolume = nullptr;
507
508 if (fRootDetectorConstruction == nullptr) {
509 const G4String& volName = fGeometryServices->GetConstituentVolumeName(lv);
510
511 geoVolume = gGeoManager->GetVolume(volName.data());
512 }
513 else {
514#ifdef USE_G4ROOT
515 geoVolume = fRootDetectorConstruction->GetVolume(lv);
516#endif
517 }
518
519 if (!geoVolume) {
520 TG4Globals::Exception("TG4GeometryManager", "FillMediumMapFromRoot",
521 "Root volume " + TString(lv->GetName()) + " not found");
522 }
523
524 // skip assemblies
525 if (geoVolume && geoVolume->IsAssembly()) continue;
526
527 if (geoVolume && !geoVolume->GetMedium()) {
528 TG4Globals::Exception("TG4GeometryManager", "FillMediumMapFromRoot",
529 "Root volume " + TString(lv->GetName()) + " has not medium defined.");
530 }
531
532 G4int mediumID = geoVolume->GetMedium()->GetId();
533
534 if (VerboseLevel() > 2) {
535 G4cout << "Mapping medium Id=" << mediumID << " to LV=" << lv->GetName()
536 << G4endl;
537 }
538 mediumMap->MapMedium(lv, mediumID);
539 }
540}
541
542//_____________________________________________________________________________
544{
546
547 if (fUserGeometry == "VMCtoGeant4") FillMediumMapFromG3();
548
549 if (fUserGeometry == "VMCtoRoot" || fUserGeometry == "Root" ||
550 fUserGeometry == "RootToGeant4" || fUserGeometry == "VMC+RootToGeant4") {
552 }
553
554 if (fUserGeometry == "Geant4") FillMediumMapFromG4();
555}
556
557//_____________________________________________________________________________
558void TG4GeometryManager::CreateField(TVirtualMagField* magField,
559 G4FieldParameters* fieldParameters, G4LogicalVolume* lv)
560{
562
563 TG4Field* tg4Field = new TG4Field(*fieldParameters, magField, lv);
564
565 if (VerboseLevel() > 0) {
566 G4String lvName;
567 if (lv != nullptr) lvName = lv->GetName();
568 auto fieldParameters = G4FieldBuilder::Instance()->GetFieldParameters(lvName);
569 G4String fieldType =
570 G4FieldParameters::FieldTypeName(fieldParameters->GetFieldType());
571 G4bool isCachedMagneticField = (fieldParameters->GetConstDistance() > 0.);
572 if (!lv) {
573 fieldType = "Global";
574 }
575 else {
576 fieldType = "Local (in ";
577 fieldType.append(lv->GetName());
578 fieldType.append(")");
579 }
580 if (isCachedMagneticField) {
581 fieldType.append(" cached");
582 }
583
584 G4cout << fieldType << " field created with stepper ";
585 G4cout << G4FieldParameters::StepperTypeName(
586 fieldParameters->GetStepperType())
587 << G4endl;
588 }
589
590 // create magnetic field vector
591 if (!fgFields) {
592 fgFields = new std::vector<TG4Field*>();
593 }
594
595 fgFields->push_back(tg4Field);
596}
597
598//_____________________________________________________________________________
600{
602
603 if (VerboseLevel() > 1)
604 G4cout << "TG4GeometryManager::ConstructGlobalField()" << G4endl;
605
606 // Create global magnetic field
607 if (gMC->GetMagField()) {
608 auto fieldParameters = G4FieldBuilder::Instance()->GetFieldParameters();
609 CreateField(gMC->GetMagField(), fieldParameters, nullptr);
610
611 // create monopole field
612 if (fIsMonopoleField) {
613 G4cout << "Create G4MonopoleFieldSetup" << G4endl;
614 G4MonopoleFieldSetup* monFieldSetup =
616 TG4Field* tg4Field = (*fgFields)[0];
617 G4Field* field = tg4Field->GetG4Field();
618 G4MagneticField* magField = dynamic_cast<G4MagneticField*>(field);
619 if (!magField) {
620 // add warning
621 G4cerr << "Wrong field type. Only magnetic field is supported in "
622 "G4MonopoleFieldSetup."
623 << G4endl;
624 }
625 else {
626 monFieldSetup->SetMagneticField(magField);
627 // TO DO: Update functions in G4MonopoleFieldSetup
628 // monFieldSetup->SetDefaultEquation(fieldParameters->GetEquationType());
629 // monFieldSetup->SetDefaultStepper(fieldParameters->GetStepperType());
630 monFieldSetup->InitialiseAll();
631 }
632 }
633
634 if (fIsZeroField) {
636 }
637 }
638}
639
640//_____________________________________________________________________________
642{
646
647 if (VerboseLevel() > 1)
648 G4cout << "TG4GeometryManager::ConstructZeroFields()" << G4endl;
649
650 G4bool forceToAllDaughters = false;
651
652 // Set a dummy field manager to all LV first in order to avoid propagation
653 // of zero field to volume daughters
654 G4FieldManager* dummyFieldManager = new G4FieldManager();
655 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
656 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
657 G4LogicalVolume* lv = (*lvStore)[i];
658 lv->SetFieldManager(dummyFieldManager, forceToAllDaughters);
659 }
660
661 // Set zero field manager to volumes associated with a tracking medium
662 // with ifield value = 0.
663 G4FieldManager* fieldManager = 0;
664 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
665
666 G4LogicalVolume* lv = (*lvStore)[i];
667
668 // skip volume without medium
669 TG4Medium* medium =
671 if (!medium) continue;
672
673 // Skip volumes with ifield != 0
674 if (medium->GetIfield() != 0) {
675 if (VerboseLevel() > 2) {
676 G4cout << "Global field in logical volume: " << lv->GetName() << G4endl;
677 }
678 continue;
679 }
680
681 // create field manager if it does not exist yet
682 if (!fieldManager) {
683 fieldManager = new G4FieldManager();
684 // CHECK if we need to delete it
685 fieldManager->SetDetectorField(0);
686 fieldManager->CreateChordFinder(0);
687 }
688 lv->SetFieldManager(fieldManager, forceToAllDaughters);
689
690 if (VerboseLevel() > 1) {
691 G4cout << "Zero magnetic field set to logical volume: " << lv->GetName()
692 << G4endl;
693 }
694 }
695
696 // Remove the dummy field manager to all LV without zero field
697 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
698 G4LogicalVolume* lv = (*lvStore)[i];
699
700 if (lv->GetFieldManager() == dummyFieldManager) {
701 lv->SetFieldManager(0, forceToAllDaughters);
702 }
703 }
704
705 // Delete the dummy field manager
706 delete dummyFieldManager;
707}
708
709//_____________________________________________________________________________
711{
713
714 // Supported only for geomRoot and geomRootToGeant4.
715 if ((fUserGeometry != "Root") && (fUserGeometry != "RootToGeant4")) return;
716
717 if (VerboseLevel() > 1)
718 G4cout << "TG4GeometryManager::ConstructLocalFields()" << G4endl;
719
720 TIter next(gGeoManager->GetListOfVolumes());
721 TGeoVolume* geoVolume;
722 while ((geoVolume = (TGeoVolume*)next())) {
723
724 if (!geoVolume->GetField()) continue;
725
726 // Get field
727 TVirtualMagField* magField =
728 dynamic_cast<TVirtualMagField*>(geoVolume->GetField());
729 if (!magField) {
730 TString message = geoVolume->GetName();
731 message += ": uknown field type will be ignored.";
732 TG4Globals::Warning("TG4GeometryManager", "ConstructLocalFields",
733 "No magnetic field is defined.");
734 continue;
735 }
736
737 // Volume name
738 G4String volumeName = geoVolume->GetName();
739
740 // Get Geant4 volume
741 auto volumes = fGeometryServices->FindLogicalVolumes(volumeName);
742 if (volumes.empty()) {
743 TString message = geoVolume->GetName();
744 message += " volume not found in Geant4 geometry.";
745 TG4Globals::Warning("TG4GeometryManager", "ConstructLocalFields",
746 "No magnetic field is defined.");
747 continue;
748 }
749
750 // G4FieldBuilder indexes parameters by the actual Geant4 name.
751 auto fieldBuilder = G4FieldBuilder::Instance();
752 std::map<G4String, G4FieldParameters*> parameters;
753 for (auto lv : volumes) {
754 auto& fieldParameters = parameters[lv->GetName()];
755 if (!fieldParameters) {
756 fieldParameters = fieldBuilder->CreateFieldParameters(lv->GetName());
757 }
758 CreateField(magField, fieldParameters, lv);
759 }
760 }
761}
762
763//
764// public methods
765//
766
767//_____________________________________________________________________________
769{
772
773 if (!fMCGeometry) {
775 "TG4GeometryManager", "GetMCGeometry", "No MC geometry defined.");
776 }
777
778 return fMCGeometry;
779}
780
781//_____________________________________________________________________________
783{
785
786 // Construct G4 geometry
788 fGeometryServices->BuildConstituentVolumes();
789
790 // Fill medium map
792
793 // Build assembly levels structures
795
796 // VMC application construct geometry for optical processes
798 TVirtualMCApplication::Instance()->ConstructOpGeometry();
800
801 // Construct user regions
803}
804
805#include "TG4SDManager.h"
806
807//_____________________________________________________________________________
809{
811
812 if (VerboseLevel() > 1)
813 G4cout << "TG4GeometryManager::ConstructSDandField() " << G4endl;
814
815 // Call user class for geometry customization
817
818 // Construct regions with fast simulation and EM models
819 fFastModelsManager->CreateRegions();
820 fEmModelsManager->CreateRegions();
821
822 // Construct biasing operator
823 fBiasingManager->CreateBiasingOperator();
824
825 // Initialize SD manager (create SDs)
827
828 // Create global field
830
831 if (fIsLocalField) {
833 }
834
835 // Construct all Geant4 field objects
836 auto fieldBuilder = G4FieldBuilder::Instance();
837 fieldBuilder->ConstructFieldSetup();
838}
839
840//_____________________________________________________________________________
842{
844
845 if (VerboseLevel() > 1)
846 G4cout << "TG4GeometryManager::FinishGeometry" << G4endl;
847
848 // Create magnetic field
849 // ConstructField();
850
851 // Fill medium map if not yet done
852 if (fGeometryServices->GetMediumMap()->GetNofMedia() == 0) FillMediumMap();
853
854 // Set world to geometry services
855 fGeometryServices->SetWorld(
856 G4TransportationManager::GetTransportationManager()
857 ->GetNavigatorForTracking()
858 ->GetWorldVolume());
859
860 if (VerboseLevel() > 1)
861 G4cout << "TG4GeometryManager::FinishGeometry done" << G4endl;
862}
863
864//_____________________________________________________________________________
866 const G4String& volName)
867{
869
870 TG4RadiatorDescription* radiatorDescription =
871 new TG4RadiatorDescription(volName);
872 fRadiators.push_back(radiatorDescription);
873
874 return radiatorDescription;
875}
876
877//_____________________________________________________________________________
879 const TG4G3CutVector& cuts, const TG4G3ControlVector& controls) const
880{
882
883 if (VerboseLevel() > 1)
884 G4cout << "TG4GeometryManager::SetUserLimits" << G4endl;
885
886 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
887
888 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
889 G4LogicalVolume* lv = (*lvStore)[i];
890 TG4Medium* medium = fGeometryServices->GetMediumMap()->GetMedium(lv, false);
891
892 if (!medium) continue;
893
894 // get limits if already exist
895 TG4Limits* tg4Limits = 0;
896 G4UserLimits* limits = medium->GetLimits();
897 tg4Limits = fGeometryServices->GetLimits(limits, cuts, controls);
898
899 // get tracking medium name
900 G4String name = medium->GetName();
901
902 if (tg4Limits) {
903 tg4Limits->SetName(name);
904 }
905 else {
906 // Check if the step below is needed
907 tg4Limits = fGeometryServices->FindLimits2(name, true);
908 if (!tg4Limits) {
909 tg4Limits = new TG4Limits(name, cuts, controls);
910 }
911 }
912
913 // set new limits back to medium
914 medium->SetLimits(tg4Limits);
915
916 // inactivate max step defined by user
917 // if its activation was not asked explicitely
918 if (!fIsUserMaxStep) tg4Limits->SetMaxAllowedStep(DBL_MAX);
919
920 // limit max step for low density materials (< AIR)
922 lv->GetMaterial()->GetDensity() < fLimitDensity)
923 tg4Limits->SetMaxAllowedStep(fMaxStepInLowDensityMaterials);
924
925 // set max step the default value
926 tg4Limits->SetDefaultMaxAllowedStep();
927
928 // update controls in limits according to the setup
929 // in the passed vector
930 tg4Limits->Update(controls);
931
932 // set limits to logical volume
933 lv->SetUserLimits(tg4Limits);
934 }
935
936 if (VerboseLevel() > 1)
937 G4cout << "TG4GeometryManager::SetUserLimits done" << G4endl;
938}
939
940//_____________________________________________________________________________
941void TG4GeometryManager::SetIsLocalField(G4bool isLocalField)
942{
944
945 if (VerboseLevel() > 1)
946 G4cout << "TG4GeometryManager::SetIsLocalField: " << std::boolalpha
947 << isLocalField << G4endl;
948
949 fIsLocalField = isLocalField;
950}
951
952//_____________________________________________________________________________
954{
956
957 if (VerboseLevel() > 1)
958 G4cout << "TG4GeometryManager::SetIsZeroField: " << std::boolalpha
959 << isZeroField << G4endl;
960
961 fIsZeroField = isZeroField;
962}
963
964//_____________________________________________________________________________
965void TG4GeometryManager::SetIsMonopoleField(G4bool isMonopoleField)
966{
968
969 if (VerboseLevel() > 1)
970 G4cout << "TG4GeometryManager::SetIsMonopoleField: " << std::boolalpha
971 << isMonopoleField << G4endl;
972
973 fIsMonopoleField = isMonopoleField;
974}
975
976//_____________________________________________________________________________
977void TG4GeometryManager::SetIsUserMaxStep(G4bool isUserMaxStep)
978{
980
981 if (VerboseLevel() > 0)
982 G4cout << "TG4GeometryManager::SetIsUserMaxStep: " << std::boolalpha
983 << isUserMaxStep << G4endl;
984
985 fIsUserMaxStep = isUserMaxStep;
986}
987
988//_____________________________________________________________________________
990{
992
993 if (VerboseLevel() > 0)
994 G4cout << "TG4GeometryManager::SetIsMaxStepInLowDensityMaterials: "
995 << std::boolalpha << isMaxStep << G4endl;
996
998}
999
1000//_____________________________________________________________________________
1002 TG4VUserRegionConstruction* userRegionConstruction)
1003{
1005
1006 fUserRegionConstruction = userRegionConstruction;
1007}
1008
1009//_____________________________________________________________________________
1011 TG4VUserPostDetConstruction* userPostDetConstruction)
1012{
1014
1015 fUserPostDetConstruction = userPostDetConstruction;
1016}
1017
1018//_____________________________________________________________________________
1020 G4EquationOfMotion* equation, G4String volumeName)
1021{
1022 auto fieldBuilder = G4FieldBuilder::Instance();
1023 fieldBuilder->SetUserEquationOfMotion(equation, volumeName);
1024}
1025
1026//_____________________________________________________________________________
1028 G4MagIntegratorStepper* stepper, G4String volumeName)
1029{
1030 auto fieldBuilder = G4FieldBuilder::Instance();
1031 fieldBuilder->SetUserStepper(stepper, volumeName);
1032}
1033
1034//_____________________________________________________________________________
1036{
1039 if (VerboseLevel() > 0 && fgFields) {
1040 for (G4int i = 0; i < G4int(fgFields->size()); ++i) {
1041 auto f = fgFields->at(i); // this is a TG4Field
1042 // we need to get the containing TG4MagneticField in order to print statistics
1043 auto mgfield = dynamic_cast<TG4MagneticField*>(f->GetG4Field());
1044 if (mgfield) {
1045 mgfield->PrintStatistics();
1046 }
1047 }
1048 }
1049}
Definition of the G4MonopoleFieldSetup class.
Definition of the TG4BiasingManager class.
Definition of the TG4Field class.
Definition of the TG4G3ControlVector class.
Definition of the TG4G3CutVector class.
Definition of the TG4G3Units class.
Definition of the TG4GeometryManager class.
Definition of the TG4GeometryServices class.
Definition of the TG4Globals class and basic container types.
Definition of the TG4Limits class.
Definition of the TG4MCGeometry class.
Definition of the TG4MagneticField class.
Definition of the TG4MediumMap class.
Definition of the TG4Medium class.
Definition of the TG4ModelConfigurationManager class.
Definition of the TG4OpGeometryManager class.
Definition of the TG4RadiatorDescription class.
Definition of the TG4SDManager class.
Definition of the TG4StateManager class.
Definition of the TG4VUserPostDetConstruction class.
Definition of the TG4VUserRegionConstruction class.
static G4MonopoleFieldSetup * GetMonopoleFieldSetup()
void SetMagneticField(G4MagneticField *magneticField)
The biasing manager.
The class for constructing magnetic, electromagnetic and gravity fields which strength is defined via...
Definition TG4Field.h:36
G4Field * GetG4Field() const
Definition TG4Field.h:57
Vector of control process values with convenient set/get methods.
Vector of kinetic energy cut values with convenient set/get methods.
The manager class for building Geant4 geometry depending on a selected user input.
G4bool fIsZeroField
option to activate propagating 'ifield = 0' defined in tracking media
static const G4double fgDefaultMaxStep
default max allowed step in materials with density < fLimitDensity
static TG4GeometryManager * fgInstance
this instance
G4bool fIsLocalField
option to activate getting local magnetic fields from Root geometry
void CreateField(TVirtualMagField *magField, G4FieldParameters *fieldParameters, G4LogicalVolume *lv)
TG4BiasingManager * fBiasingManager
Biasing manager.
TG4ModelConfigurationManager * fFastModelsManager
Fast simulation models manager.
TVirtualMCGeometry * GetMCGeometry() const
static G4ThreadLocal std::vector< TG4Field * > * fgFields
Fields.
void SetIsLocalField(G4bool isLocalField)
void SetIsMaxStepInLowDensityMaterials(G4bool isMaxStep)
TG4DetConstructionMessenger fMessenger
messenger
TG4GeometryManager(const TString &userGeometry)
void SetUserEquationOfMotion(G4EquationOfMotion *equation, G4String volumeName="")
void SetUserPostDetConstruction(TG4VUserPostDetConstruction *userPostDetConstruction)
TG4GeometryServices * fGeometryServices
geometry services
G4bool fIsUserMaxStep
option to activate max step defined in tracking media
void SetIsZeroField(G4bool isZeroField)
G4double fLimitDensity
material density limit for setting max allowed step
G4bool fIsMonopoleField
option to activate monopole field setup
TG4OpGeometryManager * fOpManager
optical geometry manager
G4bool fIsMaxStepInLowDensityMaterials
option to activate max step defined in low density materials
TG4VUserRegionConstruction * fUserRegionConstruction
User region construction.
TG4RadiatorDescription * CreateRadiator(const G4String &volName)
TG4ModelConfigurationManager * fEmModelsManager
EM models manager.
void SetUserRegionConstruction(TG4VUserRegionConstruction *userRegionConstruction)
std::vector< TG4RadiatorDescription * > fRadiators
Radiators.
TG4RootDetectorConstruction * fRootDetectorConstruction
Root detector construction.
static const G4double fgDefaultLimitDensity
default material density limit for setting max allowed step
void SetIsUserMaxStep(G4bool isUserMaxStep)
void SetUserLimits(const TG4G3CutVector &cuts, const TG4G3ControlVector &controls) const
TG4VUserPostDetConstruction * fUserPostDetConstruction
User post detector construction.
void SetIsMonopoleField(G4bool isMonopoleField)
G4String fUserGeometry
User geometry input.
void SetUserStepper(G4MagIntegratorStepper *stepper, G4String volumeName="")
G4double fMaxStepInLowDensityMaterials
max allowed step in materials with density < fLimitDensity
TVirtualMCGeometry * fMCGeometry
VirtualMC geometry.
Services for accessing to Geant4 geometry.
static TG4GeometryServices * Instance()
TG4MediumMap * GetMediumMap() const
static void Warning(const TString &className, const TString &methodName, const TString &text)
static void Exception(const TString &className, const TString &methodName, const TString &text)
static TString Endl()
Definition TG4Globals.h:101
Extended G4UserLimits class.
Definition TG4Limits.h:38
G4bool Update(const TG4G3ControlVector &controls)
void SetDefaultMaxAllowedStep()
void SetName(const G4String &name)
Definition TG4Limits.h:123
Geant4 implementation of the TVirtualMCGeometry interface.
The magnetic field defined via TVirtualMagField.
The map of media to logical volumes.
void MapMedium(G4LogicalVolume *lv, G4int mediumID)
TG4Medium * AddMedium(G4int mediumID, G4bool warn=true)
TG4Medium * GetMedium(G4int mediumID, G4bool warn=true) const
Helper class to keep medium data.
Definition TG4Medium.h:29
G4UserLimits * GetLimits() const
Definition TG4Medium.h:99
G4int GetIfield() const
Definition TG4Medium.h:104
void SetLimits(G4UserLimits *limits)
Definition TG4Medium.cxx:83
void SetIfield(G4int ifield)
Definition TG4Medium.h:79
G4String GetName() const
Definition TG4Medium.h:89
void SetMaterial(G4Material *material)
Definition TG4Medium.cxx:68
void SetName(const G4String &name)
Definition TG4Medium.cxx:55
The model configuration vector with suitable setters and a messenger.
Geant4 implementation of the TVirtualMC interface methods for definition of material properties for o...
The radiator description.
static TG4SDManager * Instance()
void SetNewState(TG4ApplicationState state)
static TG4StateManager * Instance()
The abstract base class for user defined class to customize geometry.
The abstract base class for user defined regions.
virtual G4int VerboseLevel() const
Definition TG4Verbose.h:78
TG4Verbose(const G4String &cmdName)
@ kMisalignGeometry
in MisalignGeometry
@ kConstructGeometry
in ConstructGeometry
@ kNotInApplication
not in VMC application
@ kConstructOpGeometry
in ConstructOpGeometry