Geant4 VMC Version 6.8
Loading...
Searching...
No Matches
TG4GeometryServices.cxx
Go to the documentation of this file.
1//------------------------------------------------
2// The Geant4 Virtual Monte Carlo package
3// Copyright (C) 2007 - 2014 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 "TG4GeometryServices.h"
16#include "TG4G3ControlVector.h"
17#include "TG4G3Units.h"
18#include "TG4Globals.h"
19#include "TG4IntMap.h"
20#include "TG4Limits.h"
21#include "TG4Medium.h"
22#include "TG4MediumMap.h"
23#include "TG4NameMap.h"
24
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>
36#ifdef USE_G3TOG4
37#include <G3EleTable.hh>
38#include <G3toG4.hh>
39#endif
40
41#include "Riostream.h"
42#include <TGeoMatrix.h>
43
44#ifdef USE_VGM
45#include "RootGM/volumes/Placement.h"
46#endif
47
48// Moved after Root includes to avoid shadowed variables
49// generated from short units names
50#include <G4SystemOfUnits.hh>
51
52#include <algorithm>
53#include <cstdlib>
54#include <iomanip>
55#include <math.h>
56#include <vector>
57
59thread_local G4String TG4GeometryServices::fgBuffer = "";
60const G4double TG4GeometryServices::fgkAZTolerance = 0.001;
61const G4double TG4GeometryServices::fgkDensityTolerance = 0.005;
62
63//_____________________________________________________________________________
65 : TG4Verbose("geometryServices"),
66 fIsG3toG4(false),
68 fMediumMap(0),
70 fWorld(0),
74{
76
77 if (fgInstance) {
78 TG4Globals::Exception("TG4GeometryServices", "TG4GeometryServices",
79 "Cannot create two instances of singleton.");
80 }
81
84
85 fgInstance = this;
86}
87
88//_____________________________________________________________________________
97
98//
99// private methods
100//
101
102#ifdef USE_G3TOG4
103//_____________________________________________________________________________
104G4bool TG4GeometryServices::IsG3Volume(const G4String& lvName) const
105{
109
110 if (G4StrUtil::contains(lvName, gSeparator))
111 return false;
112 else
113 return true;
114}
115
116//_____________________________________________________________________________
118 G4double /*a*/, G4double z, const G4Element* element) const
119{
122
123 G4double ae = element->GetA() * TG4G3Units::InverseAtomicWeight();
124 G4double ze = element->GetZ();
125
126 // g3tog4 can redefine A
127 G4double ax;
128 if (z < 1) {
129 // vacuum
130 ax = 1.01 * g / mole;
131 }
132 else
133 ax = G3Ele.GetEle(z)->GetA() * TG4G3Units::InverseAtomicWeight();
134
135 if (std::abs(ax - ae) < fgkAZTolerance && std::abs(z - ze) < fgkAZTolerance)
136 return true;
137 else
138 return false;
139}
140#else
141//_____________________________________________________________________________
142G4bool TG4GeometryServices::IsG3Volume(const G4String& /*lvName*/) const
143{
147
148 return false;
149}
150
151//_____________________________________________________________________________
153 G4double /*a*/, G4double /*z*/, const G4Element* /*element*/) const
154{
157
158 return false;
159}
160#endif
161
162//_____________________________________________________________________________
164 G4int nofElements, G4double density, const G4Material* material) const
165{
168
169 G4double dm = material->GetDensity() * TG4G3Units::InverseMassDensity();
170 G4int ne = material->GetNumberOfElements();
171
172 // density percentual difference
173 G4double diff = std::abs(density - dm) / (density + dm) * 2.;
174
175 if (nofElements == ne && diff < fgkDensityTolerance)
176 return true;
177 else
178 return false;
179}
180
181//_____________________________________________________________________________
183 G4int nmat, G4double* a, G4double* wmat) const
184{
188
189 G4double* weight = new G4double[abs(nmat)];
190
191 if (nmat < 0) {
192 G4double aMol = 0.;
193 G4int i;
194 for (i = 0; i < abs(nmat); i++) {
195 // total molecular weight
196 aMol += wmat[i] * a[i];
197 }
198 if (aMol == 0.) {
199 TG4Globals::Warning("TG4GeometryServices", "ConvertAtomWeight",
200 "Total molecular weight = 0.");
201 }
202 for (i = 0; i < abs(nmat); i++) {
203 // weight fractions
204 weight[i] = wmat[i] * a[i] / aMol;
205 }
206 }
207 else
208 for (G4int j = 0; j < nmat; j++) weight[j] = wmat[j];
209
210 return weight;
211}
212
213//
214// public methods
215//
216
217//_____________________________________________________________________________
219{
222
223 fAssemblyLevels.clear();
225
226 // Do nothing if accounting assembly levels is switched off
227 if (!fAccountAssemblyLevels) return;
228
229#ifdef USE_VGM
230 if (!RootGM::Placement::GetIncludeAssembliesInNames()) return;
231 const char prefix = RootGM::Placement::GetNamePrefix();
232 const char separator = RootGM::Placement::GetNameSeparator();
233
234 const G4PhysicalVolumeStore* store = G4PhysicalVolumeStore::GetInstance();
235 G4int maxId = -1;
236 for (G4VPhysicalVolume* pv : *store)
237 maxId = std::max(maxId, pv->GetInstanceID());
238 if (maxId < 0) return;
239 fAssemblyLevels.resize(maxId + 1);
240
241 for (G4VPhysicalVolume* pv : *store) {
242 const G4String& name = pv->GetName();
243 if (name.size() < 2 || name[0] != prefix) continue;
244
245 TG4AssemblyLevels levels;
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));
250 levels.fCopyNos.push_back(-1);
251 if (sep == G4String::npos) break;
252 start = sep + 1;
253 }
254 if (levels.fNames.size() < 2) continue;
255
256 // every component but the last is a collapsed node named "<volume>_<copyNo>"
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);
263 part.resize(us);
264 }
265 fAssemblyLevels[pv->GetInstanceID()] = levels;
266 }
267
268 if (VerboseLevel() > 1) {
269 G4cout << "### AssemblyLevels constructed." << G4endl;
270 }
271#endif
272}
273
274//_____________________________________________________________________________
276 const G4VPhysicalVolume* pv) const
277{
278 static const TG4AssemblyLevels kNone;
279
281 return kNone;
282 }
283
284 const G4int id = pv->GetInstanceID();
285 if (id < 0 || id >= G4int(fAssemblyLevels.size())) return kNone;
286
287 return fAssemblyLevels[id];
288}
289
290//_____________________________________________________________________________
292 Float_t* array, G4int size, G4bool copyValues) const
293{
296
297 G4double* doubleArray;
298 if (size > 0) {
299 doubleArray = new G4double[size];
300 if (copyValues) {
301 for (G4int i = 0; i < size; i++) doubleArray[i] = array[i];
302 }
303 }
304 else {
305 doubleArray = 0;
306 }
307 return doubleArray;
308}
309
310//_____________________________________________________________________________
312 Double_t* array, G4int size, G4bool copyValues) const
313{
316
317 G4double* doubleArray;
318 if (size > 0) {
319 doubleArray = new G4double[size];
320 if (copyValues) {
321 for (G4int i = 0; i < size; i++) doubleArray[i] = array[i];
322 }
323 }
324 else {
325 doubleArray = 0;
326 }
327 return doubleArray;
328}
329
330//_____________________________________________________________________________
331G4String TG4GeometryServices::CutName(const char* name) const
332{
334
335 G4String cutName = name;
336 G4int i = cutName.length();
337 while (cutName[--i] == ' ') cutName = cutName.substr(0, i);
338
339 return cutName;
340}
341
342//_____________________________________________________________________________
343G4String TG4GeometryServices::CutMaterialName(const char* name) const
344{
346
347 G4String cutName = name;
348 cutName = cutName.substr(0, cutName.find('$'));
349
350 return CutName(cutName);
351}
352
353//_____________________________________________________________________________
355 const G4String& volumePath, G4String& volName, G4int& copyNo) const
356{
358
359 G4String path(volumePath);
360
361 G4int npos1 = path.find('/');
362 G4int npos2 = path.find('_');
363 G4int npos3 = path.find('/', 2);
364 if (npos3 < 0) npos3 = path.length();
365
366 volName = path.substr(npos1 + 1, npos2 - npos1 - 1);
367 G4String copyNoStr = path.substr(npos2 + 1, npos3 - npos2);
368 std::istringstream in(copyNoStr);
369 in >> copyNo;
370
371 return path.substr(npos3, path.length() - npos3);
372}
373
374//_____________________________________________________________________________
375const G4String& TG4GeometryServices::UserVolumeName(const G4String& name) const
376{
379
380#ifdef USE_G3TOG4
381 if (fIsG3toG4 && G4StrUtil::contains(name, gSeparator)) {
382 fgBuffer = name.substr(0, name.find(gSeparator));
383 return fgBuffer;
384 }
385 else {
386 return name;
387 }
388#else
389 return name;
390#endif
391}
392
393//_____________________________________________________________________________
395{
396 // The factory is thread-local; workers do not construct these clones.
397 if (G4Threading::IsWorkerThread()) return;
398 fConstituentVolumes.clear();
399 for (auto lv : *G4LogicalVolumeStore::GetInstance()) {
400 auto constituent = G4ReflectionFactory::Instance()->GetConstituentLV(lv);
401 if (constituent) fConstituentVolumes.emplace(lv, constituent);
402 }
403}
404
405//_____________________________________________________________________________
406const G4String& TG4GeometryServices::GetConstituentVolumeName(G4LogicalVolume* lv) const
407{
408 auto it = fConstituentVolumes.find(lv);
409 if (it != fConstituentVolumes.end()) return it->second->GetName();
410 // Also support master-side queries before the geometry snapshot is built.
411 if (!G4Threading::IsWorkerThread()) {
412 auto constituent = G4ReflectionFactory::Instance()->GetConstituentLV(lv);
413 if (constituent) return constituent->GetName();
414 }
415 return lv->GetName();
416}
417
418//_____________________________________________________________________________
419G4String TG4GeometryServices::UserVolumeName(G4LogicalVolume* lv) const
420{
421 // Return by value: the string overload may return the shared Gsposp buffer.
423}
424
425//_____________________________________________________________________________
427 EMCOpSurfaceModel model) const
428{
430
431 // clang-format off
432 switch (model) {
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;
438 // clang-format on
439 default:
440 TG4Globals::Warning("TG4GeometryServices", "SurfaceModel",
441 "Unknown optical surface model, return Glisur.");
442 return glisur;
443 }
444}
445
446//_____________________________________________________________________________
447G4SurfaceType TG4GeometryServices::SurfaceType(EMCOpSurfaceType surfType) const
448{
450
451 // clang-format off
452 switch (surfType) {
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;
460 // clang-format on
461 default:
462 TG4Globals::Warning("TG4GeometryServices", "SurfaceType",
463 "Unknown optical surface type, return dielectric_metal.");
464 return dielectric_metal;
465 }
466}
467
468//_____________________________________________________________________________
470 EMCOpSurfaceFinish finish) const
471{
473
474 // clang-format off
475 switch (finish) {
476 case kPolished: return polished;
477 case kPolishedfrontpainted: return polishedfrontpainted;
478 case kPolishedbackpainted: return polishedbackpainted;
479 //
480 case kGround: return ground;
481 case kGroundfrontpainted: return groundfrontpainted;
482 case kGroundbackpainted: return groundbackpainted;
483 //
484 case kPolishedlumirrorair: return polishedlumirrorair;
485 case kPolishedlumirrorglue: return polishedlumirrorglue;
486 //
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;
493 //
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;
510 //
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;
515 //
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;
520 //
521 case kDetector_LUT: return Detector_LUT;
522 // clang-format on
523 default:
524 TG4Globals::Warning("TG4GeometryServices", "SurfaceFinish",
525 "Unknown optical surface finish, return polished.");
526 return polished;
527 }
528}
529
530//_____________________________________________________________________________
532 const G4Transform3D& transform, TGeoHMatrix& matrix) const
533{
535
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;
542 }
543 matrix.SetTranslation(translation);
544 matrix.SetRotation(rotation);
545 delete[] translation;
546 delete[] rotation;
547}
548
549//_____________________________________________________________________________
550G4Material* TG4GeometryServices::MixMaterials(G4String name, G4double density,
551 const TG4StringVector& matNames, const TG4doubleVector& matWeights)
552{
554
555 // number of materials to be mixed
556 G4int nofMaterials = matNames.size();
557 if (nofMaterials != G4int(matWeights.size())) {
558 TG4Globals::Exception("TG4GeometryServices", "MixMaterials",
559 "Different number of material names and weigths.");
560 }
561
562 if (VerboseLevel() > 1) {
563 G4cout << "Nof of materials to be mixed: " << nofMaterials << G4endl;
564 }
565
566 // fill vector of materials
567 std::vector<G4Material*> matVector;
568 G4int im;
569 for (im = 0; im < nofMaterials; im++) {
570 // material
571 G4Material* material = G4Material::GetMaterial(matNames[im]);
572 matVector.push_back(material);
573 }
574
575 // create the mixed 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);
581 }
582
583 return mixture;
584}
585
586//_____________________________________________________________________________
587void TG4GeometryServices::PrintLimits(const G4String& name) const
588{
590
591 TG4Limits* limits = FindLimits(name, true);
592
593 if (limits) limits->Print();
594}
595
596//_____________________________________________________________________________
597void TG4GeometryServices::PrintVolumeLimits(const G4String& volumeName) const
598{
601
602 for (auto lv : FindLogicalVolumes(volumeName, false)) {
603 TG4Limits* limits = GetLimits(lv->GetUserLimits());
604 G4cout << lv->GetName() << " ";
605 if (limits)
606 limits->Print();
607 else
608 G4cout << "has not the limits set." << G4endl;
609 }
610}
611
612//_____________________________________________________________________________
613void TG4GeometryServices::PrintStatistics(G4bool open, G4bool close) const
614{
616
617 if (open) TG4Globals::PrintStars(true);
618
619 G4cout << " GEANT4 Geometry statistics: " << G4endl << " "
620 << std::setw(5) << NofG4LogicalVolumes() << " logical volumes"
621 << G4endl << " " << std::setw(5) << NofG4PhysicalVolumes()
622 << " physical volumes" << G4endl << " " << std::setw(5)
623 << G4Material::GetNumberOfMaterials() << " materials" << G4endl
624 << " " << std::setw(5) << TG4Limits::GetNofLimits()
625 << " user limits" << G4endl;
626
627 if (close) TG4Globals::PrintStars(false);
628}
629
630//_____________________________________________________________________________
632{
634
635 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
636
637 G4cout << "Logical volume store: " << G4endl;
638
639 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
640
641 G4LogicalVolume* lv = (*lvStore)[i];
642
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
649 << G4endl;
650
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()
658 << " material: "
659 << lv->GetDaughter(j)->GetLogicalVolume()->GetMaterial()->GetName()
660 << " " << addressd << G4endl;
661 }
662 }
663}
664
665//_____________________________________________________________________________
667{
669
670 G4PhysicalVolumeStore* pvStore = G4PhysicalVolumeStore::GetInstance();
671
672 for (G4int i = 0; i < G4int(pvStore->size()); i++) {
673 G4VPhysicalVolume* pv = (*pvStore)[i];
674 G4cout << i << "th volume name=" << pv->GetName()
675 << " g3name=" << UserVolumeName(pv->GetName())
676 << " copyNo=" << pv->GetCopyNo() << G4endl;
677 }
678}
679
680//_____________________________________________________________________________
682{
684
685 const G4ElementTable* elementTable = G4Element::GetElementTable();
686
687 G4cout << "Element table: " << G4endl;
688
689 for (G4int i = 0; i < G4int(elementTable->size()); i++) {
690
691 G4Element* element = (*elementTable)[i];
692 G4cout << " " << std::setw(5) << i << "th element:"
693 << " " << element << G4endl;
694 }
695}
696
697//_____________________________________________________________________________
699{
701
702 // Dump materials
703 const G4MaterialTable* matTable = G4Material::GetMaterialTable();
704 G4cout << *matTable;
705}
706
707//_____________________________________________________________________________
709{
711
712 // Dump material properties tables
713 // associated with materials
714 const G4MaterialTable* matTable = G4Material::GetMaterialTable();
715 for (G4int i = 0; i < G4int(matTable->size()); i++) {
716 if ((*matTable)[i] && (*matTable)[i]->GetMaterialPropertiesTable()) {
717
718 G4cout << (*matTable)[i]->GetName()
719 << " material properties table: " << G4endl;
720 (*matTable)[i]->GetMaterialPropertiesTable()->DumpTable();
721 }
722 }
723
724 // Dump material properties tables
725 // associated with optical surfaces
726 TG4OpSurfaceMap::const_iterator it;
727 for (it = fOpSurfaceMap->begin(); it != fOpSurfaceMap->end(); it++) {
728 if (it->second && it->second->GetMaterialPropertiesTable()) {
729
730 G4cout << it->first
731 << " optical surface material properties table: " << G4endl;
732 it->second->GetMaterialPropertiesTable()->DumpTable();
733 }
734 }
735}
736
737//_____________________________________________________________________________
739{
741
742 fMediumMap->Print();
743}
744
745//_____________________________________________________________________________
746void TG4GeometryServices::PrintCuts(const G4String& cutName) const
747{
750
751 TG4G3Cut cut = TG4G3CutVector::GetCut(cutName);
752 if (cut == kNoG3Cuts) {
753 TG4Globals::Exception("TG4GeometryServices", "PrintCuts",
754 TString(cutName.c_str()) + " not defined.");
755 return;
756 }
757
758 G4cout << "Cut " << cutName << G4endl;
759 G4cout << "Medium ID"
760 << " "
761 << "cutValue(MeV)" << G4endl;
762 for (G4int i = 0; i < fMediumMap->GetNofMedia(); i++) {
763 TG4Medium* medium = fMediumMap->GetMedium(i + 1);
764 if (dynamic_cast<TG4Limits*>(medium->GetLimits())) {
765 G4double cutValue =
766 (*GetLimits(medium->GetLimits())->GetCutVector())[cut];
767 G4cout << i + 1 << " " << cutValue << G4endl;
768 }
769 else {
770 // G4cout << "Medium " << medium->GetName()
771 // << " has not TG4Limits " << G4endl;
772 }
773 }
774}
775
776//_____________________________________________________________________________
777void TG4GeometryServices::PrintControls(const G4String& controlName) const
778{
781
782 TG4G3Control control = TG4G3ControlVector::GetControl(controlName);
783 if (control == kNoG3Controls) {
784 TG4Globals::Exception("TG4GeometryServices", "PrintControls",
785 TString(controlName.c_str()) + " not defined.");
786 return;
787 }
788
789 G4cout << "Control " << controlName << G4endl;
790 G4cout << "Medium ID"
791 << " "
792 << "controlValue" << G4endl;
793 for (G4int i = 0; i < fMediumMap->GetNofMedia(); i++) {
794
795 TG4Medium* medium = fMediumMap->GetMedium(i + 1);
796 G4int controlValue =
797 (*GetLimits(medium->GetLimits())->GetControlVector())[control];
798
799 G4cout << i + 1 << " " << controlValue << G4endl;
800 }
801}
802
803#ifdef USE_G3TOG4
804//_____________________________________________________________________________
806{
809
810 gSeparator = separator;
811}
812#else
813//_____________________________________________________________________________
815{
818}
819#endif
820
821//_____________________________________________________________________________
823{
828
829 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
830
831 G4int counter = 0;
832 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
833 G4LogicalVolume* lv = (*lvStore)[i];
834 if (IsG3Volume(lv->GetName())) counter++;
835 }
836
837 return counter;
838}
839
840//_____________________________________________________________________________
842{
844
845 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
846 return lvStore->size();
847}
848
849//_____________________________________________________________________________
851{
853
854 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
855
856 G4int counter = 0;
857 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
858 counter += ((*lvStore)[i])->GetNoDaughters();
859 }
860
861 return counter;
862}
863
864//_____________________________________________________________________________
866{
868
869 if (!limits) return 0;
870
871 TG4Limits* tg4Limits = dynamic_cast<TG4Limits*>(limits);
872 if (!tg4Limits) {
874 "TG4GeometryServices", "GetLimits(.)", "Wrong limits type");
875 return 0;
876 }
877
878 return tg4Limits;
879}
880
881//_____________________________________________________________________________
883 const TG4G3CutVector& cuts, const TG4G3ControlVector& controls) const
884{
887
888 if (!limits) return 0;
889
890 TG4Limits* tg4Limits = dynamic_cast<TG4Limits*>(limits);
891
892 if (tg4Limits) return tg4Limits;
893
894 G4UserLimits* g4Limits = dynamic_cast<G4UserLimits*>(limits);
895
896 if (g4Limits) {
897 tg4Limits = new TG4Limits(*limits, cuts, controls);
898 delete limits;
899 return tg4Limits;
900 }
901
903 "TG4GeometryServices", "GetLimits(..)", "Wrong limits type.");
904 return 0;
905}
906
907//_____________________________________________________________________________
908std::vector<G4LogicalVolume*> TG4GeometryServices::FindLogicalVolumes(
909 const G4String& name, G4bool silent) const
910{
911 std::vector<G4LogicalVolume*> result;
912 for (auto lv : *G4LogicalVolumeStore::GetInstance()) {
913 if (UserVolumeName(lv) == name) result.push_back(lv);
914 }
915 // Preserve explicit lookup of a generated Geant4 name.
916 if (result.empty()) {
917 for (auto lv : *G4LogicalVolumeStore::GetInstance()) {
918 if (lv->GetName() == name) result.push_back(lv);
919 }
920 }
921 if (result.empty() && !silent) {
922 TG4Globals::Warning("TG4GeometryServices", "FindLogicalVolumes",
923 "Logical volume " + TString(name) + " not found.");
924 }
925 return result;
926}
927
928//_____________________________________________________________________________
930 const G4String& name, G4bool silent) const
931{
932 // Preserve the singular API for queries needing one representative.
933 auto volumes = FindLogicalVolumes(name, silent);
934 for (auto lv : volumes) {
935 if (GetConstituentVolumeName(lv) == lv->GetName()) return lv;
936 }
937 return volumes.empty() ? nullptr : volumes.front();
938}
939
940//_____________________________________________________________________________
942 const G4String& name, G4int copyNo, G4bool silent) const
943{
946
947 G4PhysicalVolumeStore* pvStore = G4PhysicalVolumeStore::GetInstance();
948
949 for (G4int i = 0; i < G4int(pvStore->size()); i++) {
950 G4VPhysicalVolume* pv = (*pvStore)[i];
951 // G4cout << i << "th volume "
952 // << pv->GetName() << " "
953 // << UserVolumeName(pv->GetName()) << " "
954 // << pv->GetCopyNo()
955 // << G4endl;
956 if (UserVolumeName(pv->GetName()) == name && pv->GetCopyNo() == copyNo)
957 return pv;
958 }
959
960 if (!silent) {
961 TG4Globals::Warning("TG4GeometryServices", "FindPhysicalVolume",
962 "Physical volume " + TString(name) + " not found.");
963 }
964 return 0;
965}
966
967//_____________________________________________________________________________
969 const G4String& name, G4int copyNo, G4LogicalVolume* mlv, G4bool silent) const
970{
973
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)
977 return dpv;
978 }
979
980 if (!silent) {
981 TG4Globals::Warning("TG4GeometryServices", "FindDaughter",
982 "Physical volume " + TString(name) + " not found.");
983 }
984 return 0;
985}
986
987//_____________________________________________________________________________
989 const G4String& name, G4bool silent) const
990{
992
993 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
994
995 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
996 G4LogicalVolume* lv = (*lvStore)[i];
997 TG4Limits* limits = GetLimits(lv->GetUserLimits());
998 if (limits && limits->GetName() == name) return limits;
999 }
1000
1001 if (!silent) {
1002 TG4Globals::Warning("TG4GeometryServices", "FindLimits",
1003 "Limits " + TString(name) + " not found.");
1004 }
1005 return 0;
1006}
1007
1008//_____________________________________________________________________________
1010 const G4String& name, G4bool silent) const
1011{
1014
1015 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
1016
1017 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
1018 G4LogicalVolume* lv = (*lvStore)[i];
1019 if (!dynamic_cast<TG4Limits*>(lv->GetUserLimits())) {
1020 continue;
1021 }
1022 TG4Limits* limits = GetLimits(lv->GetUserLimits());
1023 if (limits && limits->GetName() == name) return limits;
1024 }
1025
1026 if (!silent) {
1027 TG4Globals::Warning("TG4GeometryServices", "FindLimits",
1028 "Limits " + TString(name) + " not found.");
1029 }
1030 return 0;
1031}
1032
1033//_____________________________________________________________________________
1035 const G4Material* material, G4bool silent) const
1036{
1038
1039 // Get medium
1040 TG4Medium* medium = fMediumMap->GetMedium(material, !silent);
1041 if (!medium) return 0;
1042
1043 return FindLimits(medium->GetName(), silent);
1044}
1045
1046//_____________________________________________________________________________
1047G4int TG4GeometryServices::GetMediumId(G4LogicalVolume* lv) const
1048{
1051
1052 TG4Medium* medium = fMediumMap->GetMedium(lv, false);
1053
1054 if (!medium) return 0;
1055
1056 return medium->GetID();
1057}
1058
1059//_____________________________________________________________________________
1060G4double TG4GeometryServices::GetEffA(G4Material* material) const
1061{
1064
1065 G4double a = 0.;
1066 G4int nofElements = material->GetNumberOfElements();
1067 if (nofElements > 1) {
1068 // TG4Globals::Warning(
1069 // "TG4GeometryServices", "GetEffA",
1070 // "Effective A for material mixture (" + TString(material->GetName()) +
1071 // ") is used.");
1072
1073 for (G4int i = 0; i < nofElements; i++) {
1074 G4double aOfElement = material->GetElement(i)->GetA();
1075 G4double massFraction = material->GetFractionVector()[i];
1076 a += aOfElement * massFraction / (TG4G3Units::AtomicWeight());
1077 }
1078 }
1079 else {
1080 a = material->GetA();
1082 }
1083 return a;
1084}
1085
1086//_____________________________________________________________________________
1087G4double TG4GeometryServices::GetEffZ(G4Material* material) const
1088{
1091
1092 G4double z = 0.;
1093 G4int nofElements = material->GetNumberOfElements();
1094 if (nofElements > 1) {
1095 // TG4Globals::Warning(
1096 // "TG4GeometryServices", "GetEffZ",
1097 // "Effective Z for material mixture (" + TString(material->GetName()) +
1098 // ") is used.");
1099
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;
1104 }
1105 }
1106 else {
1107 z = material->GetZ();
1108 }
1109 return z;
1110}
1111
1112//_____________________________________________________________________________
1114 G4double a, G4double z, G4double density) const
1115{
1118
1119 const G4MaterialTable* kpMatTable = G4Material::GetMaterialTable();
1120
1121 for (G4int i = 0; i < G4int(G4Material::GetNumberOfMaterials()); i++) {
1122
1123 G4Material* material = (*kpMatTable)[i];
1124
1125 if (CompareElement(a, z, material->GetElement(0)) &&
1126 CompareMaterial(1, density, material))
1127
1128 return material;
1129 }
1130
1131 return 0;
1132}
1133
1134//_____________________________________________________________________________
1136 G4double* a, G4double* z, G4double density, G4int nmat, G4double* wmat) const
1137{
1140
1141 G4double* weight = ConvertAtomWeight(nmat, a, wmat);
1142
1143 // loop over materials
1144 G4Material* found = 0;
1145 for (G4int i = 0; i < G4int(G4Material::GetNumberOfMaterials()); i++) {
1146
1147 G4Material* material = (*G4Material::GetMaterialTable())[i];
1148 G4int nofElements = material->GetNumberOfElements();
1149
1150 if (CompareMaterial(nofElements, density, material)) {
1151
1152 // loop over elements
1153 G4bool equal = true;
1154 for (G4int ie = 0; ie < nofElements; ie++) {
1155
1156 G4double we = (material->GetFractionVector())[ie];
1157
1158 if (!CompareElement(a[ie], z[ie], material->GetElement(ie)) ||
1159 std::abs(weight[ie] - we) > fgkAZTolerance) {
1160
1161 equal = false;
1162 break;
1163 }
1164 }
1165 if (equal) {
1166 found = material;
1167 break;
1168 }
1169 }
1170 }
1171
1172 delete[] weight;
1173 return found;
1174}
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()
Definition TG4G3Units.h:123
static G4double InverseMassDensity()
Definition TG4G3Units.h:169
static G4double InverseAtomicWeight()
Definition TG4G3Units.h:175
Services for accessing to Geant4 geometry.
void PrintControls(const G4String &controlName) const
G4String CutVolumePath(const G4String &volumePath, G4String &volName, G4int &copyNo) 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
G4OpticalSurfaceFinish SurfaceFinish(EMCOpSurfaceFinish finish) const
G4double * ConvertAtomWeight(G4int nmat, G4double *a, G4double *wmat) const
G4int GetMediumId(G4LogicalVolume *lv) 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
G4LogicalVolume * FindLogicalVolume(const G4String &name, G4bool silent=false) const
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
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.
Definition TG4Limits.h:38
G4String GetName() const
Definition TG4Limits.h:129
const TG4G3CutVector * GetCutVector() const
Definition TG4Limits.h:141
static G4int GetNofLimits()
Definition TG4Limits.h:105
void Print() const
const TG4G3ControlVector * GetControlVector() const
Definition TG4Limits.h:147
The map of media to logical volumes.
Helper class to keep medium data.
Definition TG4Medium.h:29
G4UserLimits * GetLimits() const
Definition TG4Medium.h:99
G4int GetID() const
Definition TG4Medium.h:84
G4String GetName() const
Definition TG4Medium.h:89
virtual G4int VerboseLevel() const
Definition TG4Verbose.h:78
TG4Verbose(const G4String &cmdName)
std::map< G4String, G4OpticalSurface * > TG4OpSurfaceMap
The map between optical surfaces names and their objects.
std::vector< G4String > TG4StringVector
Definition TG4Globals.h:49
std::vector< G4double > TG4doubleVector
Definition TG4Globals.h:45
TG4G3Cut
Enumeration for G3 types of kinetic energy cuts.
Definition TG4G3Cut.h:22
TG4G3Control
Enumeration for G3 types of physics processes controls.
@ kNoG3Cuts
Invalid value.
Definition TG4G3Cut.h:80
@ 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