Geant4 VMC Version 6.7
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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 <G4ReflectionFactory.hh>
48//#include <G4SystemOfUnits.hh>
49#include <G4TransportationManager.hh>
50
51#include <TGeoMCGeometry.h>
52#include <TGeoManager.h>
53#include <TGeoMedium.h>
54#include <TGeoVolume.h>
55#include <TList.h>
56#include <TVirtualMC.h>
57#include <TVirtualMCApplication.h>
58
59// Moved after ROOT includes to avoid warnings about shadowing variables
60// from CLHEP units
61#include <G4SystemOfUnits.hh>
62
63#ifdef USE_G3TOG4
64#include <G3MatTable.hh>
65#include <G3MedTable.hh>
66#include <G3SensVolVector.hh>
67#include <G3VolTable.hh>
68#include <G3toG4.hh>
69#include <G3toG4BuildTree.hh>
70#include <G3toG4MANY.hh>
71#endif
72
73#ifdef USE_VGM
74#include <Geant4GM/volumes/Factory.h>
75#include <RootGM/volumes/Factory.h>
76#endif
77
79const G4double TG4GeometryManager::fgDefaultLimitDensity = 0.001 * (g / cm3);
80const G4double TG4GeometryManager::fgDefaultMaxStep = 10 * cm;
81
82G4ThreadLocal std::vector<TG4Field*>* TG4GeometryManager::fgFields = 0;
83
84//_____________________________________________________________________________
85TG4GeometryManager::TG4GeometryManager(const TString& userGeometry)
86 : TG4Verbose("geometryManager"),
87 fMessenger(this),
89 fMCGeometry(0),
91 fOpManager(0),
95 fUserGeometry(userGeometry),
98 fIsLocalField(false),
99 fIsZeroField(false),
100 fIsMonopoleField(false),
101 fIsUserMaxStep(false),
105
106{
108
109 if (fgInstance) {
110 TG4Globals::Exception("TG4GeometryManager",
111 "TG4GeometryManager:", "Cannot create two instances of singleton.");
112 }
113
114 // Geant4 field builder, it creates field parameters for global field
115 G4FieldBuilder::Instance();
116
118
120
121 fFastModelsManager = new TG4ModelConfigurationManager("fastSimulation");
123 fBiasingManager = new TG4BiasingManager("biasing");
124
125 fgInstance = this;
126}
127
128//_____________________________________________________________________________
130{
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
185 fGeometryServices->SetIsG3toG4(true);
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);
206 fGeometryServices->SetWorld(world);
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
351 TG4MediumMap* mediumMap = fGeometryServices->GetMediumMap();
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
423 TG4MediumMap* mediumMap = fGeometryServices->GetMediumMap();
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
463 TG4MediumMap* mediumMap = fGeometryServices->GetMediumMap();
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#ifdef USE_G4ROOT
525 geoVolume = fRootDetectorConstruction->GetVolume(lv);
526#endif
527 }
528
529 if (!geoVolume) {
530 TG4Globals::Exception("TG4GeometryManager", "FillMediumMapFromRoot",
531 "Root volume " + TString(lv->GetName()) + " not found");
532 }
533
534 // skip assemblies
535 if (geoVolume && geoVolume->IsAssembly()) continue;
536
537 if (geoVolume && !geoVolume->GetMedium()) {
538 TG4Globals::Exception("TG4GeometryManager", "FillMediumMapFromRoot",
539 "Root volume " + TString(lv->GetName()) + " has not medium defined.");
540 }
541
542 G4int mediumID = geoVolume->GetMedium()->GetId();
543
544 if (VerboseLevel() > 2) {
545 G4cout << "Mapping medium Id=" << mediumID << " to LV=" << lv->GetName()
546 << G4endl;
547 }
548 mediumMap->MapMedium(lv, mediumID);
549 }
550}
551
552//_____________________________________________________________________________
554{
556
557 if (fUserGeometry == "VMCtoGeant4") FillMediumMapFromG3();
558
559 if (fUserGeometry == "VMCtoRoot" || fUserGeometry == "Root" ||
560 fUserGeometry == "RootToGeant4" || fUserGeometry == "VMC+RootToGeant4") {
562 }
563
564 if (fUserGeometry == "Geant4") FillMediumMapFromG4();
565}
566
567//_____________________________________________________________________________
568void TG4GeometryManager::CreateField(TVirtualMagField* magField,
569 G4FieldParameters* fieldParameters, G4LogicalVolume* lv)
570{
572
573 TG4Field* tg4Field = new TG4Field(*fieldParameters, magField, lv);
574
575 if (VerboseLevel() > 0) {
576 G4String lvName;
577 if (lv != nullptr) lvName = lv->GetName();
578 auto fieldParameters = G4FieldBuilder::Instance()->GetFieldParameters(lvName);
579 G4String fieldType =
580 G4FieldParameters::FieldTypeName(fieldParameters->GetFieldType());
581 G4bool isCachedMagneticField = (fieldParameters->GetConstDistance() > 0.);
582 if (!lv) {
583 fieldType = "Global";
584 }
585 else {
586 fieldType = "Local (in ";
587 fieldType.append(lv->GetName());
588 fieldType.append(")");
589 }
590 if (isCachedMagneticField) {
591 fieldType.append(" cached");
592 }
593
594 G4cout << fieldType << " field created with stepper ";
595 G4cout << G4FieldParameters::StepperTypeName(
596 fieldParameters->GetStepperType())
597 << G4endl;
598 }
599
600 // create magnetic field vector
601 if (!fgFields) {
602 fgFields = new std::vector<TG4Field*>();
603 }
604
605 fgFields->push_back(tg4Field);
606}
607
608//_____________________________________________________________________________
610{
612
613 if (VerboseLevel() > 1)
614 G4cout << "TG4GeometryManager::ConstructGlobalField()" << G4endl;
615
616 // Create global magnetic field
617 if (gMC->GetMagField()) {
618 auto fieldParameters = G4FieldBuilder::Instance()->GetFieldParameters();
619 CreateField(gMC->GetMagField(), fieldParameters, nullptr);
620
621 // create monopole field
622 if (fIsMonopoleField) {
623 G4cout << "Create G4MonopoleFieldSetup" << G4endl;
624 G4MonopoleFieldSetup* monFieldSetup =
626 TG4Field* tg4Field = (*fgFields)[0];
627 G4Field* field = tg4Field->GetG4Field();
628 G4MagneticField* magField = dynamic_cast<G4MagneticField*>(field);
629 if (!magField) {
630 // add warning
631 G4cerr << "Wrong field type. Only magnetic field is supported in "
632 "G4MonopoleFieldSetup."
633 << G4endl;
634 }
635 else {
636 monFieldSetup->SetMagneticField(magField);
637 // TO DO: Update functions in G4MonopoleFieldSetup
638 // monFieldSetup->SetDefaultEquation(fieldParameters->GetEquationType());
639 // monFieldSetup->SetDefaultStepper(fieldParameters->GetStepperType());
640 monFieldSetup->InitialiseAll();
641 }
642 }
643
644 if (fIsZeroField) {
646 }
647 }
648}
649
650//_____________________________________________________________________________
652{
656
657 if (VerboseLevel() > 1)
658 G4cout << "TG4GeometryManager::ConstructZeroFields()" << G4endl;
659
660 G4bool forceToAllDaughters = false;
661
662 // Set a dummy field manager to all LV first in order to avoid propagation
663 // of zero field to volume daughters
664 G4FieldManager* dummyFieldManager = new G4FieldManager();
665 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
666 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
667 G4LogicalVolume* lv = (*lvStore)[i];
668 lv->SetFieldManager(dummyFieldManager, forceToAllDaughters);
669 }
670
671 // Set zero field manager to volumes associated with a tracking medium
672 // with ifield value = 0.
673 G4FieldManager* fieldManager = 0;
674 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
675
676 G4LogicalVolume* lv = (*lvStore)[i];
677
678 // skip volume without medium
679 TG4Medium* medium =
681 if (!medium) continue;
682
683 // Skip volumes with ifield != 0
684 if (medium->GetIfield() != 0) {
685 if (VerboseLevel() > 2) {
686 G4cout << "Global field in logical volume: " << lv->GetName() << G4endl;
687 }
688 continue;
689 }
690
691 // create field manager if it does not exist yet
692 if (!fieldManager) {
693 fieldManager = new G4FieldManager();
694 // CHECK if we need to delete it
695 fieldManager->SetDetectorField(0);
696 fieldManager->CreateChordFinder(0);
697 }
698 lv->SetFieldManager(fieldManager, forceToAllDaughters);
699
700 if (VerboseLevel() > 1) {
701 G4cout << "Zero magnetic field set to logical volume: " << lv->GetName()
702 << G4endl;
703 }
704 }
705
706 // Remove the dummy field manager to all LV without zero field
707 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
708 G4LogicalVolume* lv = (*lvStore)[i];
709
710 if (lv->GetFieldManager() == dummyFieldManager) {
711 lv->SetFieldManager(0, forceToAllDaughters);
712 }
713 }
714
715 // Delete the dummy field manager
716 delete dummyFieldManager;
717}
718
719//_____________________________________________________________________________
721{
723
724 // Supported only for geomRoot and geomRootToGeant4.
725 if ((fUserGeometry != "Root") && (fUserGeometry != "RootToGeant4")) return;
726
727 if (VerboseLevel() > 1)
728 G4cout << "TG4GeometryManager::ConstructLocalFields()" << G4endl;
729
730 TIter next(gGeoManager->GetListOfVolumes());
731 TGeoVolume* geoVolume;
732 while ((geoVolume = (TGeoVolume*)next())) {
733
734 if (!geoVolume->GetField()) continue;
735
736 // Get field
737 TVirtualMagField* magField =
738 dynamic_cast<TVirtualMagField*>(geoVolume->GetField());
739 if (!magField) {
740 TString message = geoVolume->GetName();
741 message += ": uknown field type will be ignored.";
742 TG4Globals::Warning("TG4GeometryManager", "ConstructLocalFields",
743 "No magnetic field is defined.");
744 continue;
745 }
746
747 // Volume name
748 G4String volumeName = geoVolume->GetName();
749
750 // Get Geant4 volume
751 G4LogicalVolume* lv =
753 if (!lv) {
754 TString message = geoVolume->GetName();
755 message += " volume not found in Geant4 geometry.";
756 TG4Globals::Warning("TG4GeometryManager", "ConstructLocalFields",
757 "No magnetic field is defined.");
758 continue;
759 }
760
761 // Get or create user field parameters
762 auto fieldBuilder = G4FieldBuilder::Instance();
763 // Activate this code when G4FieldBuilder::GetFieldParameters
764 // provides an option to suppress a warning if parameters do not exist
765 // auto fieldParameters = fieldBuilder->GetFieldParameters(volumeName);
766 // if (fieldParameters == nullptr) {
767 // fieldParameters = fieldBuilder->CreateFieldParameters(volumeName);
768 // }
769
770 // Create G4 user field parameters
771 auto fieldParameters = fieldBuilder->CreateFieldParameters(volumeName);
772
773 // Create magnetic field
774 CreateField(magField, fieldParameters, lv);
775 }
776}
777
778//
779// public methods
780//
781
782//_____________________________________________________________________________
784{
787
788 if (!fMCGeometry) {
790 "TG4GeometryManager", "GetMCGeometry", "No MC geometry defined.");
791 }
792
793 return fMCGeometry;
794}
795
796//_____________________________________________________________________________
798{
800
801 // Construct G4 geometry
803
804 // Fill medium map
806
807 // VMC application construct geometry for optical processes
809 TVirtualMCApplication::Instance()->ConstructOpGeometry();
811
812 // Construct user regions
814}
815
816#include "TG4SDManager.h"
817
818//_____________________________________________________________________________
820{
822
823 if (VerboseLevel() > 1)
824 G4cout << "TG4GeometryManager::ConstructSDandField() " << G4endl;
825
826 // Call user class for geometry customization
828
829 // Construct regions with fast simulation and EM models
830 fFastModelsManager->CreateRegions();
831 fEmModelsManager->CreateRegions();
832
833 // Construct biasing operator
834 fBiasingManager->CreateBiasingOperator();
835
836 // Initialize SD manager (create SDs)
838
839 // Create global field
841
842 if (fIsLocalField) {
844 }
845
846 // Construct all Geant4 field objects
847 auto fieldBuilder = G4FieldBuilder::Instance();
848 fieldBuilder->ConstructFieldSetup();
849}
850
851//_____________________________________________________________________________
853{
855
856 if (VerboseLevel() > 1)
857 G4cout << "TG4GeometryManager::FinishGeometry" << G4endl;
858
859 // Create magnetic field
860 // ConstructField();
861
862 // Fill medium map if not yet done
863 if (fGeometryServices->GetMediumMap()->GetNofMedia() == 0) FillMediumMap();
864
865 // Set world to geometry services
866 fGeometryServices->SetWorld(
867 G4TransportationManager::GetTransportationManager()
868 ->GetNavigatorForTracking()
869 ->GetWorldVolume());
870
871 if (VerboseLevel() > 1)
872 G4cout << "TG4GeometryManager::FinishGeometry done" << G4endl;
873}
874
875//_____________________________________________________________________________
877 const G4String& volName)
878{
880
881 TG4RadiatorDescription* radiatorDescription =
882 new TG4RadiatorDescription(volName);
883 fRadiators.push_back(radiatorDescription);
884
885 return radiatorDescription;
886}
887
888//_____________________________________________________________________________
890 const TG4G3CutVector& cuts, const TG4G3ControlVector& controls) const
891{
893
894 if (VerboseLevel() > 1)
895 G4cout << "TG4GeometryManager::SetUserLimits" << G4endl;
896
897 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
898
899 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
900 G4LogicalVolume* lv = (*lvStore)[i];
901 TG4Medium* medium = fGeometryServices->GetMediumMap()->GetMedium(lv, false);
902
903 if (!medium) continue;
904
905 // get limits if already exist
906 TG4Limits* tg4Limits = 0;
907 G4UserLimits* limits = medium->GetLimits();
908 tg4Limits = fGeometryServices->GetLimits(limits, cuts, controls);
909
910 // get tracking medium name
911 G4String name = medium->GetName();
912
913 if (tg4Limits) {
914 tg4Limits->SetName(name);
915 }
916 else {
917 // Check if the step below is needed
918 tg4Limits = fGeometryServices->FindLimits2(name, true);
919 if (!tg4Limits) {
920 tg4Limits = new TG4Limits(name, cuts, controls);
921 }
922 }
923
924 // set new limits back to medium
925 medium->SetLimits(tg4Limits);
926
927 // inactivate max step defined by user
928 // if its activation was not asked explicitely
929 if (!fIsUserMaxStep) tg4Limits->SetMaxAllowedStep(DBL_MAX);
930
931 // limit max step for low density materials (< AIR)
933 lv->GetMaterial()->GetDensity() < fLimitDensity)
934 tg4Limits->SetMaxAllowedStep(fMaxStepInLowDensityMaterials);
935
936 // set max step the default value
937 tg4Limits->SetDefaultMaxAllowedStep();
938
939 // update controls in limits according to the setup
940 // in the passed vector
941 tg4Limits->Update(controls);
942
943 // set limits to logical volume
944 lv->SetUserLimits(tg4Limits);
945 }
946
947 if (VerboseLevel() > 1)
948 G4cout << "TG4GeometryManager::SetUserLimits done" << G4endl;
949}
950
951//_____________________________________________________________________________
952void TG4GeometryManager::SetIsLocalField(G4bool isLocalField)
953{
955
956 if (VerboseLevel() > 1)
957 G4cout << "TG4GeometryManager::SetIsLocalField: " << std::boolalpha
958 << isLocalField << G4endl;
959
960 fIsLocalField = isLocalField;
961}
962
963//_____________________________________________________________________________
965{
967
968 if (VerboseLevel() > 1)
969 G4cout << "TG4GeometryManager::SetIsZeroField: " << std::boolalpha
970 << isZeroField << G4endl;
971
972 fIsZeroField = isZeroField;
973}
974
975//_____________________________________________________________________________
976void TG4GeometryManager::SetIsMonopoleField(G4bool isMonopoleField)
977{
979
980 if (VerboseLevel() > 1)
981 G4cout << "TG4GeometryManager::SetIsMonopoleField: " << std::boolalpha
982 << isMonopoleField << G4endl;
983
984 fIsMonopoleField = isMonopoleField;
985}
986
987//_____________________________________________________________________________
988void TG4GeometryManager::SetIsUserMaxStep(G4bool isUserMaxStep)
989{
991
992 if (VerboseLevel() > 0)
993 G4cout << "TG4GeometryManager::SetIsUserMaxStep: " << std::boolalpha
994 << isUserMaxStep << G4endl;
995
996 fIsUserMaxStep = isUserMaxStep;
997}
998
999//_____________________________________________________________________________
1001{
1003
1004 if (VerboseLevel() > 0)
1005 G4cout << "TG4GeometryManager::SetIsMaxStepInLowDensityMaterials: "
1006 << std::boolalpha << isMaxStep << G4endl;
1007
1009}
1010
1011//_____________________________________________________________________________
1013 TG4VUserRegionConstruction* userRegionConstruction)
1014{
1016
1017 fUserRegionConstruction = userRegionConstruction;
1018}
1019
1020//_____________________________________________________________________________
1022 TG4VUserPostDetConstruction* userPostDetConstruction)
1023{
1025
1026 fUserPostDetConstruction = userPostDetConstruction;
1027}
1028
1029//_____________________________________________________________________________
1031 G4EquationOfMotion* equation, G4String volumeName)
1032{
1033 auto fieldBuilder = G4FieldBuilder::Instance();
1034 fieldBuilder->SetUserEquationOfMotion(equation, volumeName);
1035}
1036
1037//_____________________________________________________________________________
1039 G4MagIntegratorStepper* stepper, G4String volumeName)
1040{
1041 auto fieldBuilder = G4FieldBuilder::Instance();
1042 fieldBuilder->SetUserStepper(stepper, volumeName);
1043}
1044
1045//_____________________________________________________________________________
1047{
1050 if (VerboseLevel() > 0 && fgFields) {
1051 for (G4int i = 0; i < G4int(fgFields->size()); ++i) {
1052 auto f = fgFields->at(i); // this is a TG4Field
1053 // we need to get the containing TG4MagneticField in order to print statistics
1054 auto mgfield = dynamic_cast<TG4MagneticField*>(f->GetG4Field());
1055 if (mgfield) {
1056 mgfield->PrintStatistics();
1057 }
1058 }
1059 }
1060}
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.
G4LogicalVolume * FindLogicalVolume(const G4String &name, G4bool silent=false) const
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