]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TGeant4/TG4GeometryServices.cxx
ae59166ed31537563bb1534f318a58c7ba6aa47f
[u/mrichter/AliRoot.git] / TGeant4 / TG4GeometryServices.cxx
1 // $Id$
2 // Category: geometry
3 //
4 // See the class description in the header file.
5
6 #include "TG4GeometryServices.h"
7 #include "TG4VSensitiveDetector.h"
8 #include "TG4Globals.h"
9 #include "TG3Units.h"
10
11 #include <G4VSensitiveDetector.hh>
12 #include <G4LogicalVolumeStore.hh>
13 #include <G4LogicalVolume.hh>
14 #include <G4Material.hh>
15 #include <G3toG4.hh> 
16
17 TG4GeometryServices* TG4GeometryServices::fgInstance = 0;
18
19 TG4GeometryServices::TG4GeometryServices(TG4intVector* mediumIdVector, 
20                                          TG4NameMap* nameMap) 
21 {
22 //
23   if (fgInstance) {
24     TG4Globals::Exception(
25       "TG4GeometryServices: attempt to create two instances of singleton.");
26   }
27
28   fMediumIdVector = mediumIdVector;
29   fNameMap = nameMap;
30
31   fgInstance = this;
32 }
33
34 TG4GeometryServices::TG4GeometryServices() {
35 // 
36   TG4Globals::Exception(
37     "Attempt to copy TG4GeometryServices singleton.");
38 }
39
40
41 TG4GeometryServices::TG4GeometryServices(const TG4GeometryServices& right) {
42 // 
43   TG4Globals::Exception(
44     "Attempt to copy TG4GeometryServices singleton.");
45 }
46
47
48 TG4GeometryServices::~TG4GeometryServices() {
49 //
50 }
51
52 //=============================================================================
53 //
54 // operators
55 //
56 //=============================================================================
57
58 TG4GeometryServices& 
59 TG4GeometryServices::operator=(const TG4GeometryServices& right)
60 {
61   // check assignement to self
62   if (this == &right) return *this;
63
64   TG4Globals::Exception(
65     "Attempt to assign TG4GeometryServices singleton.");
66     
67   return *this;  
68 }    
69           
70
71 //=============================================================================
72 //
73 // public methods
74 //
75 //=============================================================================
76
77
78 G4double* TG4GeometryServices::CreateG4doubleArray(Float_t* array, 
79                G4int size) const
80 {
81 // Converts Float_t* array to G4double*,
82 // !! The new array has to be deleted by user.
83 // ---
84
85   G4double* doubleArray;
86   if (size>0) {
87     doubleArray = new G4double[size]; 
88     for (G4int i=0; i<size; i++) doubleArray[i] = array[i];
89   }
90   else {
91     doubleArray = 0; 
92   }  
93   return doubleArray;
94 }
95
96
97 G4String TG4GeometryServices::CutName(const char* name) const
98 {
99 // Removes spaces after the name if present.
100 // ---
101
102   G4String cutName = name;
103   G4int i = cutName.length();
104   while (cutName(--i) == ' ') cutName = cutName(0,i);
105
106   return cutName;
107 }  
108
109
110 void TG4GeometryServices::G4ToG3VolumeName(G4String& name) const
111 {
112 // Cuts _copyNo extension added to logical volume name in case 
113 // the logical volume was created by Gsposp method.
114 // ---
115
116   if (name.contains(gSeparator)) 
117   name = name(0,name.first(gSeparator));
118 }
119
120
121 G4Material* TG4GeometryServices::MixMaterials(G4String name, G4double density, 
122         TG4StringVector* matNames, TG4doubleVector* matWeights)
123 {
124 // Creates a mixture of selected materials
125 // ---
126
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);
133   }    
134   // add verbose
135   // G4cout << "Nof of materials to be mixed: " << nofMaterials << G4endl;
136
137   // fill vector of materials
138   TG4MaterialVector matVector;  
139   G4int im;
140   for (im=0; im< nofMaterials; im++) {
141     // material
142     G4Material* material = G4Material::GetMaterial((*matNames)[im]);
143     matVector.insert(material);
144   } 
145
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);
152   }
153
154   return mixture;
155 }  
156
157
158  Int_t TG4GeometryServices::NofG3Volumes() const
159 {
160 // Returns the total number of logical volumes corresponding
161 // to G3 volumes. (
162 // The logical volume that were created by Gsposp method 
163 // with a generic name (name_copyNo) are NOT included.
164 // ---
165
166   G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
167
168   G4int counter = 0;  
169   for (G4int i=0; i<pLVStore->entries(); i++) {
170     G4LogicalVolume* lv = (*pLVStore)[i];
171     if (IsG3Volume(lv->GetName())) counter++;
172   }
173   
174   return counter;  
175 }
176
177
178 Int_t TG4GeometryServices::NofG4LogicalVolumes() const
179 {
180 // Returns the total number of logical volumes in the geometry.
181 // ---
182
183   G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
184   return pLVStore->entries();
185 }
186
187
188 Int_t TG4GeometryServices::NofG4PhysicalVolumes() const
189 {
190 // Returns the total number of physical volumes in the geometry.
191 // ---
192
193   G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
194
195   G4int counter = 0;
196   for (G4int i=0; i<pLVStore->entries(); i++) {
197     counter += ((*pLVStore)[i])->GetNoDaughters();
198   }
199   
200   return counter;  
201 }
202
203
204 Int_t TG4GeometryServices::NofSensitiveDetectors() const
205 {
206 // Returns the total number of sensitive detectors.
207 // ---
208
209   return TG4VSensitiveDetector::GetTotalNofSensitiveDetectors();
210 }
211
212  
213 G4int TG4GeometryServices::GetVolumeID(const G4String& volName) const
214
215 // Returns the sensitive detector identifier.
216 // !! Gives exception in case logical volume is not associated with 
217 // a sensitive detector.
218 // ---
219
220   G4String g4VolName = CutName(volName);
221   G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
222   
223   for (G4int i=0; i<pLVStore->entries(); i++) {
224     G4LogicalVolume* lv = pLVStore->at(i);
225     G4VSensitiveDetector* sd = lv->GetSensitiveDetector();
226   
227     if ((sd) && (sd->GetName()==g4VolName)) {
228       TG4VSensitiveDetector* tsd = dynamic_cast<TG4VSensitiveDetector*>(sd);
229       if (tsd)
230         return tsd->GetID();
231       else {
232         TG4Globals::Exception(
233           "TG4GeometryServices::GetVolumeID: Unknown sensitive detector type");
234         return 0;
235       }
236     }   
237   }
238
239   G4String text = "TG4GeometryServices::VolId: Sensitive detector ";
240   text = text + g4VolName;
241   text = text + " is not defined.\n"; 
242   TG4Globals::Warning(text);
243   return 0;
244 }
245
246
247 G4int TG4GeometryServices::GetVolumeID(G4LogicalVolume* logicalVolume) const 
248 {
249 // Returns the sensitive detector ID of the specified
250 // logical volume.
251 // ---
252  
253   // sensitive detector ID
254   G4VSensitiveDetector* sd
255     = logicalVolume->GetSensitiveDetector();
256   if (sd) {
257     TG4VSensitiveDetector* tsd = dynamic_cast<TG4VSensitiveDetector*>(sd);
258     if (tsd)
259       return tsd->GetID();
260     else {
261       TG4Globals::Exception(
262         "TG4GeometryServices::GetVolumeID: Unknown sensitive detector type");
263       return 0;
264     }           
265   }  
266   else {
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);
272     return 0;
273   }             
274
275
276
277 G4String TG4GeometryServices::GetVolumeName(G4int volumeId) const
278 {
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.
282 // ---
283
284   G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
285   
286   for (G4int i=0; i<pLVStore->entries(); i++) {
287     G4LogicalVolume* lv = pLVStore->at(i);
288     G4VSensitiveDetector* sd = lv->GetSensitiveDetector();
289     
290     if (sd) {
291       G4int sdID;
292       TG4VSensitiveDetector* tsd = dynamic_cast<TG4VSensitiveDetector*>(sd);
293       if (tsd)
294         sdID = tsd->GetID();
295       else {
296         TG4Globals::Exception(
297           "TG4GeometryServices::VolId: Unknown sensitive detector type");
298         return "";
299       }
300       if (sdID == volumeId) return sd->GetName();
301     }  
302   }
303
304   G4String text = "TG4GeometryServices::VolName:\n";
305   text = text + "    Sensitive detector with given id is not defined. \n";
306   TG4Globals::Warning(text);
307   return "";                     
308 }
309
310
311 G4LogicalVolume* TG4GeometryServices::GetLogicalVolume(G4int volumeId) const 
312 {
313 // Finds the first logical volume with specified volumeId 
314 // (sensitive detector ID) in G4LogicalVolumeStore.
315 // ---
316
317   G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
318   
319   for (G4int i=0; i<pLVStore->entries(); i++) {
320     G4LogicalVolume* lv = pLVStore->at(i);
321     if (GetVolumeID(lv) == volumeId) return lv;
322   }
323   
324   G4String text = "TG4GeometryServices::GetLogicalVolume: \n";
325   text = text + "    Logical volume with given ID does not exist.";
326   return 0;                      
327 }  
328
329
330 G4bool TG4GeometryServices::IsG3Volume(const G4String& lvName) const
331 {
332 // Returns true if the logical volume of given volumeName
333 // was not created by Gsposp method with a generic name 
334 // (name_copyNo).
335 // ---
336
337   if (lvName.contains(gSeparator))
338     return false;  
339   else
340     return true;   
341 }
342
343
344 const G4String& TG4GeometryServices::GetMapSecond(const G4String& name)
345
346 // Returns the second string associated with the name in
347 // the name map.
348 // ---
349
350   return fNameMap->GetSecond(name); 
351 }
352
353
354 G4int TG4GeometryServices::GetMediumId(G4Material* material) const
355 {
356 // Returns the second index for materials (having its origin in
357 // G4 tracking media concept)
358 // ---
359
360   return (*fMediumIdVector)[material->GetIndex()];
361 }  
362
363
364 Int_t TG4GeometryServices::GetMediumId(G4int volumeId)  const
365 {
366 // Return the material number for a given volume id
367 // ---
368
369   G4LogicalVolume* logicalVolume = GetLogicalVolume(volumeId);
370     
371   G4Material* material = logicalVolume->GetMaterial();  
372
373   return GetMediumId(material);                  
374 }
375  
376
377 G4double TG4GeometryServices::GetEffA(G4Material* material) const
378 {
379 // Returns A or effective A=sum(pi*Ai) (if compound/mixture)
380 // of given material.
381 // ---
382
383   G4double a = 0.;
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);
390
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());
395     }
396   }
397   else { 
398     a = material->GetA();
399     a /= TG3Units::AtomicWeight();
400   }
401   return a;
402 }
403
404
405 G4double TG4GeometryServices::GetEffZ(G4Material* material) const
406 {
407 // Returns Z or effective Z=sum(pi*Zi) (if compound/mixture)
408 // of given material.
409 // ---
410
411   G4double z = 0.;
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);
418
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;
423     }
424   }
425   else { 
426     z = material->GetZ(); 
427   }  
428   return z;
429 }