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>
15 #include <G4UserLimits.hh>
18 TG4GeometryServices* TG4GeometryServices::fgInstance = 0;
20 TG4GeometryServices::TG4GeometryServices(TG4intVector* mediumIdVector,
25 TG4Globals::Exception(
26 "TG4GeometryServices: attempt to create two instances of singleton.");
29 fMediumIdVector = mediumIdVector;
35 TG4GeometryServices::TG4GeometryServices() {
37 TG4Globals::Exception(
38 "Attempt to copy TG4GeometryServices singleton.");
42 TG4GeometryServices::TG4GeometryServices(const TG4GeometryServices& right) {
44 TG4Globals::Exception(
45 "Attempt to copy TG4GeometryServices singleton.");
49 TG4GeometryServices::~TG4GeometryServices() {
53 //=============================================================================
57 //=============================================================================
60 TG4GeometryServices::operator=(const TG4GeometryServices& right)
62 // check assignement to self
63 if (this == &right) return *this;
65 TG4Globals::Exception(
66 "Attempt to assign TG4GeometryServices singleton.");
72 //=============================================================================
76 //=============================================================================
79 G4double* TG4GeometryServices::CreateG4doubleArray(Float_t* array,
82 // Converts Float_t* array to G4double*,
83 // !! The new array has to be deleted by user.
86 G4double* doubleArray;
88 doubleArray = new G4double[size];
89 for (G4int i=0; i<size; i++) doubleArray[i] = array[i];
98 G4String TG4GeometryServices::CutName(const char* name) const
100 // Removes spaces after the name if present.
103 G4String cutName = name;
104 G4int i = cutName.length();
105 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));
120 G4int TG4GeometryServices::SetUserLimits(G4UserLimits* userLimits,
123 // Sets user limits to all logical volumes corresponding to
124 // the same G3 volume as the volume with specified name.
125 // Returns the number of updated logical volumes.
128 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
130 G4String volName = lv->GetName();
131 G4ToG3VolumeName(volName);
134 for (G4int i=0; i<pLVStore->entries(); i++) {
135 G4LogicalVolume* lv = (*pLVStore)[i];
136 G4String name = lv->GetName();
137 G4ToG3VolumeName(name);
138 if (name == volName) {
139 lv->SetUserLimits(userLimits);
147 G4Material* TG4GeometryServices::MixMaterials(G4String name, G4double density,
148 TG4StringVector* matNames, TG4doubleVector* matWeights)
150 // Creates a mixture of selected materials
153 // number of materials to be mixed
154 G4int nofMaterials = matNames->entries();
155 if (nofMaterials != matWeights->entries()) {
156 G4String text = "TG4GeometryServices::MixMaterials: ";
157 text = text + "different number of material names and weigths.";
158 TG4Globals::Exception(text);
161 // G4cout << "Nof of materials to be mixed: " << nofMaterials << G4endl;
163 // fill vector of materials
164 TG4MaterialVector matVector;
166 for (im=0; im< nofMaterials; im++) {
168 G4Material* material = G4Material::GetMaterial((*matNames)[im]);
169 matVector.insert(material);
172 // create the mixed material
173 G4Material* mixture = new G4Material(name, density, nofMaterials);
174 for (im=0; im< nofMaterials; im++) {
175 G4Material* material = matVector[im];
176 G4double fraction = (*matWeights)[im];
177 mixture->AddMaterial(material, fraction);
184 Int_t TG4GeometryServices::NofG3Volumes() const
186 // Returns the total number of logical volumes corresponding
188 // The logical volume that were created by Gsposp method
189 // with a generic name (name_copyNo) are NOT included.
192 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
195 for (G4int i=0; i<pLVStore->entries(); i++) {
196 G4LogicalVolume* lv = (*pLVStore)[i];
197 if (IsG3Volume(lv->GetName())) counter++;
204 Int_t TG4GeometryServices::NofG4LogicalVolumes() const
206 // Returns the total number of logical volumes in the geometry.
209 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
210 return pLVStore->entries();
214 Int_t TG4GeometryServices::NofG4PhysicalVolumes() const
216 // Returns the total number of physical volumes in the geometry.
219 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
222 for (G4int i=0; i<pLVStore->entries(); i++) {
223 counter += ((*pLVStore)[i])->GetNoDaughters();
230 Int_t TG4GeometryServices::NofSensitiveDetectors() const
232 // Returns the total number of sensitive detectors.
235 return TG4VSensitiveDetector::GetTotalNofSensitiveDetectors();
239 G4int TG4GeometryServices::GetVolumeID(const G4String& volName) const
241 // Returns the sensitive detector identifier.
242 // !! Gives exception in case logical volume is not associated with
243 // a sensitive detector.
246 G4String g4VolName = CutName(volName);
247 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
249 for (G4int i=0; i<pLVStore->entries(); i++) {
250 G4LogicalVolume* lv = pLVStore->at(i);
251 G4VSensitiveDetector* sd = lv->GetSensitiveDetector();
253 if ((sd) && (sd->GetName()==g4VolName)) {
254 TG4VSensitiveDetector* tsd = dynamic_cast<TG4VSensitiveDetector*>(sd);
258 TG4Globals::Exception(
259 "TG4GeometryServices::GetVolumeID: Unknown sensitive detector type");
265 G4String text = "TG4GeometryServices::VolId: Sensitive detector ";
266 text = text + g4VolName;
267 text = text + " is not defined.\n";
268 TG4Globals::Warning(text);
273 G4int TG4GeometryServices::GetVolumeID(G4LogicalVolume* logicalVolume) const
275 // Returns the sensitive detector ID of the specified
279 // sensitive detector ID
280 G4VSensitiveDetector* sd
281 = logicalVolume->GetSensitiveDetector();
283 TG4VSensitiveDetector* tsd = dynamic_cast<TG4VSensitiveDetector*>(sd);
287 TG4Globals::Exception(
288 "TG4GeometryServices::GetVolumeID: Unknown sensitive detector type");
293 G4String text = "TG4GeometryServices::GetVolumeID: \n";
294 text = text + " Volume " + logicalVolume->GetName();
295 text = text + " has not a sensitive detector.";
296 //TG4Globals::Exception(text);
297 TG4Globals::Warning(text);
303 G4String TG4GeometryServices::GetVolumeName(G4int volumeId) const
305 // Returns the name of the sensitive detector with the given identifier.
306 // Gives a warning in case logical volume is not associated with
307 // a sensitive detector.
310 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
312 for (G4int i=0; i<pLVStore->entries(); i++) {
313 G4LogicalVolume* lv = pLVStore->at(i);
314 G4VSensitiveDetector* sd = lv->GetSensitiveDetector();
318 TG4VSensitiveDetector* tsd = dynamic_cast<TG4VSensitiveDetector*>(sd);
322 TG4Globals::Exception(
323 "TG4GeometryServices::VolId: Unknown sensitive detector type");
326 if (sdID == volumeId) return sd->GetName();
330 G4String text = "TG4GeometryServices::VolName:\n";
331 text = text + " Sensitive detector with given id is not defined. \n";
332 TG4Globals::Warning(text);
337 G4LogicalVolume* TG4GeometryServices::GetLogicalVolume(G4int volumeId) const
339 // Finds the first logical volume with specified volumeId
340 // (sensitive detector ID) in G4LogicalVolumeStore.
343 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
345 for (G4int i=0; i<pLVStore->entries(); i++) {
346 G4LogicalVolume* lv = pLVStore->at(i);
347 if (GetVolumeID(lv) == volumeId) return lv;
350 G4String text = "TG4GeometryServices::GetLogicalVolume: \n";
351 text = text + " Logical volume with given ID does not exist.";
356 G4bool TG4GeometryServices::IsG3Volume(const G4String& lvName) const
358 // Returns true if the logical volume of given volumeName
359 // was not created by Gsposp method with a generic name
363 if (lvName.contains(gSeparator))
370 const G4String& TG4GeometryServices::GetMapSecond(const G4String& name)
372 // Returns the second string associated with the name in
376 return fNameMap->GetSecond(name);
380 G4int TG4GeometryServices::GetMediumId(G4Material* material) const
382 // Returns the second index for materials (having its origin in
383 // G4 tracking media concept)
386 return (*fMediumIdVector)[material->GetIndex()];
390 Int_t TG4GeometryServices::GetMediumId(G4int volumeId) const
392 // Return the material number for a given volume id
395 G4LogicalVolume* logicalVolume = GetLogicalVolume(volumeId);
397 G4Material* material = logicalVolume->GetMaterial();
399 return GetMediumId(material);
403 G4double TG4GeometryServices::GetEffA(G4Material* material) const
405 // Returns A or effective A=sum(pi*Ai) (if compound/mixture)
406 // of given material.
410 G4int nofElements = material->GetNumberOfElements();
411 if (nofElements > 1) {
412 G4String text = "Effective A for material mixture (";
413 text = text + material->GetName();
414 text = text + ") is used.";
415 //TG4Globals::Warning(text);
417 for (G4int i=0; i<nofElements; i++) {
418 G4double aOfElement = material->GetElement(i)->GetA();
419 G4double massFraction = material->GetFractionVector()[i];
420 a += aOfElement*massFraction /(TG3Units::AtomicWeight());
424 a = material->GetA();
425 a /= TG3Units::AtomicWeight();
431 G4double TG4GeometryServices::GetEffZ(G4Material* material) const
433 // Returns Z or effective Z=sum(pi*Zi) (if compound/mixture)
434 // of given material.
438 G4int nofElements = material->GetNumberOfElements();
439 if (nofElements > 1) {
440 G4String text = "Effective Z for material mixture (";
441 text = text + material->GetName();
442 text = text + ") is used.";
443 //TG4Globals::Warning(text);
445 for (G4int i=0; i<nofElements; i++) {
446 G4double zOfElement = material->GetElement(i)->GetZ();
447 G4double massFraction = material->GetFractionVector()[i];
448 z += zOfElement*massFraction;
452 z = material->GetZ();