25#include <G4Element.hh>
26#include <G4LogicalVolume.hh>
27#include <G4ReflectionFactory.hh>
28#include <G4Threading.hh>
29#include <G4LogicalVolumeStore.hh>
30#include <G4Material.hh>
31#include <G4MaterialPropertiesTable.hh>
32#include <G4MaterialPropertyVector.hh>
33#include <G4PhysicalVolumeStore.hh>
34#include <G4UserLimits.hh>
35#include <G4VPhysicalVolume.hh>
37#include <G3EleTable.hh>
42#include <TGeoMatrix.h>
45#include "RootGM/volumes/Placement.h"
50#include <G4SystemOfUnits.hh>
79 "Cannot create two instances of singleton.");
110 if (G4StrUtil::contains(lvName, gSeparator))
118 G4double , G4double z,
const G4Element* element)
const
124 G4double ze = element->GetZ();
130 ax = 1.01 * g / mole;
153 G4double , G4double ,
const G4Element* )
const
164 G4int nofElements, G4double density,
const G4Material* material)
const
170 G4int ne = material->GetNumberOfElements();
173 G4double diff = std::abs(density - dm) / (density + dm) * 2.;
183 G4int nmat, G4double* a, G4double* wmat)
const
189 G4double* weight =
new G4double[abs(nmat)];
194 for (i = 0; i < abs(nmat); i++) {
196 aMol += wmat[i] * a[i];
200 "Total molecular weight = 0.");
202 for (i = 0; i < abs(nmat); i++) {
204 weight[i] = wmat[i] * a[i] / aMol;
208 for (G4int j = 0; j < nmat; j++) weight[j] = wmat[j];
230 if (!RootGM::Placement::GetIncludeAssembliesInNames())
return;
231 const char prefix = RootGM::Placement::GetNamePrefix();
232 const char separator = RootGM::Placement::GetNameSeparator();
234 const G4PhysicalVolumeStore* store = G4PhysicalVolumeStore::GetInstance();
236 for (G4VPhysicalVolume* pv : *store)
237 maxId = std::max(maxId, pv->GetInstanceID());
238 if (maxId < 0)
return;
241 for (G4VPhysicalVolume* pv : *store) {
242 const G4String& name = pv->GetName();
243 if (name.size() < 2 || name[0] != prefix)
continue;
246 for (std::size_t start = 1; start <= name.size();) {
247 const std::size_t sep = name.find(separator, start);
248 levels.
fNames.push_back(name.substr(
249 start, sep == G4String::npos ? G4String::npos : sep - start));
251 if (sep == G4String::npos)
break;
254 if (levels.
fNames.size() < 2)
continue;
257 for (std::size_t i = 0; i + 1 < levels.
fNames.size(); ++i) {
258 G4String& part = levels.
fNames[i];
259 const std::size_t us = part.rfind(
'_');
260 if (us == G4String::npos || us + 1 >= part.size())
continue;
261 if (part.find_first_not_of(
"0123456789", us + 1) != G4String::npos)
continue;
262 levels.
fCopyNos[i] = std::atoi(part.c_str() + us + 1);
269 G4cout <<
"### AssemblyLevels constructed." << G4endl;
276 const G4VPhysicalVolume* pv)
const
284 const G4int
id = pv->GetInstanceID();
292 Float_t* array, G4int size, G4bool copyValues)
const
297 G4double* doubleArray;
299 doubleArray =
new G4double[size];
301 for (G4int i = 0; i < size; i++) doubleArray[i] = array[i];
312 Double_t* array, G4int size, G4bool copyValues)
const
317 G4double* doubleArray;
319 doubleArray =
new G4double[size];
321 for (G4int i = 0; i < size; i++) doubleArray[i] = array[i];
335 G4String cutName = name;
336 G4int i = cutName.length();
337 while (cutName[--i] ==
' ') cutName = cutName.substr(0, i);
347 G4String cutName = name;
348 cutName = cutName.substr(0, cutName.find(
'$'));
355 const G4String& volumePath, G4String& volName, G4int& copyNo)
const
359 G4String path(volumePath);
361 G4int npos1 = path.find(
'/');
362 G4int npos2 = path.find(
'_');
363 G4int npos3 = path.find(
'/', 2);
364 if (npos3 < 0) npos3 = path.length();
366 volName = path.substr(npos1 + 1, npos2 - npos1 - 1);
367 G4String copyNoStr = path.substr(npos2 + 1, npos3 - npos2);
368 std::istringstream in(copyNoStr);
371 return path.substr(npos3, path.length() - npos3);
381 if (
fIsG3toG4 && G4StrUtil::contains(name, gSeparator)) {
382 fgBuffer = name.substr(0, name.find(gSeparator));
397 if (G4Threading::IsWorkerThread())
return;
399 for (
auto lv : *G4LogicalVolumeStore::GetInstance()) {
400 auto constituent = G4ReflectionFactory::Instance()->GetConstituentLV(lv);
411 if (!G4Threading::IsWorkerThread()) {
412 auto constituent = G4ReflectionFactory::Instance()->GetConstituentLV(lv);
413 if (constituent)
return constituent->GetName();
415 return lv->GetName();
427 EMCOpSurfaceModel model)
const
433 case kGlisur:
return glisur;
434 case kUnified:
return unified;
435 case kLUT:
return LUT;
436 case kDAVIS:
return DAVIS;
437 case kdichroic:
return dichroic;
441 "Unknown optical surface model, return Glisur.");
453 case kDielectric_metal:
return dielectric_metal;
454 case kDielectric_dielectric:
return dielectric_dielectric;
455 case kDielectric_LUT:
return dielectric_LUT;
456 case kDielectric_LUTDAVIS:
return dielectric_LUTDAVIS;
457 case kDielectric_dichroic:
return dielectric_dichroic;
458 case kFirsov:
return firsov;
459 case kXray:
return x_ray;
463 "Unknown optical surface type, return dielectric_metal.");
464 return dielectric_metal;
470 EMCOpSurfaceFinish finish)
const
476 case kPolished:
return polished;
477 case kPolishedfrontpainted:
return polishedfrontpainted;
478 case kPolishedbackpainted:
return polishedbackpainted;
480 case kGround:
return ground;
481 case kGroundfrontpainted:
return groundfrontpainted;
482 case kGroundbackpainted:
return groundbackpainted;
484 case kPolishedlumirrorair:
return polishedlumirrorair;
485 case kPolishedlumirrorglue:
return polishedlumirrorglue;
487 case kPolishedair:
return polishedair;
488 case kPolishedteflonair:
return polishedteflonair;
489 case kPolishedtioair:
return polishedtioair;
490 case kPolishedtyvekair:
return polishedtyvekair;
491 case kPolishedvm2000air:
return polishedvm2000air;
492 case kPolishedvm2000glue:
return polishedvm2000glue;
494 case kEtchedlumirrorair:
return etchedlumirrorair;
495 case kEtchedlumirrorglue:
return etchedlumirrorglue;
496 case kEtchedair:
return etchedair;
497 case kEtchedteflonair:
return etchedteflonair;
498 case kEtchedtioair:
return etchedtioair;
499 case kEtchedtyvekair:
return etchedtyvekair;
500 case kEtchedvm2000air:
return etchedvm2000air;
501 case kEtchedvm2000glue:
return etchedvm2000glue;
502 case kGroundlumirrorair:
return groundlumirrorair;
503 case kGroundlumirrorglue:
return groundlumirrorglue;
504 case kGroundair:
return groundair;
505 case kGroundteflonair:
return groundteflonair;
506 case kGroundtioair:
return groundtioair;
507 case kGroundtyvekair:
return groundtyvekair;
508 case kGroundvm2000air:
return groundvm2000air;
509 case kGroundvm2000glue:
return groundvm2000glue;
511 case kRough_LUT:
return Rough_LUT;
512 case kRoughTeflon_LUT:
return RoughTeflon_LUT;
513 case kRoughESR_LUT:
return RoughESR_LUT;
514 case kRoughESRGrease_LUT:
return RoughESRGrease_LUT;
516 case kPolished_LUT:
return Polished_LUT;
517 case kPolishedTeflon_LUT:
return PolishedTeflon_LUT;
518 case kPolishedESR_LUT:
return PolishedESR_LUT;
519 case kPolishedESRGrease_LUT:
return PolishedESRGrease_LUT;
521 case kDetector_LUT:
return Detector_LUT;
525 "Unknown optical surface finish, return polished.");
532 const G4Transform3D& transform, TGeoHMatrix& matrix)
const
536 Double_t* translation =
new Double_t[3];
537 Double_t* rotation =
new Double_t[9];
538 for (G4int i = 0; i < 3; i++)
539 for (G4int j = 0; j < 3; j++) {
540 rotation[i * 3 + j] = transform(i, j);
541 translation[i] = transform(i, 3) / cm;
543 matrix.SetTranslation(translation);
544 matrix.SetRotation(rotation);
545 delete[] translation;
556 G4int nofMaterials = matNames.size();
557 if (nofMaterials != G4int(matWeights.size())) {
559 "Different number of material names and weigths.");
563 G4cout <<
"Nof of materials to be mixed: " << nofMaterials << G4endl;
567 std::vector<G4Material*> matVector;
569 for (im = 0; im < nofMaterials; im++) {
571 G4Material* material = G4Material::GetMaterial(matNames[im]);
572 matVector.push_back(material);
576 G4Material* mixture =
new G4Material(name, density, nofMaterials);
577 for (im = 0; im < nofMaterials; im++) {
578 G4Material* material = matVector[im];
579 G4double fraction = matWeights[im];
580 mixture->AddMaterial(material, fraction);
593 if (limits) limits->
Print();
604 G4cout << lv->GetName() <<
" ";
608 G4cout <<
"has not the limits set." << G4endl;
619 G4cout <<
" GEANT4 Geometry statistics: " << G4endl <<
" "
622 <<
" physical volumes" << G4endl <<
" " << std::setw(5)
623 << G4Material::GetNumberOfMaterials() <<
" materials" << G4endl
625 <<
" user limits" << G4endl;
635 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
637 G4cout <<
"Logical volume store: " << G4endl;
639 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
641 G4LogicalVolume* lv = (*lvStore)[i];
643 void* address = lv->GetMaterial();
644 G4cout <<
"Logical volume: " << G4endl;
645 G4cout <<
" " << std::setw(5) << i <<
" " << lv <<
" " << lv->GetName()
646 <<
" " << std::setw(5) << lv->GetNoDaughters() <<
" daughters"
647 <<
" limits: " << lv->GetUserLimits()
648 <<
" material: " << lv->GetMaterial()->GetName() <<
" " << address
651 for (
size_t j = 0; j < lv->GetNoDaughters(); j++) {
652 void* addressd = lv->GetDaughter(j)->GetLogicalVolume()->GetMaterial();
653 G4cout <<
" Daughter: " << std::setw(5) << j <<
" "
654 << lv->GetDaughter(j) <<
" " << lv->GetDaughter(j)->GetName()
655 <<
" of LV: " << lv->GetDaughter(j)->GetLogicalVolume() <<
" "
656 << lv->GetDaughter(j)->GetLogicalVolume()->GetName()
657 <<
" copy no: " << lv->GetDaughter(j)->GetCopyNo()
659 << lv->GetDaughter(j)->GetLogicalVolume()->GetMaterial()->GetName()
660 <<
" " << addressd << G4endl;
670 G4PhysicalVolumeStore* pvStore = G4PhysicalVolumeStore::GetInstance();
672 for (G4int i = 0; i < G4int(pvStore->size()); i++) {
673 G4VPhysicalVolume* pv = (*pvStore)[i];
674 G4cout << i <<
"th volume name=" << pv->GetName()
676 <<
" copyNo=" << pv->GetCopyNo() << G4endl;
685 const G4ElementTable* elementTable = G4Element::GetElementTable();
687 G4cout <<
"Element table: " << G4endl;
689 for (G4int i = 0; i < G4int(elementTable->size()); i++) {
691 G4Element* element = (*elementTable)[i];
692 G4cout <<
" " << std::setw(5) << i <<
"th element:"
693 <<
" " << element << G4endl;
703 const G4MaterialTable* matTable = G4Material::GetMaterialTable();
714 const G4MaterialTable* matTable = G4Material::GetMaterialTable();
715 for (G4int i = 0; i < G4int(matTable->size()); i++) {
716 if ((*matTable)[i] && (*matTable)[i]->GetMaterialPropertiesTable()) {
718 G4cout << (*matTable)[i]->GetName()
719 <<
" material properties table: " << G4endl;
720 (*matTable)[i]->GetMaterialPropertiesTable()->DumpTable();
726 TG4OpSurfaceMap::const_iterator it;
728 if (it->second && it->second->GetMaterialPropertiesTable()) {
731 <<
" optical surface material properties table: " << G4endl;
732 it->second->GetMaterialPropertiesTable()->DumpTable();
754 TString(cutName.c_str()) +
" not defined.");
758 G4cout <<
"Cut " << cutName << G4endl;
759 G4cout <<
"Medium ID"
761 <<
"cutValue(MeV)" << G4endl;
762 for (G4int i = 0; i <
fMediumMap->GetNofMedia(); i++) {
767 G4cout << i + 1 <<
" " << cutValue << G4endl;
785 TString(controlName.c_str()) +
" not defined.");
789 G4cout <<
"Control " << controlName << G4endl;
790 G4cout <<
"Medium ID"
792 <<
"controlValue" << G4endl;
793 for (G4int i = 0; i <
fMediumMap->GetNofMedia(); i++) {
799 G4cout << i + 1 <<
" " << controlValue << G4endl;
810 gSeparator = separator;
829 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
832 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
833 G4LogicalVolume* lv = (*lvStore)[i];
845 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
846 return lvStore->size();
854 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
857 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
858 counter += ((*lvStore)[i])->GetNoDaughters();
869 if (!limits)
return 0;
874 "TG4GeometryServices",
"GetLimits(.)",
"Wrong limits type");
888 if (!limits)
return 0;
892 if (tg4Limits)
return tg4Limits;
897 tg4Limits =
new TG4Limits(*limits, cuts, controls);
903 "TG4GeometryServices",
"GetLimits(..)",
"Wrong limits type.");
909 const G4String& name, G4bool silent)
const
911 std::vector<G4LogicalVolume*> result;
912 for (
auto lv : *G4LogicalVolumeStore::GetInstance()) {
916 if (result.empty()) {
917 for (
auto lv : *G4LogicalVolumeStore::GetInstance()) {
918 if (lv->GetName() == name) result.push_back(lv);
921 if (result.empty() && !silent) {
923 "Logical volume " + TString(name) +
" not found.");
930 const G4String& name, G4bool silent)
const
934 for (
auto lv : volumes) {
937 return volumes.empty() ? nullptr : volumes.front();
942 const G4String& name, G4int copyNo, G4bool silent)
const
947 G4PhysicalVolumeStore* pvStore = G4PhysicalVolumeStore::GetInstance();
949 for (G4int i = 0; i < G4int(pvStore->size()); i++) {
950 G4VPhysicalVolume* pv = (*pvStore)[i];
956 if (
UserVolumeName(pv->GetName()) == name && pv->GetCopyNo() == copyNo)
962 "Physical volume " + TString(name) +
" not found.");
969 const G4String& name, G4int copyNo, G4LogicalVolume* mlv, G4bool silent)
const
974 for (
size_t i = 0; i < mlv->GetNoDaughters(); i++) {
975 G4VPhysicalVolume* dpv = mlv->GetDaughter(i);
976 if (
UserVolumeName(dpv->GetName()) == name && dpv->GetCopyNo() == copyNo)
982 "Physical volume " + TString(name) +
" not found.");
989 const G4String& name, G4bool silent)
const
993 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
995 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
996 G4LogicalVolume* lv = (*lvStore)[i];
998 if (limits && limits->
GetName() == name)
return limits;
1003 "Limits " + TString(name) +
" not found.");
1010 const G4String& name, G4bool silent)
const
1015 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
1017 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
1018 G4LogicalVolume* lv = (*lvStore)[i];
1019 if (!
dynamic_cast<TG4Limits*
>(lv->GetUserLimits())) {
1023 if (limits && limits->
GetName() == name)
return limits;
1028 "Limits " + TString(name) +
" not found.");
1035 const G4Material* material, G4bool silent)
const
1041 if (!medium)
return 0;
1054 if (!medium)
return 0;
1056 return medium->
GetID();
1066 G4int nofElements = material->GetNumberOfElements();
1067 if (nofElements > 1) {
1073 for (G4int i = 0; i < nofElements; i++) {
1074 G4double aOfElement = material->GetElement(i)->GetA();
1075 G4double massFraction = material->GetFractionVector()[i];
1080 a = material->GetA();
1093 G4int nofElements = material->GetNumberOfElements();
1094 if (nofElements > 1) {
1100 for (G4int i = 0; i < nofElements; i++) {
1101 G4double zOfElement = material->GetElement(i)->GetZ();
1102 G4double massFraction = material->GetFractionVector()[i];
1103 z += zOfElement * massFraction;
1107 z = material->GetZ();
1114 G4double a, G4double z, G4double density)
const
1119 const G4MaterialTable* kpMatTable = G4Material::GetMaterialTable();
1121 for (G4int i = 0; i < G4int(G4Material::GetNumberOfMaterials()); i++) {
1123 G4Material* material = (*kpMatTable)[i];
1136 G4double* a, G4double* z, G4double density, G4int nmat, G4double* wmat)
const
1144 G4Material* found = 0;
1145 for (G4int i = 0; i < G4int(G4Material::GetNumberOfMaterials()); i++) {
1147 G4Material* material = (*G4Material::GetMaterialTable())[i];
1148 G4int nofElements = material->GetNumberOfElements();
1153 G4bool equal =
true;
1154 for (G4int ie = 0; ie < nofElements; ie++) {
1156 G4double we = (material->GetFractionVector())[ie];
Definition of the TG4G3ControlVector class.
Definition of the TG4G3Units class.
Definition of the TG4GeometryServices class.
Definition of the TG4Globals class and basic container types.
Definition of the TG4IntMap class.
Definition of the TG4Limits class.
Definition of the TG4MediumMap class.
Definition of the TG4Medium class.
Definition of the TG4NameMap class.
Vector of control process values with convenient set/get methods.
static TG4G3Control GetControl(const G4String &controlName)
Vector of kinetic energy cut values with convenient set/get methods.
static TG4G3Cut GetCut(const G4String &cutName)
static G4double AtomicWeight()
static G4double InverseMassDensity()
static G4double InverseAtomicWeight()
Services for accessing to Geant4 geometry.
void PrintControls(const G4String &controlName) const
G4String CutVolumePath(const G4String &volumePath, G4String &volName, G4int ©No) const
void PrintLogicalVolumeStore() const
static const G4double fgkDensityTolerance
density tolerance (percentual)
static TG4GeometryServices * fgInstance
this instance
TG4OpSurfaceMap * fOpSurfaceMap
map of optical surfaces names to their objects
void PrintPhysicalVolumeStore() const
TG4MediumMap * fMediumMap
map of madia
TG4Limits * FindLimits(const G4String &name, G4bool silent=false) const
G4Material * FindMaterial(G4double a, G4double z, G4double density) const
virtual ~TG4GeometryServices()
G4OpticalSurfaceFinish SurfaceFinish(EMCOpSurfaceFinish finish) const
G4double * ConvertAtomWeight(G4int nmat, G4double *a, G4double *wmat) const
G4int GetMediumId(G4LogicalVolume *lv) const
void BuildAssemblyLevels()
Int_t NofG4PhysicalVolumes() const
G4Material * MixMaterials(G4String name, G4double density, const TG4StringVector &matNames, const TG4doubleVector &matWeights)
G4bool IsG3Volume(const G4String &lvName) const
G4double * CreateG4doubleArray(Float_t *array, G4int size, G4bool copyValues=true) const
void PrintStatistics(G4bool open, G4bool close) const
void PrintElementTable() const
G4LogicalVolume * FindLogicalVolume(const G4String &name, G4bool silent=false) const
void BuildConstituentVolumes()
const G4String & UserVolumeName(const G4String &name) const
G4String CutName(const char *name) const
G4SurfaceType SurfaceType(EMCOpSurfaceType surfType) const
TG4Limits * FindLimits2(const G4String &name, G4bool silent=false) const
Int_t NofG3Volumes() const
Int_t NofG4LogicalVolumes() const
void PrintMaterials() const
G4bool CompareElement(G4double a, G4double z, const G4Element *elem) const
std::vector< TG4AssemblyLevels > fAssemblyLevels
assembly levels per placement, indexed by its Geant4 instance id
void PrintLimits(const G4String &name) const
void PrintMaterialsProperties() const
G4bool fAccountAssemblyLevels
option to account assembly levels in the volume level hierarchy
G4VPhysicalVolume * FindPhysicalVolume(const G4String &name, G4int copyNo, G4bool silent=false) const
TG4Limits * GetLimits(G4UserLimits *limits) const
G4bool fIsG3toG4
info if user geometry is defined via G3toG4
std::map< G4LogicalVolume *, G4LogicalVolume * > fConstituentVolumes
Master-built reflection provenance, read-only during tracking.
G4VPhysicalVolume * FindDaughter(const G4String &name, G4int copyNo, G4LogicalVolume *mlv, G4bool silent=false) const
void SetG3toG4Separator(char separator)
const G4String & GetConstituentVolumeName(G4LogicalVolume *lv) const
G4VPhysicalVolume * fWorld
top physical volume (world)
std::vector< G4LogicalVolume * > FindLogicalVolumes(const G4String &name, G4bool silent=false) const
G4bool fAssemblyLevelsBuilt
whether fAssemblyLevels has been filled
static const G4double fgkAZTolerance
A,Z tolerance.
G4double GetEffA(G4Material *material) const
G4bool CompareMaterial(G4int nofElements, G4double density, const G4Material *material) const
G4String CutMaterialName(const char *name) const
void PrintVolumeLimits(const G4String &volumeName) const
G4OpticalSurfaceModel SurfaceModel(EMCOpSurfaceModel model) const
void PrintCuts(const G4String &cutName) const
const TG4AssemblyLevels & GetAssemblyLevels(const G4VPhysicalVolume *pv) const
void Convert(const G4Transform3D &transform, TGeoHMatrix &matrix) const
G4double GetEffZ(G4Material *material) const
static G4String fgBuffer
string buffer
static void PrintStars(G4bool emptyLineFirst)
static void Warning(const TString &className, const TString &methodName, const TString &text)
static void Exception(const TString &className, const TString &methodName, const TString &text)
Extended G4UserLimits class.
const TG4G3CutVector * GetCutVector() const
static G4int GetNofLimits()
const TG4G3ControlVector * GetControlVector() const
The map of media to logical volumes.
Helper class to keep medium data.
G4UserLimits * GetLimits() const
virtual G4int VerboseLevel() const
TG4Verbose(const G4String &cmdName)
std::map< G4String, G4OpticalSurface * > TG4OpSurfaceMap
The map between optical surfaces names and their objects.
std::vector< G4String > TG4StringVector
std::vector< G4double > TG4doubleVector
TG4G3Cut
Enumeration for G3 types of kinetic energy cuts.
TG4G3Control
Enumeration for G3 types of physics processes controls.
@ kNoG3Cuts
Invalid value.
@ kNoG3Controls
No process control.
std::vector< G4int > fCopyNos
-1 where the Geant4 copy number applies
std::vector< G4String > fNames
outermost first; last is the placed volume