4 // See the class description in the header file.
6 #include "TG4GeometryServices.h"
7 #include "TG4VSensitiveDetector.h"
8 #include "TG4Globals.h"
11 #include <G4VSensitiveDetector.hh>
12 #include <G4LogicalVolumeStore.hh>
13 #include <G4LogicalVolume.hh>
14 #include <G4Material.hh>
17 TG4GeometryServices* TG4GeometryServices::fgInstance = 0;
19 TG4GeometryServices::TG4GeometryServices(TG4intVector* mediumIdVector,
24 TG4Globals::Exception(
25 "TG4GeometryServices: attempt to create two instances of singleton.");
28 fMediumIdVector = mediumIdVector;
34 TG4GeometryServices::TG4GeometryServices() {
36 TG4Globals::Exception(
37 "Attempt to copy TG4GeometryServices singleton.");
41 TG4GeometryServices::TG4GeometryServices(const TG4GeometryServices& right) {
43 TG4Globals::Exception(
44 "Attempt to copy TG4GeometryServices singleton.");
48 TG4GeometryServices::~TG4GeometryServices() {
52 //=============================================================================
56 //=============================================================================
59 TG4GeometryServices::operator=(const TG4GeometryServices& right)
61 // check assignement to self
62 if (this == &right) return *this;
64 TG4Globals::Exception(
65 "Attempt to assign TG4GeometryServices singleton.");
71 //=============================================================================
75 //=============================================================================
78 G4double* TG4GeometryServices::CreateG4doubleArray(Float_t* array,
81 // Converts Float_t* array to G4double*,
82 // !! The new array has to be deleted by user.
85 G4double* doubleArray;
87 doubleArray = new G4double[size];
88 for (G4int i=0; i<size; i++) doubleArray[i] = array[i];
97 G4String TG4GeometryServices::CutName(const char* name) const
99 // Removes spaces after the name if present.
102 G4String cutName = name;
103 G4int i = cutName.length();
104 while (cutName(--i) == ' ') cutName = cutName(0,i);
110 void TG4GeometryServices::G4ToG3VolumeName(G4String& name) const
112 // Cuts _copyNo extension added to logical volume name in case
113 // the logical volume was created by Gsposp method.
116 if (name.contains(gSeparator))
117 name = name(0,name.first(gSeparator));
121 G4Material* TG4GeometryServices::MixMaterials(G4String name, G4double density,
122 TG4StringVector* matNames, TG4doubleVector* matWeights)
124 // Creates a mixture of selected materials
127 // number of materials to be mixed
128 G4int nofMaterials = matNames->entries();
129 if (nofMaterials != matWeights->entries()) {
130 G4String text = "TG4GeometryServices::MixMaterials: ";
131 text = text + "different number of material names and weigths.";
132 TG4Globals::Exception(text);
135 // G4cout << "Nof of materials to be mixed: " << nofMaterials << G4endl;
137 // fill vector of materials
138 TG4MaterialVector matVector;
140 for (im=0; im< nofMaterials; im++) {
142 G4Material* material = G4Material::GetMaterial((*matNames)[im]);
143 matVector.insert(material);
146 // create the mixed material
147 G4Material* mixture = new G4Material(name, density, nofMaterials);
148 for (im=0; im< nofMaterials; im++) {
149 G4Material* material = matVector[im];
150 G4double fraction = (*matWeights)[im];
151 mixture->AddMaterial(material, fraction);
158 Int_t TG4GeometryServices::NofG3Volumes() const
160 // Returns the total number of logical volumes corresponding
162 // The logical volume that were created by Gsposp method
163 // with a generic name (name_copyNo) are NOT included.
166 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
169 for (G4int i=0; i<pLVStore->entries(); i++) {
170 G4LogicalVolume* lv = (*pLVStore)[i];
171 if (IsG3Volume(lv->GetName())) counter++;
178 Int_t TG4GeometryServices::NofG4LogicalVolumes() const
180 // Returns the total number of logical volumes in the geometry.
183 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
184 return pLVStore->entries();
188 Int_t TG4GeometryServices::NofG4PhysicalVolumes() const
190 // Returns the total number of physical volumes in the geometry.
193 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
196 for (G4int i=0; i<pLVStore->entries(); i++) {
197 counter += ((*pLVStore)[i])->GetNoDaughters();
204 Int_t TG4GeometryServices::NofSensitiveDetectors() const
206 // Returns the total number of sensitive detectors.
209 return TG4VSensitiveDetector::GetTotalNofSensitiveDetectors();
213 G4int TG4GeometryServices::GetVolumeID(const G4String& volName) const
215 // Returns the sensitive detector identifier.
216 // !! Gives exception in case logical volume is not associated with
217 // a sensitive detector.
220 G4String g4VolName = CutName(volName);
221 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
223 for (G4int i=0; i<pLVStore->entries(); i++) {
224 G4LogicalVolume* lv = pLVStore->at(i);
225 G4VSensitiveDetector* sd = lv->GetSensitiveDetector();
227 if ((sd) && (sd->GetName()==g4VolName)) {
228 TG4VSensitiveDetector* tsd = dynamic_cast<TG4VSensitiveDetector*>(sd);
232 TG4Globals::Exception(
233 "TG4GeometryServices::GetVolumeID: Unknown sensitive detector type");
239 G4String text = "TG4GeometryServices::VolId: Sensitive detector ";
240 text = text + g4VolName;
241 text = text + " is not defined.\n";
242 TG4Globals::Warning(text);
247 G4int TG4GeometryServices::GetVolumeID(G4LogicalVolume* logicalVolume) const
249 // Returns the sensitive detector ID of the specified
253 // sensitive detector ID
254 G4VSensitiveDetector* sd
255 = logicalVolume->GetSensitiveDetector();
257 TG4VSensitiveDetector* tsd = dynamic_cast<TG4VSensitiveDetector*>(sd);
261 TG4Globals::Exception(
262 "TG4GeometryServices::GetVolumeID: Unknown sensitive detector type");
267 G4String text = "TG4GeometryServices::GetVolumeID: \n";
268 text = text + " Volume " + logicalVolume->GetName();
269 text = text + " has not a sensitive detector.";
270 //TG4Globals::Exception(text);
271 TG4Globals::Warning(text);
277 G4String TG4GeometryServices::GetVolumeName(G4int volumeId) const
279 // Returns the name of the sensitive detector with the given identifier.
280 // Gives a warning in case logical volume is not associated with
281 // a sensitive detector.
284 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
286 for (G4int i=0; i<pLVStore->entries(); i++) {
287 G4LogicalVolume* lv = pLVStore->at(i);
288 G4VSensitiveDetector* sd = lv->GetSensitiveDetector();
292 TG4VSensitiveDetector* tsd = dynamic_cast<TG4VSensitiveDetector*>(sd);
296 TG4Globals::Exception(
297 "TG4GeometryServices::VolId: Unknown sensitive detector type");
300 if (sdID == volumeId) return sd->GetName();
304 G4String text = "TG4GeometryServices::VolName:\n";
305 text = text + " Sensitive detector with given id is not defined. \n";
306 TG4Globals::Warning(text);
311 G4LogicalVolume* TG4GeometryServices::GetLogicalVolume(G4int volumeId) const
313 // Finds the first logical volume with specified volumeId
314 // (sensitive detector ID) in G4LogicalVolumeStore.
317 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
319 for (G4int i=0; i<pLVStore->entries(); i++) {
320 G4LogicalVolume* lv = pLVStore->at(i);
321 if (GetVolumeID(lv) == volumeId) return lv;
324 G4String text = "TG4GeometryServices::GetLogicalVolume: \n";
325 text = text + " Logical volume with given ID does not exist.";
330 G4bool TG4GeometryServices::IsG3Volume(const G4String& lvName) const
332 // Returns true if the logical volume of given volumeName
333 // was not created by Gsposp method with a generic name
337 if (lvName.contains(gSeparator))
344 const G4String& TG4GeometryServices::GetMapSecond(const G4String& name)
346 // Returns the second string associated with the name in
350 return fNameMap->GetSecond(name);
354 G4int TG4GeometryServices::GetMediumId(G4Material* material) const
356 // Returns the second index for materials (having its origin in
357 // G4 tracking media concept)
360 return (*fMediumIdVector)[material->GetIndex()];
364 Int_t TG4GeometryServices::GetMediumId(G4int volumeId) const
366 // Return the material number for a given volume id
369 G4LogicalVolume* logicalVolume = GetLogicalVolume(volumeId);
371 G4Material* material = logicalVolume->GetMaterial();
373 return GetMediumId(material);
377 G4double TG4GeometryServices::GetEffA(G4Material* material) const
379 // Returns A or effective A=sum(pi*Ai) (if compound/mixture)
380 // of given material.
384 G4int nofElements = material->GetNumberOfElements();
385 if (nofElements > 1) {
386 G4String text = "Effective A for material mixture (";
387 text = text + material->GetName();
388 text = text + ") is used.";
389 //TG4Globals::Warning(text);
391 for (G4int i=0; i<nofElements; i++) {
392 G4double aOfElement = material->GetElement(i)->GetA();
393 G4double massFraction = material->GetFractionVector()[i];
394 a += aOfElement*massFraction /(TG3Units::AtomicWeight());
398 a = material->GetA();
399 a /= TG3Units::AtomicWeight();
405 G4double TG4GeometryServices::GetEffZ(G4Material* material) const
407 // Returns Z or effective Z=sum(pi*Zi) (if compound/mixture)
408 // of given material.
412 G4int nofElements = material->GetNumberOfElements();
413 if (nofElements > 1) {
414 G4String text = "Effective Z for material mixture (";
415 text = text + material->GetName();
416 text = text + ") is used.";
417 //TG4Globals::Warning(text);
419 for (G4int i=0; i<nofElements; i++) {
420 G4double zOfElement = material->GetElement(i)->GetZ();
421 G4double massFraction = material->GetFractionVector()[i];
422 z += zOfElement*massFraction;
426 z = material->GetZ();