Geant4 VMC Version 6.6
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 "TG4FieldParameters.h"
20#include "TG4G3ControlVector.h"
21#include "TG4G3CutVector.h"
22#include "TG4G3Units.h"
23#include "TG4GeometryServices.h"
24#include "TG4Globals.h"
25#include "TG4Limits.h"
26#include "TG4MCGeometry.h"
27#include "TG4Medium.h"
28#include "TG4MediumMap.h"
32#include "TG4RootDetectorConstruction.h"
33#include "TG4SDManager.h"
34#include "TG4StateManager.h"
37
38#include <G4FieldManager.hh>
39#include <G4LogicalVolumeStore.hh>
40#include <G4Material.hh>
42#include <G4PVPlacement.hh>
43#include <G4ReflectionFactory.hh>
44//#include <G4SystemOfUnits.hh>
45#include <G4TransportationManager.hh>
46
47#include <TGeoMCGeometry.h>
48#include <TGeoManager.h>
49#include <TGeoMedium.h>
50#include <TGeoVolume.h>
51#include <TList.h>
52#include <TVirtualMC.h>
53#include <TVirtualMCApplication.h>
54
55// Moved after ROOT includes to avoid warnings about shadowing variables
56// from CLHEP units
57#include <G4SystemOfUnits.hh>
58
59#ifdef USE_G3TOG4
60#include <G3MatTable.hh>
61#include <G3MedTable.hh>
62#include <G3SensVolVector.hh>
63#include <G3VolTable.hh>
64#include <G3toG4.hh>
65#include <G3toG4BuildTree.hh>
66#include <G3toG4MANY.hh>
67#endif
68
69#ifdef USE_VGM
70#include <Geant4GM/volumes/Factory.h>
71#include <RootGM/volumes/Factory.h>
72#endif
73
75const G4double TG4GeometryManager::fgDefaultLimitDensity = 0.001 * (g / cm3);
76const G4double TG4GeometryManager::fgDefaultMaxStep = 10 * cm;
77
78G4ThreadLocal std::vector<TG4Field*>* TG4GeometryManager::fgFields = 0;
79
80//_____________________________________________________________________________
81TG4GeometryManager::TG4GeometryManager(const TString& userGeometry)
82 : TG4Verbose("geometryManager"),
83 fMessenger(this),
84 fGeometryServices(new TG4GeometryServices()),
85 fMCGeometry(0),
86 fRootDetectorConstruction(0),
87 fOpManager(0),
88 fFastModelsManager(0),
89 fEmModelsManager(0),
90 fBiasingManager(0),
91 fUserGeometry(userGeometry),
92 fFieldParameters(),
93 fUserRegionConstruction(0),
94 fUserPostDetConstruction(0),
95 fIsLocalField(false),
96 fIsZeroField(false),
97 fIsUserMaxStep(false),
98 fIsMaxStepInLowDensityMaterials(true),
99 fLimitDensity(fgDefaultLimitDensity),
100 fMaxStepInLowDensityMaterials(fgDefaultMaxStep)
101
102{
104
105 if (fgInstance) {
106 TG4Globals::Exception("TG4GeometryManager",
107 "TG4GeometryManager:", "Cannot create two instances of singleton.");
108 }
109
110 // Field parameters for global field
111 fFieldParameters.push_back(new TG4FieldParameters());
112
114
116
117 fFastModelsManager = new TG4ModelConfigurationManager("fastSimulation");
119 fBiasingManager = new TG4BiasingManager("biasing");
120
121 fgInstance = this;
122}
123
124//_____________________________________________________________________________
126{
128
129 for (G4int i = 0; i < G4int(fFieldParameters.size()); ++i) {
130 delete fFieldParameters[i];
131 }
132
133 delete fgFields;
134 // magnetic field objects are deleted via G4 kernel
135
136 delete fGeometryServices;
137 delete fOpManager;
138 delete fFastModelsManager;
139 delete fEmModelsManager;
140 delete fBiasingManager;
141
142 fgInstance = 0;
143 fgFields = 0;
144}
145
146//
147// private methods
148//
149
150//_____________________________________________________________________________
152{
154
155 if (fUserGeometry == "VMCtoGeant4" || fUserGeometry == "Geant4" ||
156 fUserGeometry == "RootToGeant4") {
158 }
159
160 if (fUserGeometry == "VMCtoRoot" || fUserGeometry == "Root" ||
161 fUserGeometry == "VMC+RootToGeant4") {
162 if (!gGeoManager) new TGeoManager("TGeo", "Root geometry manager");
163 fMCGeometry = new TGeoMCGeometry();
164 }
165}
166
167//_____________________________________________________________________________
169{
171
172#ifdef USE_G3TOG4
173 if (VerboseLevel() > 1)
174 G4cout << "TG4GeometryManager::ConstructG4GeometryViaVMC" << G4endl;
175
176 // check if G4 tables were filled
177 /*
178 if ( ! TG4G3MCGeometry::Instance()->IsGeometryDefined() ) {
179 TG4Globals::Exception(
180 "TG4GeometryManager", "ConstructG4GeometryViaVMC",
181 "Geometry was not defined via VMC.");
182 }
183 */
184 // pass info about using G3toG4 to geometry services
186
187 // set the first entry in the G3Vol table
188 G4ggclos();
189 G3VolTableEntry* first = G3Vol.GetFirstVTE();
190
191 // transform MANY to Boolean solids
192 G3toG4MANY(first);
193
194 // create G4 geometry
195 G3toG4BuildTree(first, 0);
196
197 // fill medium map
198 // FillMediumMapFromG3();
199
200 // position the first entry with copyNo = 1
201 // (in Geant3 the top volume cannot be positioned)
202 //
203 if (!fGeometryServices->GetWorld()) {
204 G4VPhysicalVolume* world = new G4PVPlacement(
205 0, G4ThreeVector(), first->GetName(), first->GetLV(), 0, false, 1);
207 }
208
209 // print G3 volume table statistics
210 G3Vol.VTEStat();
211
212#else
213 TG4Globals::Exception("TG4GeometryManager", "ConstructG4GeometryViaVMC",
214 "Geant4 VMC has been installed without G3toG4." + TG4Globals::Endl() +
215 "Geometry construction via VMC is not supported.");
216#endif
217}
218
219//_____________________________________________________________________________
221{
224
225#ifdef USE_VGM
226 if (VerboseLevel() > 1)
227 G4cout << "TG4GeometryManager::ConstructG4GeometryViaVGM" << G4endl;
228
229 // Check Root manager
230 if (!gGeoManager) {
231 TG4Globals::Exception("TG4GeometryManager", "ConstructG4GeometryViaVGM",
232 "Geometry was not defined via Root.");
233 }
234
235 // Get and eventually also set the Root top volume
236 TGeoVolume* topVolume = gGeoManager->GetTopVolume();
237 if (!topVolume) {
238 topVolume = (TGeoVolume*)gGeoManager->GetListOfVolumes()->First();
239 if (!topVolume) {
240 TG4Globals::Exception("TG4GeometryManager", "ConstructG4GeometryViaVGM",
241 "Root top volume not found.");
242 }
243 gGeoManager->SetTopVolume(topVolume);
244 }
245
246 // Close Root geometry
247 if (!gGeoManager->IsClosed()) gGeoManager->CloseGeometry();
248
249 // Convert Root geometry to G4
250 if (VerboseLevel() > 0)
251 G4cout << "Converting Root geometry to Geant4 via VGM ... " << G4endl;
252
253 // import Root geometry in VGM
254 RootGM::Factory rootFactory;
255 if (VerboseLevel() > 1) rootFactory.SetDebug(1);
256 rootFactory.SetIgnore(true);
257 rootFactory.Import(gGeoManager->GetTopNode());
258
259 // export Root VGM geometry in Geant4
260 Geant4GM::Factory g4Factory;
261 if (VerboseLevel() > 1) g4Factory.SetDebug(1);
262 rootFactory.Export(&g4Factory);
263
264 G4VPhysicalVolume* g4World = g4Factory.World();
265 fGeometryServices->SetWorld(g4World);
266
267#else
268 TG4Globals::Exception("TG4GeometryManager", "ConstructG4GeometryViaVGM",
269 "Geant4 VMC has been installed without VGM." + TG4Globals::Endl() +
270 "Root geometry conversion is not supported.");
271#endif
272}
273
274//_____________________________________________________________________________
276{
278
279 if (VerboseLevel() > 1) {
280 G4cout << "TG4GeometryManager::ConstructG4Geometry: "
281 << "userGeometry=" << fUserGeometry << G4endl;
282 }
283
284 // VMC application construct geometry
285 if (fUserGeometry == "VMCtoGeant4") {
286
287 if (VerboseLevel() > 1)
288 G4cout << "Running TVirtualMCApplication::ConstructGeometry" << G4endl;
289
291 TVirtualMCApplication::Instance()->ConstructGeometry();
293 TVirtualMCApplication::Instance()->MisalignGeometry();
295 }
296
297 // VMC application construct geometry
298 if (fUserGeometry == "RootToGeant4" || fUserGeometry == "VMC+RootToGeant4") {
299 if (VerboseLevel() > 1)
300 G4cout << "Running TVirtualMCApplication::ConstructGeometry" << G4endl;
301
302#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 22, 8)
303 // Set Root default units to TGeo
304 TGeoManager::LockDefaultUnits(false);
305 TGeoManager::SetDefaultUnits(TGeoManager::kRootUnits);
306 TGeoManager::LockDefaultUnits(true);
307#endif
308
310 TVirtualMCApplication::Instance()->ConstructGeometry();
312
313 // If Root geometry was not closed by user
314 // we have to do it here
315 if (!gGeoManager->IsClosed()) {
316 TGeoVolume* top = (TGeoVolume*)gGeoManager->GetListOfVolumes()->First();
317 gGeoManager->SetTopVolume(top);
318 gGeoManager->CloseGeometry();
319 }
320
322 TVirtualMCApplication::Instance()->MisalignGeometry();
324 }
325
326 // Build G4 geometry
327 if (fUserGeometry == "VMCtoGeant4") ConstructG4GeometryViaVMC();
328
329 if (fUserGeometry == "RootToGeant4" || fUserGeometry == "VMC+RootToGeant4")
331
332 // print G4 geometry statistics
333 if (VerboseLevel() > 0) {
334 G4cout << "G4 Stat: instantiated "
335 << fGeometryServices->NofG4LogicalVolumes() << " logical volumes \n"
336 << " "
337 << fGeometryServices->NofG4PhysicalVolumes() << " physical volumes"
338 << G4endl;
339 }
340}
341
342//_____________________________________________________________________________
344{
346
347#ifdef USE_G3TOG4
348 if (VerboseLevel() > 1)
349 G4cout << "TG4GeometryManager::FillMediumMapFromG3()" << G4endl;
350
352
353 // Create medium for each medium entry
354 for (G4int i = 0; i < G4int(G3Med.GetSize()); i++) {
355 G3MedTableEntry* mediumEntry = G3Med.GetMTE(i);
356 G4int mediumID = mediumEntry->GetID();
357
358 if (VerboseLevel() > 2) {
359 G4cout << "Getting medium ID=" << mediumID << G4endl;
360 }
361 // Get medium from medium map
362 TG4Medium* medium = mediumMap->GetMedium(mediumID);
363
364 // Create a medium if it does not exist
365 // (This should not happen, but let's check it anyway)
366 if (!medium) {
367 medium = mediumMap->AddMedium(mediumID, false);
368
369 TString message = "Medium ";
370 message += mediumID;
371 message += " was not found in medium map. New medium will be created";
372 TG4Globals::Warning("TG4GeometryManager", "FillMediumMapFromG3", message);
373 }
374
375 medium->SetLimits(mediumEntry->GetLimits());
376 medium->SetMaterial(mediumEntry->GetMaterial());
377 }
378
379 if (VerboseLevel() > 2) G3Vol.PrintAll();
380
381 // Map media to logical volumes
382 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
383 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
384 G4LogicalVolume* lv = (*lvStore)[i];
385
386 // Get medium ID from G3 tables
387 G4String name = lv->GetName();
388 G4String g3Name(name);
389 // Filter out the reflected volume name extension
390 // added by reflection factory
391 G4String ext = G4ReflectionFactory::Instance()->GetVolumesNameExtension();
392 if (name.find(ext)) g3Name = g3Name.substr(0, g3Name.find(ext));
393 G4int mediumID = G3Vol.GetVTE(g3Name)->GetNmed();
394
395 if (VerboseLevel() > 2)
396 G4cout << "Mapping medium Id " << mediumID << " to LV " << name << G4endl;
397
398 // Map medium to LV
399 mediumMap->MapMedium(lv, mediumID);
400 }
401
402 // clear G3 tables
403 G3Vol.Clear();
404 G3SensVol.clear();
405 G3Mat.Clear();
406 G3Med.Clear();
407#else
408 TG4Globals::Exception("TG4GeometryManager", "FillMediumMapFromG3",
409 "Geant4 VMC has been installed without G3toG4." + TG4Globals::Endl() +
410 "Geometry construction via VMC is not supported.");
411#endif
412}
413
414//_____________________________________________________________________________
416{
419
420 if (VerboseLevel() > 1)
421 G4cout << "TG4GeometryManager::FillMediumMapFromG4()" << G4endl;
422
424
425 // Create medium for each material
426 const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
427 for (G4int i = 0; i < G4int(materialTable->size()); i++) {
428 G4Material* material = (*materialTable)[i];
429
430 if (VerboseLevel() > 2) {
431 G4cout << "Adding medium name= " << material->GetName()
432 << " Id=" << material->GetIndex() << G4endl;
433 }
434 TG4Medium* medium = mediumMap->AddMedium(material->GetIndex());
435 medium->SetName(material->GetName());
436 medium->SetMaterial(material);
437 }
438
439 // Map media to logical volumes
440 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
441 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
442 G4LogicalVolume* lv = (*lvStore)[i];
443 G4int mediumID = lv->GetMaterial()->GetIndex();
444
445 if (VerboseLevel() > 2) {
446 G4cout << "Mapping medium Id=" << mediumID << " to LV= " << lv->GetName()
447 << G4endl;
448 }
449 mediumMap->MapMedium(lv, mediumID);
450 }
451}
452
453//_____________________________________________________________________________
455{
457
458 if (VerboseLevel() > 1)
459 G4cout << "TG4GeometryManager::FillMediumMapFromRoot()" << G4endl;
460
461 // fGeometryServices->PrintLogicalVolumeStore();
462
464
465 // Create TG4 medium for each TGeo madium
466 TIter next(gGeoManager->GetListOfMedia());
467 TGeoMedium* geoMedium;
468 while ((geoMedium = (TGeoMedium*)next())) {
469 Int_t mediumId = geoMedium->GetId();
470 G4String mediumName = geoMedium->GetName();
471
472 // Int_t isvol = (Int_t) geoMedium->GetParam(0);
473 Int_t ifield = (Int_t)geoMedium->GetParam(1);
474 // Double_t fieldm = geoMedium->GetParam(2);
475 // Double_t tmaxfd = geoMedium->GetParam(3);
476 Double_t stemax = geoMedium->GetParam(4);
477 // Double_t deemax = geoMedium->GetParam(5);
478 // Double_t epsil = geoMedium->GetParam(6);
479 // Double_t stmin = geoMedium->GetParam(7);
480
481 // Only stemax parameter is passed to G4 if it is positive
482 G4UserLimits* limits = 0;
483 if (stemax > 0) {
484 limits = new G4UserLimits();
485 limits->SetMaxAllowedStep(stemax * cm);
486 }
487
488 if (VerboseLevel() > 2) {
489 G4cout << "Adding medium Id=" << mediumId << " name=" << mediumName
490 << " limits=" << limits << G4endl;
491 }
492 TG4Medium* medium = mediumMap->AddMedium(mediumId);
493 medium->SetName(mediumName);
494 medium->SetLimits(limits);
495 medium->SetIfield(ifield);
496
497 G4String matName = geoMedium->GetMaterial()->GetName();
498 G4Material* material = G4Material::GetMaterial(matName);
499 if (!material) {
500 TG4Globals::Exception("TG4GeometryManager", "FillMediumMapFromRoot",
501 "Material " + TString(matName) + " not found.");
502 }
503 medium->SetMaterial(material);
504 }
505
506 // Map media to logical volumes
507 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
508 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
509 G4LogicalVolume* lv = (*lvStore)[i];
510
511 TGeoVolume* geoVolume = nullptr;
512
513 if (fRootDetectorConstruction == nullptr) {
514 G4String volName = lv->GetName();
515
516 // Filter out the reflected volumes name extension
517 // added by reflection factory
518 G4String ext = G4ReflectionFactory::Instance()->GetVolumesNameExtension();
519 if (volName.find(ext)) volName = volName.substr(0, volName.find(ext));
520
521 geoVolume = gGeoManager->GetVolume(volName.data());
522 }
523 else {
524 geoVolume = fRootDetectorConstruction->GetVolume(lv);
525 }
526
527 if (!geoVolume) {
528 TG4Globals::Exception("TG4GeometryManager", "FillMediumMapFromRoot",
529 "Root volume " + TString(lv->GetName()) + " not found");
530 }
531
532 // skip assemblies
533 if (geoVolume && geoVolume->IsAssembly()) continue;
534
535 if (geoVolume && !geoVolume->GetMedium()) {
536 TG4Globals::Exception("TG4GeometryManager", "FillMediumMapFromRoot",
537 "Root volume " + TString(lv->GetName()) + " has not medium defined.");
538 }
539
540 G4int mediumID = geoVolume->GetMedium()->GetId();
541
542 if (VerboseLevel() > 2) {
543 G4cout << "Mapping medium Id=" << mediumID << " to LV=" << lv->GetName()
544 << G4endl;
545 }
546 mediumMap->MapMedium(lv, mediumID);
547 }
548}
549
550//_____________________________________________________________________________
552{
554
555 if (fUserGeometry == "VMCtoGeant4") FillMediumMapFromG3();
556
557 if (fUserGeometry == "VMCtoRoot" || fUserGeometry == "Root" ||
558 fUserGeometry == "RootToGeant4" || fUserGeometry == "VMC+RootToGeant4") {
560 }
561
562 if (fUserGeometry == "Geant4") FillMediumMapFromG4();
563}
564
565//_____________________________________________________________________________
566void TG4GeometryManager::CreateField(TVirtualMagField* magField,
567 TG4FieldParameters* fieldParameters, G4LogicalVolume* lv)
568{
570
571 TG4Field* tg4Field = new TG4Field(*fieldParameters, magField, lv);
572
573 if (VerboseLevel() > 0) {
574 G4String fieldType =
576 G4bool isCachedMagneticField = (fieldParameters->GetConstDistance() > 0.);
577 if (!lv) {
578 fieldType = "Global";
579 }
580 else {
581 fieldType = "Local (in ";
582 fieldType.append(lv->GetName());
583 fieldType.append(")");
584 }
585 if (isCachedMagneticField) {
586 fieldType.append(" cached");
587 }
588
589 G4cout << fieldType << " field created with stepper ";
591 fieldParameters->GetStepperType())
592 << G4endl;
593 }
594
595 // create magnetic field vector
596 if (!fgFields) {
597 fgFields = new std::vector<TG4Field*>();
598 }
599
600 fgFields->push_back(tg4Field);
601}
602
603//_____________________________________________________________________________
605{
607
608 // Create global magnetic field
609 if (gMC->GetMagField()) {
610 CreateField(gMC->GetMagField(), fFieldParameters[0], 0);
611
612 // create monopole field
613 if (fFieldParameters[0]->GetIsMonopole()) {
614 G4cout << "Create G4MonopoleFieldSetup" << G4endl;
615 G4MonopoleFieldSetup* monFieldSetup =
617 TG4Field* tg4Field = (*fgFields)[0];
618 G4Field* field = tg4Field->GetG4Field();
619 G4MagneticField* magField = dynamic_cast<G4MagneticField*>(field);
620 if (!magField) {
621 // add warning
622 G4cerr << "Wrong field type. Only magnetic field is supported in "
623 "G4MonopoleFieldSetup."
624 << G4endl;
625 }
626 else {
627 monFieldSetup->SetMagneticField(magField);
628 monFieldSetup->SetDefaultEquation(tg4Field->GetEquation());
629 monFieldSetup->SetDefaultStepper(tg4Field->GetStepper());
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 const G4String& volumeName)
712{
715
716 // Get user field parameters
717 TG4FieldParameters* fieldParameters = 0;
718 for (G4int i = 0; i < G4int(fFieldParameters.size()); ++i) {
719 if (fFieldParameters[i]->GetVolumeName() == volumeName) {
720 return fFieldParameters[i];
721 }
722 }
723
724 // Create field parameters if not yet defined
725 fieldParameters = new TG4FieldParameters(volumeName);
726 fFieldParameters.push_back(fieldParameters);
727 return fieldParameters;
728}
729
730//_____________________________________________________________________________
732{
734
735 // Supported only for geomRoot and geomRootToGeant4.
736 if ((fUserGeometry != "Root") && (fUserGeometry != "RootToGeant4")) return;
737
738 if (VerboseLevel() > 1)
739 G4cout << "TG4GeometryManager::ConstructLocalFields()" << G4endl;
740
741 TIter next(gGeoManager->GetListOfVolumes());
742 TGeoVolume* geoVolume;
743 while ((geoVolume = (TGeoVolume*)next())) {
744
745 if (!geoVolume->GetField()) continue;
746
747 // Get field
748 TVirtualMagField* magField =
749 dynamic_cast<TVirtualMagField*>(geoVolume->GetField());
750 if (!magField) {
751 TString message = geoVolume->GetName();
752 message += ": uknown field type will be ignored.";
753 TG4Globals::Warning("TG4GeometryManager", "ConstructLocalFields",
754 "No magnetic field is defined.");
755 continue;
756 }
757
758 // Volume name
759 G4String volumeName = geoVolume->GetName();
760
761 // Get Geant4 volume
762 G4LogicalVolume* lv =
764 if (!lv) {
765 TString message = geoVolume->GetName();
766 message += " volume not found in Geant4 geometry.";
767 TG4Globals::Warning("TG4GeometryManager", "ConstructLocalFields",
768 "No magnetic field is defined.");
769 continue;
770 }
771
772 // Get or create user field parameters
773 TG4FieldParameters* fieldParameters =
774 GetOrCreateFieldParameters(volumeName);
775
776 // Create magnetic field
777 CreateField(magField, fieldParameters, lv);
778 }
779}
780
781//
782// public methods
783//
784
785//_____________________________________________________________________________
787{
790
791 if (!fMCGeometry) {
793 "TG4GeometryManager", "GetMCGeometry", "No MC geometry defined.");
794 }
795
796 return fMCGeometry;
797}
798
799//_____________________________________________________________________________
801{
803
804 // Construct G4 geometry
806
807 // Fill medium map
809
810 // VMC application construct geometry for optical processes
812 TVirtualMCApplication::Instance()->ConstructOpGeometry();
814
815 // Construct user regions
817}
818
819#include "TG4SDManager.h"
820
821//_____________________________________________________________________________
823{
825
826 if (VerboseLevel() > 1)
827 G4cout << "TG4GeometryManager::ConstructSDandField() " << G4endl;
828
829 // Call user class for geometry customization
831
832 // Construct regions with fast simulation and EM models
835
836 // Construct biasing operator
838
839 // Initialize SD manager (create SDs)
841
842 // Create global field
844
845 if (fIsLocalField) {
847 }
848}
849
850//_____________________________________________________________________________
852{
854
855 if (VerboseLevel() > 1)
856 G4cout << "TG4GeometryManager::FinishGeometry" << G4endl;
857
858 // Create magnetic field
859 // ConstructField();
860
861 // Fill medium map if not yet done
863
864 // Set world to geometry services
866 G4TransportationManager::GetTransportationManager()
867 ->GetNavigatorForTracking()
868 ->GetWorldVolume());
869
870 if (VerboseLevel() > 1)
871 G4cout << "TG4GeometryManager::FinishGeometry done" << G4endl;
872}
873
874//_____________________________________________________________________________
876{
880
881 if (!fgFields) {
883 "TG4GeometryManager", "UpdateField", "No magnetic field is defined.");
884 return;
885 }
886
887 if (VerboseLevel() > 1) G4cout << "TG4GeometryManager::UpdateField" << G4endl;
888
889 // Only the parameters defined in TG4Magnetic field can be updated when
890 // field already exists, so we can safely call the base class non virtual
891 // method
892 for (G4int i = 0; i < G4int(fgFields->size()); ++i) {
893 fgFields->at(i)->Update(*fFieldParameters[i]);
894 }
895}
896
897//_____________________________________________________________________________
898void TG4GeometryManager::CreateFieldParameters(const G4String& fieldVolName)
899{
904
905 fFieldParameters.push_back(new TG4FieldParameters(fieldVolName));
906}
907
908//_____________________________________________________________________________
910 const G4String& volName)
911{
913
914 TG4RadiatorDescription* radiatorDescription =
915 new TG4RadiatorDescription(volName);
916 fRadiators.push_back(radiatorDescription);
917
918 return radiatorDescription;
919}
920
921//_____________________________________________________________________________
923 const TG4G3CutVector& cuts, const TG4G3ControlVector& controls) const
924{
926
927 if (VerboseLevel() > 1)
928 G4cout << "TG4GeometryManager::SetUserLimits" << G4endl;
929
930 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
931
932 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
933 G4LogicalVolume* lv = (*lvStore)[i];
934 TG4Medium* medium = fGeometryServices->GetMediumMap()->GetMedium(lv, false);
935
936 if (!medium) continue;
937
938 // get limits if already exist
939 TG4Limits* tg4Limits = 0;
940 G4UserLimits* limits = medium->GetLimits();
941 tg4Limits = fGeometryServices->GetLimits(limits, cuts, controls);
942
943 // get tracking medium name
944 G4String name = medium->GetName();
945
946 if (tg4Limits) {
947 tg4Limits->SetName(name);
948 }
949 else {
950 // Check if the step below is needed
951 tg4Limits = fGeometryServices->FindLimits2(name, true);
952 if (!tg4Limits) {
953 tg4Limits = new TG4Limits(name, cuts, controls);
954 }
955 }
956
957 // set new limits back to medium
958 medium->SetLimits(tg4Limits);
959
960 // inactivate max step defined by user
961 // if its activation was not asked explicitely
962 if (!fIsUserMaxStep) tg4Limits->SetMaxAllowedStep(DBL_MAX);
963
964 // limit max step for low density materials (< AIR)
966 lv->GetMaterial()->GetDensity() < fLimitDensity)
967 tg4Limits->SetMaxAllowedStep(fMaxStepInLowDensityMaterials);
968
969 // set max step the default value
970 tg4Limits->SetDefaultMaxAllowedStep();
971
972 // update controls in limits according to the setup
973 // in the passed vector
974 tg4Limits->Update(controls);
975
976 // set limits to logical volume
977 lv->SetUserLimits(tg4Limits);
978 }
979
980 if (VerboseLevel() > 1)
981 G4cout << "TG4GeometryManager::SetUserLimits done" << G4endl;
982}
983
984//_____________________________________________________________________________
985void TG4GeometryManager::SetIsLocalField(G4bool isLocalField)
986{
988
989 if (VerboseLevel() > 1)
990 G4cout << "TG4GeometryManager::SetIsLocalField: " << std::boolalpha
991 << isLocalField << G4endl;
992
993 fIsLocalField = isLocalField;
994}
995
996//_____________________________________________________________________________
998{
1000
1001 if (VerboseLevel() > 1)
1002 G4cout << "TG4GeometryManager::SetIsZeroField: " << std::boolalpha
1003 << isZeroField << G4endl;
1004
1005 fIsZeroField = isZeroField;
1006}
1007
1008//_____________________________________________________________________________
1010{
1012
1013 if (VerboseLevel() > 0)
1014 G4cout << "TG4GeometryManager::SetIsUserMaxStep: " << std::boolalpha
1015 << isUserMaxStep << G4endl;
1016
1017 fIsUserMaxStep = isUserMaxStep;
1018}
1019
1020//_____________________________________________________________________________
1022{
1024
1025 if (VerboseLevel() > 0)
1026 G4cout << "TG4GeometryManager::SetIsMaxStepInLowDensityMaterials: "
1027 << std::boolalpha << isMaxStep << G4endl;
1028
1030}
1031
1032//_____________________________________________________________________________
1034 TG4VUserRegionConstruction* userRegionConstruction)
1035{
1037
1038 fUserRegionConstruction = userRegionConstruction;
1039}
1040
1041//_____________________________________________________________________________
1043 TG4VUserPostDetConstruction* userPostDetConstruction)
1044{
1046
1047 fUserPostDetConstruction = userPostDetConstruction;
1048}
1049
1050//_____________________________________________________________________________
1052 G4EquationOfMotion* equation, G4String volumeName)
1053{
1054 if (!volumeName.size()) {
1055 // global field
1056 fFieldParameters[0]->SetUserEquationOfMotion(equation);
1057 }
1058 else {
1059 // local field
1060 // Get or create user field parameters
1061 TG4FieldParameters* fieldParameters =
1062 GetOrCreateFieldParameters(volumeName);
1063 fieldParameters->SetUserEquationOfMotion(equation);
1064 }
1065}
1066
1067//_____________________________________________________________________________
1069 G4MagIntegratorStepper* stepper, G4String volumeName)
1070{
1071 if (!volumeName.size()) {
1072 // global field
1073 fFieldParameters[0]->SetUserStepper(stepper);
1074 }
1075 else {
1076 // local field
1077 // Get or create user field parameters
1078 TG4FieldParameters* fieldParameters =
1079 GetOrCreateFieldParameters(volumeName);
1080 fieldParameters->SetUserStepper(stepper);
1081 }
1082}
1083
1084//_____________________________________________________________________________
1086{
1089 if (VerboseLevel() > 0 && fgFields) {
1090 for (G4int i = 0; i < G4int(fgFields->size()); ++i) {
1091 auto f = fgFields->at(i); // this is a TG4Field
1092 // we need to get the containing TG4MagneticField in order to print statistics
1093 auto mgfield = dynamic_cast<TG4MagneticField*>(f->GetG4Field());
1094 if (mgfield) {
1095 mgfield->PrintStatistics();
1096 }
1097 }
1098 }
1099}
Definition of the G4MonopoleFieldSetup class.
Definition of the TG4BiasingManager class.
Definition of the TG4FieldParameters 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.
void SetDefaultEquation(G4EquationOfMotion *equation)
static G4MonopoleFieldSetup * GetMonopoleFieldSetup()
void SetMagneticField(G4MagneticField *magneticField)
void SetDefaultStepper(G4MagIntegratorStepper *stepper)
The biasing manager.
The magnetic field parameters.
void SetUserEquationOfMotion(G4EquationOfMotion *equation)
static FieldType GetFieldType(const G4String &name)
void SetUserStepper(G4MagIntegratorStepper *stepper)
G4double GetConstDistance() const
Return the distance within which the field is considered constant.
static G4String StepperTypeName(StepperType stepper)
static StepperType GetStepperType(const G4String &name)
static G4String FieldTypeName(FieldType field)
The class for constructing magnetic, electromagnetic and gravity fields which strength is defined via...
Definition TG4Field.h:48
G4MagIntegratorStepper * GetStepper() const
Definition TG4Field.h:103
G4Field * GetG4Field() const
Definition TG4Field.h:91
G4EquationOfMotion * GetEquation() const
Definition TG4Field.h:97
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
TG4BiasingManager * fBiasingManager
Biasing manager.
TG4ModelConfigurationManager * fFastModelsManager
Fast simulation models manager.
TVirtualMCGeometry * GetMCGeometry() const
static G4ThreadLocal std::vector< TG4Field * > * fgFields
Fields.
void CreateField(TVirtualMagField *magField, TG4FieldParameters *fieldParameters, G4LogicalVolume *lv)
void SetIsLocalField(G4bool isLocalField)
TG4FieldParameters * GetOrCreateFieldParameters(const G4String &volumeName)
void SetIsMaxStepInLowDensityMaterials(G4bool isMaxStep)
std::vector< TG4FieldParameters * > fFieldParameters
Field parameters.
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)
void CreateFieldParameters(const G4String &fieldVolName)
G4double fLimitDensity
material density limit for setting max allowed step
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.
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.
G4VPhysicalVolume * GetWorld() const
void SetWorld(G4VPhysicalVolume *world)
G4LogicalVolume * FindLogicalVolume(const G4String &name, G4bool silent=false) const
static TG4GeometryServices * Instance()
TG4Limits * FindLimits2(const G4String &name, G4bool silent=false) const
TG4Limits * GetLimits(G4UserLimits *limits) const
void SetIsG3toG4(G4bool isG3toG4)
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:100
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.
virtual void PrintStatistics() const
The map of media to logical volumes.
void MapMedium(G4LogicalVolume *lv, G4int mediumID)
TG4Medium * AddMedium(G4int mediumID, G4bool warn=true)
G4int GetNofMedia() const
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.
virtual void Construct()=0
Method to be overriden by user.
The abstract base class for user defined regions.
virtual void Construct()=0
Method to be overriden by user.
Base class for defining the verbose level and a common messenger.
Definition TG4Verbose.h:36
virtual G4int VerboseLevel() const
Definition TG4Verbose.h:78
@ kMisalignGeometry
in MisalignGeometry
@ kConstructGeometry
in ConstructGeometry
@ kNotInApplication
not in VMC application
@ kConstructOpGeometry
in ConstructOpGeometry